[
  {
    "path": ".gitattributes",
    "content": "*.h linguist-language=C++\n*.c linguist-language=C++\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build project and validate checksum\n\non:\n  push:\n    branches:\n      - \"*\"\n\njobs:\n  build:\n    if: github.repository_owner == 'theonlyzac'\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n\n      - name: Set up Python\n        uses: actions/setup-python@v2\n        with:\n          python-version: \"3.x\"\n\n      - name: Install dependencies\n        run: |\n          python -m pip install --upgrade pip\n          pip install -U -r requirements.txt\n\n      - name: Setup wine\n        run: |\n          sudo dpkg --add-architecture i386\n          sudo apt-get update\n          sudo apt-get install wine32\n\n      - name: Setup build environment\n        run: |\n          sudo apt-get install binutils-mips-linux-gnu\n          scripts/setup_prodg_linux.sh\n          curl -o disc/SCUS_971.98 \"${{ secrets.FILE_URL }}\"\n\n      - name: Run build script\n        run: |\n          python configure.py\n          ninja\n"
  },
  {
    "path": ".github/workflows/frogress.yml",
    "content": "name: Post mapfile_parser progress to Frogress endpoint\n\non:\n  push:\n    branches:\n      - main\n      - progress\n\njobs:\n  frogress-upload:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - name: Set up Python\n        uses: actions/setup-python@v2\n        with:\n          python-version: \"3.9.x\"\n\n      - name: Install dependencies\n        run: |\n          python -m pip install --upgrade pip\n          pip install -U -r requirements.txt\n\n      - name: Setup wine\n        run: |\n          sudo dpkg --add-architecture i386\n          sudo apt-get update\n          sudo apt-get install wine32\n\n      - name: Setup build environment\n        run: |\n          sudo apt-get install binutils-mips-linux-gnu\n          scripts/setup_prodg_linux.sh\n          curl -o disc/SCUS_971.98 \"${{ secrets.FILE_URL }}\"\n\n      - name: Run build script\n        run: |\n          python configure.py\n          ninja\n\n      - name: Post to frogress endpoint\n        run: |\n          python3 scripts/frogress/upload_progress.py --frogress_api_key ${{ secrets.FROGRESS_API_KEY }}\n"
  },
  {
    "path": ".github/workflows/progress.yml",
    "content": "name: Upload objdiff report for Decomp.dev bot\n\non:\n  push:\n    branches:\n      - main\n      - progress\n\njobs:\n  report-upload:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout Repository\n        uses: actions/checkout@v4\n\n      - name: Set up Python\n        uses: actions/setup-python@v2\n        with:\n          python-version: \"3.9.x\"\n\n      - name: Install dependencies\n        run: |\n          python -m pip install --upgrade pip\n          pip install -U -r requirements.txt\n\n      - name: Setup wine\n        run: |\n          sudo dpkg --add-architecture i386\n          sudo apt-get update\n          sudo apt-get install wine32\n\n      - name: Setup build environment\n        run: |\n          sudo apt-get install binutils-mips-linux-gnu\n          scripts/setup_prodg_linux.sh\n          curl -o disc/SCUS_971.98 \"${{ secrets.FILE_URL }}\"\n\n      - name: Configure and generate report\n        run: |\n          python configure.py --objects\n          ninja\n          ./tools/objdiff/objdiff-cli report generate > report.json\n\n      - name: Upload Artifact\n        uses: actions/upload-artifact@v4\n        with:\n          name: SCUS_971.98_report\n          path: ./report.json\n"
  },
  {
    "path": ".gitignore",
    "content": "# Project-specific files\nSCUS_971.98\n*[Ss][Cc][Uu][Ss]*\n*971*98*\nSCUS_*.*\n*.elf\ndisc/*\nreference/*\n\n# Objdiff\nobjdiff.json\nreport.json\n\n# Compiler\nprodg*\ntools/cc/\ntools/wibo-i686\nusr/\n\n# Splat\nsplat/\nassets/\nasm/\nundefined_funcs_auto.txt\nundefined_syms_auto.txt\n.splache\n.ninja_log\n*.ninja\npermuter_settings.toml\n\n# Documentation\nhtml/\n\n## MacOS\n.DS_Store\n\n## Linux\n*.swp\n\n## WSL\n*:Zone.Identifier\n\n## Binary/object products\n**/bin/\n**/obj/\n\n## Clang-tooling things\n**/compile_commands.json\n\n# Compiled Object files\n*.slo\n*.lo\n*.o\n*.obj\n\n# Precompiled Headers\n*.gch\n*.pch\n\n# Compiled Dynamic libraries\n*.so\n*.dylib\n*.dll\n\n# Compiled Static libraries\n*.lai\n*.la\n*.a\n*.lib\n\n# Executables\n*.exe\n*.out\n*.app\n*.elf\n\n# Linker scripts\n*.ld\n\n# Python\nenv/\n__pycache__/\n*.pyc\n\n# Miscellaneous\n.vscode\ntemp/\n*.diff\n*.AppImage\n"
  },
  {
    "path": "README.md",
    "content": "# 🦝 Sly Cooper and the Thievius Raccoonus\n\n<!-- Build status shield -->\n[build-url]:https://github.com/TheOnlyZac/sly1/actions/workflows/build.yml\n[build-badge]: https://img.shields.io/github/actions/workflow/status/theonlyzac/sly1/build.yml?branch=main&label=build\n\n[decompdev-url]: https://decomp.dev/TheOnlyZac/sly1\n[data-progress-badge]: https://decomp.dev/TheOnlyZac/sly1.svg?mode=shield&label=data&measure=matched_data_percent\n\n[engine-url]: https://decomp.dev/TheOnlyZac/sly1/SCUS_971.98?category=P2\n[engine-progress-badge]: https://decomp.dev/TheOnlyZac/sly1.svg?mode=shield&category=P2&label=engine&measure=fuzzy_match_percent\n\n[splice-url]: https://decomp.dev/TheOnlyZac/sly1/SCUS_971.98?category=splice\n[splice-progress-badge]: https://decomp.dev/TheOnlyZac/sly1.svg?mode=shield&category=splice&label=splice&measure=fuzzy_match_percent\n\n<!-- Contributors shield -->\n[contributors-url]: https://github.com/theonlyzac/sly1/graphs/contributors\n[contributors-badge]: https://img.shields.io/github/contributors/theonlyzac/sly1?color=%23db6d28\n\n<!-- Discord shield -->\n[discord-url]: https://discord.gg/2GSXcEzPJA\n[discord-badge]: https://img.shields.io/discord/439454661100175380?color=%235865F2&logo=discord&logoColor=%23FFFFFF\n\n<!-- Docs shield -->\n[docs-url]: https://theonlyzac.github.io/sly1\n[docs-badge]: https://img.shields.io/badge/docs-github.io-2C4AA8\n\n<!-- Wiki shield -->\n[wiki-url]: https://slymods.info\n[wiki-badge]: https://img.shields.io/badge/wiki-slymods.info-2C4AA8\n\n<!-- Shields -->\n[![Build][build-badge]][build-url] [![Engine Progress][engine-progress-badge]][engine-url] [![Splice Progress][splice-progress-badge]][splice-url] [![Data Progress][data-progress-badge]][decompdev-url] [![Contributors][contributors-badge]][contributors-url] [![Discord Channel][discord-badge]][discord-url] [![Docs][docs-badge]][docs-url] [![Wiki][wiki-badge]][wiki-url]\n\n[<img src=\"./docs/logo.png\" style=\"margin:7px\" align=\"right\" width=\"33%\" alt=\"Sly 1 Decompilation Logo by Cooper941\">][docs-url]\n\nThis is a work-in-progress decompilation of [*Sly Cooper and the Thievius Raccoonus*](https://en.wikipedia.org/wiki/Sly_Cooper_and_the_Thievius_Raccoonus) for the PlayStation 2. It builds the NTSC-U version of the game, `SCUS_971.98` (SHA1: `57dc305d`).\n\nOur goal is to fully decompile the game engine to matching source code. This repo does **not** contain any assets or original code from the game's files; you need your own copy of the game to build and run it.\n\nDocumentation of the code is hosted at [theonlyzac.github.io/sly1](https://theonlyzac.github.io/sly1). For more info on the game's internal systems and mechanics, check out the [SlyMods Wiki][wiki-url].\n\nNew contributors are welcome to make a pull request! If you would like to help but aren't sure where to start, check out [CONTRIBUTING.md](/docs/CONTRIBUTING.md) and [join our Discord server][discord-url] if you have any questions.\n\n[![Quickstart](https://img.shields.io/badge/⚡%20Quickstart-093fbe?style=for-the-badge)](#-quickstart)\n[![Manual Setup](https://img.shields.io/badge/⚙️%20Manual%20Setup-093fbe?style=for-the-badge)](#%EF%B8%8F-manual-setup)\n[![Running the Game](https://img.shields.io/badge/🎮%20Running%20the%20Game-093fbe?style=for-the-badge)](#-running-the-game)\n[![Project Structure](https://img.shields.io/badge/📁%20Project%20Structure-093fbe?style=for-the-badge)](#-project-structure)\n[![FAQ](https://img.shields.io/badge/❓%20FAQ-093fbe?style=for-the-badge)](#-frequently-asked-questions)\n[![Contributors](https://img.shields.io/badge/🩵%20Contributors-093fbe?style=for-the-badge)](#-contributors)\n[![Star History](https://img.shields.io/badge/⭐%20Star%20History-093fbe?style=for-the-badge)](#-star-history)\n[![Discord](https://img.shields.io/badge/Discord-093fbe?style=for-the-badge&logo=discord)](https://discord.gg/2GSXcEzPJA)\n\n## ⚡ Quickstart\n\nYou can quickly setup the project on Debian-based systems such as Ubuntu (or WSL) using the quickstart script. Follow these three steps to get started:\n\n> **NOTE:** You can follow along on other distros by using the [Distrobox Guide](./docs/DISTROBOX.md) to set up a Debian container.\n\n### 1. Clone the repo\n\n```bash\ngit clone https://github.com/theonlyzac/sly1\ncd sly1\n```\n\n### 2. Run quickstart\n\nRun the `quickstart.sh` script in the `scripts` directory. It may ask for your password to install dependencies.\n\nYou have two options to automatically extract your original game executable:\n\n- <b>Method 1:</b> Copy the NTSC-U Sly 1 game ISO to the `disc` directory and then run:\n\n  ```bash\n  ./scripts/quickstart.sh\n  ```\n\n- <b>Method 2:</b> Specify a path to the ISO:\n\n  ```bash\n  ./scripts/quickstart.sh /path/to/GameBackup.iso\n  ```\n\nOtherwise, just copy the `SCUS_971.98` file from your game disc to the `disc` directory manually.\n\n### 3. Build the project\n\n```bash\n./scripts/build.sh\n```\n\nIf the build succeeds, you will see this:\n\n```\nout/SCUS_971.98: OK\n```\n\nIf you have any issues, or you prefer to set up the project manually, follow the instructions below. Instructions to run the game are also provided below.\n\n## ⚙️ Manual Setup\n\nThe project can be built on Linux (or Windows using WSL). Follow the instructions below to set up the build environment.\n\n> **Note:** These instructions assume a Debian-based system such as Ubuntu. For other distributions, adapt the package manager commands and package names accordingly.\n\n### 1. Clone the repository\n\nClone the repo to your local machine:\n\n```bash\ngit clone https://github.com/TheOnlyZac/sly1\ncd sly1\n```\n\n### 2. Extract your game's ELF file\n\nTo build the project, you will need to extract the original ELF file from your own legally obtained copy of the game. Mount the disc on your PC and copy the file `SCUS_971.98` from your disc to the `disc` directory of this project.\n\n### 3. Setup Python environment\n\nInstall Python 3.9 or higher, pip and venv:\n\n```bash\nsudo apt install python3 python3-pip python3-venv\n```\n\nCreate a Python environment for the project:\n\n```bash\npython3 -m venv env\n```\n\nActivate the environment:\n\n```bash\nsource env/bin/activate\n```\n\nThen install the required Python packages:\n\n```bash\npip3 install -U -r requirements.txt\n```\n\n### 4. Setup build environment\n\nInstall 32 bit MIPS assembler and Wine:\n\n```bash\nsudo dpkg --add-architecture i386\nsudo apt update\nsudo apt install binutils-mips-linux-gnu wine32\n```\n\n> **Note:** For a lighter and faster alternative to Wine, download [`wibo-i686`](https://github.com/decompals/wibo/releases/) to the `tools` directory.\n\nInstall Ninja build system:\n\n```bash\nsudo apt install ninja-build\n```\n\nSetup the compiler using the provided script:\n\n```bash\n./scripts/setup_prodg_linux.sh\n```\n\n### 5. Configure and build the project\n\nRun the configure script and the build with ninja:\n\n```bash\npython3 configure.py\nninja\n```\n\nThe default behavior is to split the binary using Splat, build the object files (inserting the split assembly in place of non-matching functions), link the matching executable, and confirm that the checksum of the built executable matches the original.\n\nYou can alter the behavior by passing any of the following arguments to  `configure.py`:\n\n* `--clean` - Delete any existing build files and configure the project.\n* `--clean-only` - Delete any existing build files **without** configuring the project.\n* `--skip-checksum` - Skip the checksum verification step. This is necessary if you are intentionally changing the code, but note that the elf may not boot.\n* `--objects` - Builds the object files for matching with objdiff and generates an objdiff config file. Outputs two sets of object files: `obj/target` and `obj/current` (the latter of which will be updated automatically by objdiff as you edit the source code).\n\n## 🎮 Running the Game\n\nRunning the compiled executable requires [PCSX2 2.0](https://pcsx2.net/). You must have your own copy of the original game and the BIOS from your own PS2. They are not included in this repo and we cannot provide them for you.\n\nOnce you have those, and you have built the executable `SCUS_971.98`, you can run it using one of three methods:\n\n### Method 1: Autorun script\n\nThe `run.sh` script in the `scripts` directory will run the last successful build in the PCSX2 emulator. It will automatically detect PCSX2 installed via package manager, Flatpak, AppImage, or XDG Desktop entries in that order and use the first ISO found in the `disc` directory to load assets.\n\nOptionally, you can specify what ISO file to use:\n\n```bash\n./scripts/run.sh /path/to/GameBackup.iso\n```\n\nTo detect the PCSX2 AppImage, it must be placed in the `tools` directory, or be \"Installed\" via an AppImage manager utility.\n\n### Method 2: Run from PCSX2 CLI\n\nTo boot the elf in PCSX2 from the command line, use the following command:\n\n```bash\npcsx2 -elf \"./out/SCUS_971.98\" \"/path/to/GameBackup.iso\"\n```\n\n* Replace `pcsx2` with the path to your PCSX2 executable if not found automatically:\n  * <b>AppImage:</b> Use the path to the `.appimage` file.\n  * <b>Flatpak:</b> Grant PCSX2 access to your home directory with `flatpak override --user net.pcsx2.PCSX2 --filesystem=home` or a specific directory using `--filesystem=/path/to/files`. Then use `flatpak run net.pcsx2.PCSX2` as the executable. Relative paths to the ELF and ISO files will not work, only full system paths.\n  * <b>Windows:</b> Use the path to `pcsx2.exe`.\n* The `-elf` parameter specifies the path to the `SCUS_971.98` you built from this project. Replace the example path if necessary. The emulator will use this ELF to boot the game.\n* The last argument is the path to your game ISO. Replace the example path with the path to a backup of your own game disc. This is where the emulator will load assets from.\n\n### Method 3: Run from PCSX2 GUI\n\n1. In your PCSX2 games folder, make an alias (Linux) or symbolic link (Windows) called `SCUS_971.98.elf`, which points to the `out/SCUS_971.98` file built by this project.\n    * Note: The alias/symlink must point to `out/SCUS_971.98`, not `out/SCUS_971.98.elf`.\n2. The alias/symlink will be recognized as a game in PCSX2. Right click on it, then click `Properties... > Disc Path > Browse` and select the ISO of your game backup.\n3. Click \"Close\" and boot the game as normal.\n\nYou only have to make the alias/symlink once, and it will update every time you build the project.\n\n## 📁 Project Structure\n\nThe project files are sorted into the following directories. Many of them have their own readme with more info about what they contain.\n\n* `include` - Header files for the game engine.\n* `src` - The decompiled source code.\n  * All of the code for the game engine is in `src/P2`.\n  * Code for the game's scripting engine is in `src/P2/splice`.\n* `config` - Config files for Splat (binary splitting tool).\n* `scripts` - Utility scripts for setting up the build environment.\n* `docs` - Documentation and instructions for contributing.\n* `tools` - Utilities for function matching.\n* `reference` - Reference files for functions and data structures.\n\nWhen you build the executable, the following directories will be created.\n\n* `asm` - Disassembled assembly code from the elf.\n* `assets`- Binary data extracted from the elf.\n* `obj` - Compiled object files.\n* `out` - Compiled executables.\n\n## ❓ Frequently Asked Questions\n\n### What is a decompilation?\n\nWhen the developers created the game, they wrote source code and compiled it to assembly code that can run on the PS2. A decompilation involves reverse-engineering the assembly code to produce new, original code that compiles to the same assembly. This process leaves us with source code that is similar to and behaves the same as the source code (though not necessarily identical), which helps us understand what the programmers were thinking when they made the game.\n\n### How do you decompile the code?\n\nWe use a tool called [Splat](https://github.com/ethteck/splat/) to split the binary into assembly files representing each individual function. We then reimplement every function and data structure by writing C++ code that compiles to the same assembly code. We do not copy any code from the original game binary into the decompilation.\n\n### Has this ever been done before?\n\nThere are many other decompilation projects, but this was one of the first ones for the PS2. Our inspirations include as the [Super Mario 64 decomp](https://github.com/n64decomp/sm64) for the N64 and the [Breath of the Wild decomp](https://github.com/zeldaret/botw) for the Wii U (the latter being more similar in scope to this project). There is also a Jak & Daxter decomp/PC port called [OpenGOAL](https://github.com/open-goal/jak-project), though that game is 98% GOAL language rather than C/C++.\n\n### Is this a matching decomp?\n\nYes. This was the first PS2 decompilation project that targeted the PS2 and utilized function matching, before it was even possible to produce a byte-matching executable. We have built a matching elf since July 2024. Our ultimate goal is to match 100% of the game's functions.\n\n### What is Splice?\n\nSplice is the game's scripting engine; it handles things like scripted events, animated cutscenes, and guard spawning by executing scripts stored in the level files. The code for Splice is a distinct subset of the game engine code, which is why it has its own folder and progress percentage.\n\n### How can I help?\n\nIf you want to contribute, check out [CONTRIBUTING.md](/docs/CONTRIBUTING.md) and feel free to [join our discord server](https://discord.gg/2GSXcEzPJA)!\n\n## 🩵 Contributors\n\nThank you to everyone who has volunteered their time to make this project possible!\n\n<a href=\"https://github.com/theonlyzac/sly1/graphs/contributors\">\n  <img src=\"https://contrib.rocks/image?repo=theonlyzac/sly1\" />\n</a>\n\n<small>Made with [contrib.rocks](https://contrib.rocks).</small>\n\n## ⭐ Star History\n\n<a href=\"https://star-history.com/#theonlyzac/sly1&Date\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://api.star-history.com/svg?repos=theonlyzac/sly1&type=Date&theme=dark\" />\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"https://api.star-history.com/svg?repos=theonlyzac/sly1&type=Date\" />\n    <img alt=\"Star History Chart\" src=\"https://api.star-history.com/svg?repos=theonlyzac/sly1&type=Date\" />\n  </picture>\n</a>\n"
  },
  {
    "path": "config/checksum.sha1",
    "content": "57dc305db57932ad3f1122966cdb695d2e62a47a  out/SCUS_971.98\n"
  },
  {
    "path": "config/readme.md",
    "content": "# Splat Config Files\n\nThis directory contains config files for splat, the tool we use to split and disassemble the game binary. The config files are used to tell splat how to split the binary and what to name the output files.\n\n## Files in this directory\n- `sly1.yaml` - Main config file for splat. Contains the offsets of each file split in the game binary. Creating new `.c` files involves modifying this file to create a `c` split and then running `python3 configure.py` to generate the new files.\n- `symbol_addrs.txt` - Contains the addresses of symbols in the game binary. Used by splat to properly reference functions and variables in the game code when splitting the binary.\n- `checksum.sha1` - SHA1 checksum of the original game binary. Used to verify the integrity of the binary after compilation.\n\n## Adding new splits\nTo add a new source code file to the project, you must add the split to `sly1.yaml`. Here is an example of some file splits:\n```yaml\n    - [0x1f560, c, P2/brx]\n    - [0x1fe70, asm, P2/ac]\n    #- [0x, asm, P2/act]\n```\n- The first line tells Splat to split the binary at offset `0x1f560` and create a new file `P2/brx.c` (if it doesn't exist). It defines a translation unit starting at `0x1f560` and ending at the beginning of the next split. The `.c` file will have INCLUDE_ASM macros for each function in the split.\n- The second line tells Splat that the data starting from offset `0x1fe70` is in the translation unit `P2/ac`, but not to create a new `.c` file yet. It will only create `.s` files in the `asm/nonmatchings/` directory for each function in the split.\n- The third line is commented out and does nothing, because we know the next translation unit is `P2/act`, but we don't yet know what offset that translation unit starts at. When we find out (by finding the end of the last function in `P2/ac` and the start of the first function in `P2/act`), we can uncomment this line and add the offset.\n\nWhen splat is run, it will create `.s` assembly files for each non-matching functions in each split in the `asm/nonmatchings/` directory.\n"
  },
  {
    "path": "config/sly1.yaml",
    "content": "# Splat config for Sly 1 NTSC-U (PS2)\nname: Sly Cooper and the Thievius Raccoonus (USA)\nsha1: 57dc305db57932ad3f1122966cdb695d2e62a47a\n\noptions:\n  basename: SCUS_971.98\n  target_path: disc/SCUS_971.98\n  elf_path: SCUS_971.98\n  base_path: ../\n  platform: ps2\n  compiler: EEGCC\n\n  # Output paths\n  asm_path: asm\n  src_path: src\n  build_path: obj\n\n  # Assembly options\n  generate_asm_macros_files: False\n  named_regs_for_c_funcs: False\n  find_file_boundaries: False\n  disasm_unknown: True\n\n  # Rodata options\n  rodata_string_guesser_level: 0 # improve string detection\n  suggestion_rodata_section_start: True\n  pair_rodata_to_text: False\n  migrate_rodata_to_functions: True\n\n  # Auto-generate undefined functions and symbols\n  create_undefined_funcs_auto: True\n  undefined_funcs_auto_path: config/undefined_funcs_auto.txt\n  create_undefined_syms_auto: True\n  undefined_syms_auto_path: config/undefined_syms_auto.txt\n\n  # Manually defined symvols\n  symbol_addrs_path: config/symbol_addrs.txt\n\n  # Splat extensions\n  extensions_path: tools/splat_ext\n\n  # ELF sections\n  section_order: [\".text\", \".vutext\", \".rodata\", \".data\", \".bss\"]\n  auto_link_sections: [\".rodata\", \".data\", \".bss\"]\n\n  # Linker script options\n  subalign: 8\n\nsegments:\n  - [0, databin, elf_header]\n\n  - name: main\n    type: code\n    start: 0x001000\n    vram: 0x100000\n    bss_size: 0x3B1304\n    subsegments:\n    - [0x001000, asm, sce/crt0] # starts with 2 nops\n    - [0x001178, asm, P2/ps2t/spaprops] # ext should be .ic\n\n    #--------------------------------------------------------\n    # Splice sources\n    # All .cpp files\n    #--------------------------------------------------------\n    - [0x13698, cpp, P2/splice/bif] #MARK: P2/splice\n    - [0x19d48, cpp, P2/splice/eval]\n    - [0x1b328, cpp, P2/splice/frame]\n    - [0x1b678, cpp, P2/splice/gc]\n    - [0x1be78, cpp, P2/splice/method]\n    - [0x1beb8, cpp, P2/splice/pair]\n    - [0x1bf98, cpp, P2/splice/proc]\n    - [0x1c008, cpp, P2/splice/ref]\n    - [0x1ca28, cpp, P2/splice/serialize]\n    - [0x1cd28, cpp, P2/splice/sidebag]\n    - [0x1cf70, cpp, P2/splice/spliceutils]\n    - [0x1d128, cpp, P2/splice/splotheap]\n    - [0x1d508, cpp, P2/splice/vecmat]\n\n    #--------------------------------------------------------\n    # P2 sources\n    # All .c files (but compiled as c++)\n    #--------------------------------------------------------\n    - [0x1dbb8, c, P2/989snd] #MARK: P2\n    - [0x1f560, c, P2/brx]\n    - [0x1fe70, c, P2/ac]\n    - [0x22228, c, P2/act]\n    - [0x23f28, c, P2/actseg]\n    - [0x243c0, c, P2/alarm]\n    - [0x24dc0, c, P2/alo]\n    # Note: Anticrack check for ITM firewall is 0x2c760, maybe it's own TU?\n    - [0x2c868, c, P2/aseg]\n    - [0x2e3f8, c, P2/asega]\n    - [0x30840, c, P2/barrier]\n    - [0x30cf0, c, P2/bas]\n    - [0x310e8, c, P2/basic]\n    - [0x31168, c, P2/bez]\n    - [0x31f48, c, P2/binoc]\n    - [0x38290, c, P2/bis]\n    - [0x395a0, c, P2/bbmark]\n    - [0x39ff0, c, P2/blend]\n    - [0x3ab70, c, P2/blip]\n    - [0x3c4c0, c, P2/bomb]\n    - [0x3d988, c, P2/bq]\n    - [0x3dcf8, c, P2/break]\n    - [0x3efd8, c, P2/bsp]\n    - [0x3f7c0, c, P2/button]\n    - [0x41790, c, P2/cat]\n    - [0x417a8, c, P2/cd]\n    - [0x41d90, c, P2/chkpnt]\n    - [0x429e8, c, P2/clip]\n    - [0x43ed0, c, P2/clock]\n    - [0x44140, c, P2/cm]\n    - [0x47100, c, P2/cnvo]\n    - [0x47340, c, P2/coin]\n    - [0x4a398, c, P2/cplcy]\n    - [0x4bbd0, c, P2/credit]\n    - [0x4c0c0, c, P2/crout]\n    - [0x4c550, c, P2/crusher]\n    - [0x4e0a8, c, P2/crv]\n    - [0x4fe40, c, P2/dart]\n    - [0x50740, c, P2/dartgun]\n    - [0x514e0, c, P2/dialog]\n    - [0x529e0, c, P2/difficulty]\n    - [0x53438, c, P2/dl]\n    - [0x53810, c, P2/dmas]\n    - [0x53e28, c, P2/dysh]\n    - [0x54528, c, P2/dzg]\n    - [0x559c8, c, P2/emitter]\n    - [0x5a680, c, P2/eyes]\n    - [0x5aad0, c, P2/fader]\n    - [0x5aca0, asm, P2/UNKNOWN1] # Not in the prototype.\n    - [0x5af20, c, P2/find]\n    - [0x5b8b0, c, P2/flash]\n    - [0x5bae0, c, P2/fly]\n    - [0x5d178, c, P2/font]\n    - [0x5f6a8, c, P2/frm]\n    - [0x60678, c, P2/freeze]\n    - [0x60f88, c, P2/frzg]\n    - [0x61070, c, P2/game]\n    - [0x61e80, c, P2/geom]\n    - [0x621b8, c, P2/gifs]\n    - [0x629c0, c, P2/glbs]\n    - [0x63810, c, P2/glob]\n    - [0x68d68, c, P2/gomer]\n    - [0x69130, c, P2/gs]\n    - [0x6ac58, c, P2/hide]\n    - [0x6ba18, asm, P2/hideout]\n    - [0x6d470, c, P2/hnd]\n    - [0x6d4e8, c, P2/ik]\n    - [0x6de00, c, P2/jlo]\n    - [0x6f0b8, c, P2/joy]\n    - [0x70608, c, P2/jt]\n    - [0x79008, asm, P2/jp] # Might be something else.\n    - [0x7c998, c, P2/jsg]\n    - [0x7e248, c, P2/jump]\n    - [0x80e90, c, P2/keyhole]\n    - [0x81eb0, c, P2/landing]\n    - [0x81f68, c, P2/lgn]\n    - [0x83c18, c, P2/lo]\n    - [0x84cc8, c, P2/light]\n    - [0x86358, c, P2/lookat]\n    - [0x86758, c, P2/main]\n    - [0x86c18, c, P2/mark]\n    - [0x894c0, c, P2/mat]\n    - [0x8b388, c, P2/mb]\n    - [0x8c580, asm, P2/memcard]\n    - [0x8e430, c, P2/memory]\n    - [0x8e8e0, c, P2/missile]\n    - [0x8f410, c, P2/mpeg]\n    - [0x90988, c, P2/mrkv]\n    - [0x909d8, c, P2/ms]\n    - [0x90ef8, c, P2/murray]\n    - [0x917e0, c, P2/path]\n    - [0x92e70, c, P2/phasemem]\n    - [0x92ec0, c, P2/pipe]\n    - [0x93068, c, P2/pnt]\n    - [0x931a8, c, P2/po]\n    - [0x94210, c, P2/prog]\n    - [0x94598, asm, P2/prompt]\n    - [0x973d8, c, P2/proxy]\n    - [0x97938, c, P2/puffer]\n    - [0x99980, c, P2/pzo]\n    - [0x9bf00, c, P2/rail]\n    - [0x9c038, c, P2/rat]\n    - [0x9d440, c, P2/rchm]\n    - [0x9e410, c, P2/render]\n    - [0x9f040, c, P2/rip]\n    - [0xa4ae0, c, P2/rog]\n    - [0xa8b20, c, P2/rumble]\n    - [0xa8fe8, c, P2/rwm]\n    - [0xaa8f8, c, P2/sb]\n    - [0xaac68, c, P2/screen]\n    - [0xafcb0, c, P2/sensor]\n    - [0xb2ac8, c, P2/shadow]\n    - [0xb3840, c, P2/shape]\n    - [0xb3988, c, P2/shd]\n    - [0xb5920, c, P2/shdanim]\n    - [0xb6cd8, c, P2/sky]\n    - [0xb6d80, c, P2/slotheap]\n    - [0xb6f50, c, P2/sm]\n    - [0xb7ec8, c, P2/smartguard]\n    - [0xb8968, c, P2/so]\n    - [0xbd760, c, P2/solve]\n    - [0xbf068, c, P2/sort]\n    - [0xbf1e8, c, P2/sound]\n    - [0xc1f30, c, P2/speaker]\n    - [0xc20a8, c, P2/spire]\n    - [0xc2190, c, P2/splicemap]\n    - [0xc24c0, c, P2/spliceobj]\n    - [0xc3430, c, P2/sprbuf]\n    - [0xc39e8, c, P2/sqtr]\n    - [0xc4390, asm, P2/squish] # Might be something else.\n    - [0xc5458, c, P2/step]\n    - [0xc6f18, c, P2/stepact]\n    - [0xc71e0, c, P2/stepcane]\n    - [0xc7f48, c, P2/stepguard]\n    - [0xcd410, c, P2/stephang]\n    - [0xcefb8, c, P2/stephide]\n    - [0xd24f0, c, P2/steppipe]\n    - [0xd39c8, c, P2/steppower]\n    - [0xd41d0, c, P2/steprail]\n    - [0xd46f0, c, P2/steprun]\n    - [0xd5148, c, P2/stepside]\n    - [0xd5848, asm, P2/stepzap]\n    - [0xd8100, c, P2/stream]\n    - [0xd83a8, c, P2/suv]\n    - [0xdc480, c, P2/sw]\n    - [0xdece0, c, P2/tail]\n    - [0xdf798, c, P2/tank]\n    - [0xe0d48, c, P2/target]\n    - [0xe0e80, asm, P2/tatk] # Not in the prototype. Related to master thief sprints.\n    - [0xe18f8, c, P2/text]\n    - [0xe3268, c, P2/thread]\n    - [0xe3420, c, P2/tn]\n    - [0xe5e38, c, P2/transition]\n    - [0xe6378, c, P2/turret]\n    - [0xe6e70, c, P2/tv]\n    - [0xe98d0, c, P2/ub]\n    - [0xea088, c, P2/ui]\n    - [0xeac78, c, P2/update]\n    - [0xeb408, c, P2/util]\n    - [0xec460, asm, P2/vb]\n    - [0xee650, c, P2/vec]\n    - [0xef318, c, P2/vifs]\n    - [0xef900, c, P2/vis]\n    - [0xefc60, c, P2/water]\n    - [0xf0838, c, P2/waypoint]\n    - [0xf0ce8, c, P2/wipe]\n    - [0xf1468, c, P2/wm]\n    - [0xf3758, c, P2/wr]\n    - [0xf49f8, c, P2/xform]\n    - [0xf5f70, c, P2/zap]\n\n    ## Segments in prototype confirmed not present in release:\n    # P2/cycle.c - some kind of wheeled vehicle\n    # P2/dsp.c - unknown.\n    # P2/hg.c - hang glider\n    # P2/stepski.c - skiing\n    # P2/map2d.c - unknown\n    # P2/menu - debug menu\n    # P2/vife.c - vif encoder\n    # P2/wibu_ee.c - wibukey encryption\n    # P2/rope.c - unknown\n    # P2/sc.c - unknown\n    # P2/mouthgame.c - unknown\n\n    #--------------------------------------------------------\n    # Libs\n    # TODO: Verify start address.\n    #--------------------------------------------------------\n    - [0xF69C0, asm, sce/libs] # #MARK: libs\n    #- [0xF76F8, asm, sce/rand]\n    #- [0xF7738, asm]\n\n    #--------------------------------------------------------\n    # Vutext\n    #--------------------------------------------------------\n    - [0x112E10, textbin, vutext] #MARK: vutext\n\n    #--------------------------------------------------------\n    # Rodata (read-only data)\n    #--------------------------------------------------------\n    - [0x118380, rodata] #MARK: rodata\n    # - [0x1225a0, .rodata, P2/cm] # todo causes errors\n    - [0x141000, rodata] # todo\n    - [0x149FE0, .rodata, P2/splice/bif]\n    - [0x14A200, rodata] #todo: remove line and uncomment next for RefEvalAssert\n    # - [0x14A200, .rodata, P2/splice/eval]\n    - [0x14A2F0, .rodata, P2/splice/ref]\n    - [0x14A3A0, .rodata, P2/splice/serialize]\n    - [0x14A428, rodata] #, P2/989snd]\n    - [0x14A870, rodata]\n    #- [0x14AE20, .rodata, P2/cd]\n    - [0x14afe0, .rodata, P2/dart]\n    - [0x14aff8, rodata] # P2/dartgun Alignment issue, this should be 0x14b000.\n    - [0x14B0E0, .rodata, P2/dmas]\n    - [0x14B0F8, rodata]\n    - [0x14c1e8, .rodata, P2/main]\n    - [0x14c258, rodata]\n    - [0x14f600, .rodata, P2/ub]\n    - [0x14f670, .rodata, P2/ui]\n    - [0x14f6d0, rodata]\n    #- [0x14f7d0, .rodata, P2/wm]\n    #- [0x14f840, .rodata, P2/wr]\n    #- [0x14f860, .rodata, P2/xform]\n\n    #--------------------------------------------------------\n    # Data (variable data)\n    #--------------------------------------------------------\n    - [0x151580, data] #MARK: data\n    #- [0x, data, P2/splice/bif]\n    #- [0x, data, P2/splice/eval]\n    #- [0x, data, P2/splice/frame]\n    - [0x15af38, data, P2/splice/gc]\n    #- [0x, data, P2/splice/pair]\n    #- [0x, data, P2/splice/serialize]\n    #- [0x, data, P2/splice/sidebag]\n    #- [0x, data, P2/splice/spliceutils]\n    - [0x15d250, data, P2/splice/splotheap]\n    - [0x15d2f0, data, P2/splice/vecmat]\n    - [0x15d340, .data, P2/989snd]\n    - [0x161e60, data, P2/act]\n    - [0x161e70, data, P2/alo]\n    - [0x162090, data, P2/binoc]\n    #- [0x162314, data, P2/blip] # TODO: Alignment issue.\n    - [0x162320, data, P2/bomb]\n    - [0x162390, data, P2/bsp]\n    #- [0x1623ec, data, P2/cd] # TODO: Alignment issue.\n    - [0x162420, data, P2/chkpnt]\n    - [0x162850, .data, P2/clock]\n    - [0x162880, data, P2/cm]\n    - [0x1629a0, data, P2/coin]\n    - [0x162bf0, data, P2/cplcy]\n    #- [0x, data, P2/credit]\n    #- [0x, data, P2/crout]\n    #- [0x, data, P2/crusher]\n    #- [0x, data, P2/crv]\n    - [0x162cc8, data, P2/dart]\n    - [0x162ce0, data, P2/dartgun]\n    - [0x162d08, data, P2/dialog]\n    - [0x162d40, data, P2/difficulty]\n    #- [0x162f14, data, P2/dmas] # TODO: Alignment issue.\n    - [0x162f30, data, P2/dysh]\n    - [0x162f70, data, P2/emitter]\n    - [0x163180, data, P2/fly]\n    - [0x163250, data, P2/font]\n    #- [0x, data, P2/frm]\n    #- [0x, data, P2/freeze]\n    #- [0x, data, P2/frzg]\n    - [0x1633c0, data, P2/game]\n    #- [0x1633d8, data]\n\n    #- [0x, data, P2/geom]\n    #- [0x, data, P2/gifs]\n    #- [0x, data, P2/glbs]\n    #- [0x, data, P2/glob]\n    #- [0x, data, P2/gomer]\n    #- [0x, data, P2/gs]\n    #- [0x, data, P2/hide]\n    #- [0x, data, P2/hnd]\n    #- [0x, data, P2/ik]\n    #- [0x, data, P2/jlo]\n    - [0x163a30, data, P2/joy]\n    - [0x163e10, data, P2/jt]\n    #- [0x163e40, data] # TBD\n\n    #- [0x, data, P2/jp]\n    #- [0x164e34, data, P2/jsg] # TODO: Alignment issue.\n    - [0x164e50, data, P2/jump]\n    - [0x165098, data, P2/keyhole]\n    - [0x1650b0, data, P2/lgn]\n    - [0x165260, data, P2/light]\n    - [0x165770, data, P2/lookat]\n    - [0x1657a8, .data, P2/main]\n    - [0x165840, data, P2/mark]\n    - [0x165910, data, P2/mb]\n    - [0x165a40, data, P2/memcard]\n    #- [0x16a9a4, data, P2/memory] # TODO: Alignment issue.\n    - [0x16a9b0, data, P2/missile]\n    - [0x16a9c0, data, P2/mpeg]\n    - [0x16ab50, data, P2/ms]\n    - [0x16ab60, data, P2/murray]\n    - [0x16ab78, data, P2/path]\n    #- [0x16aba4, data, P2/phasemem] # TODO: Alignment issue.\n    - [0x16aba8, data, P2/pipe]\n    - [0x16abc0, data, P2/po]\n    - [0x16acd8, data, P2/prompt]\n    - [0x16b710, data, P2/puffer]\n    - [0x16b910, data, P2/pzo]\n    - [0x16bb90, data, P2/rat]\n    - [0x16bbd0, data, P2/rchm]\n    - [0x16bbf0, data, P2/render]\n    - [0x16c530, data, P2/rip]\n    - [0x16c778, data, P2/rog]\n    #- [0x16d3dc, data, P2/rumble] # TODO: Alignment issue.\n    #- [0x, data, P2/rwm]\n    #- [0x, data, P2/screen]\n    - [0x1754b8, data, P2/sensor]\n    - [0x1754f0, data, P2/shadow]\n    - [0x1754f8, data, P2/shd]\n    #- [0x, data, P2/shdanim]\n    #- [0x, data, P2/sky]\n    #- [0x, data, P2/sm]\n    #- [0x, data, P2/smartguard]\n    #- [0x, data, P2/so]\n    #- [0x, data, P2/solve]\n    #- [0x, data, P2/sort]\n    - [0x175720, data, P2/sound]\n    - [0x1758f0, data, P2/sprbuf]\n    - [0x175998, data, P2/sqtr]\n    #- [0x, data, P2/squish]\n    #- [0x, data, P2/step]\n    #- [0x, data, P2/stepact]\n    #- [0x, data, P2/stepcane]\n    #- [0x, data, P2/stepguard]\n    #- [0x, data, P2/stephang]\n    #- [0x, data, P2/stephide]\n    #- [0x, data, P2/steppipe]\n    #- [0x, data, P2/steppower]\n    - [0x175f90, data, P2/steprail]\n    - [0x175fa0, data, P2/steprun]\n    - [0x175fc0, data, P2/stepzap]\n    - [0x1761d0, data, P2/suv]\n    - [0x176630, data, P2/sw]\n    - [0x176730, data, P2/tail]\n    - [0x176740, data, P2/tank]\n    - [0x1768d0, data, P2/target]\n    - [0x1768e0, data, P2/tatk]\n    - [0x176940, data, P2/text]\n    - [0x176958, data, P2/thread]\n    - [0x176970, data, P2/tn]\n    - [0x176af0, data, P2/transition]\n    - [0x176b28, data, P2/turret]\n    - [0x176b50, data, P2/tv]\n    - [0x176b60, data, P2/ub]\n    - [0x176bc0, data, P2/ui]\n    - [0x176c18, data, P2/update]\n    - [0x176c40, data, P2/util]\n    - [0x176c70, data, P2/vb]\n    - [0x176dd0, data, P2/vifs]\n    - [0x176e10, data, P2/waypoint]\n    - [0x176f80, data, P2/wipe]\n    - [0x176fc0, data, P2/wm]\n    - [0x177680, databin]\n\n    ## Files with seemingly no data;\n    # - P2/brx\n    # - P2/ac\n    # - P2/actseg\n    # - P2/alarm\n    # - P2/aseg\n    # - P2/asega\n    # - P2/barrier\n    # - P2/bas\n    # - P2/basic\n    # - P2/bbmark\n    # - P2/bez\n    # - P2/bis\n    # - P2/blend\n    # - P2/bq\n    # - P2/break\n    # - P2/button\n    # - P2/cat\n    # - P2/clip\n    # - P2/cnvo\n    # - P2/dl\n    # - P2/dsp\n    # - P2/dzg\n    # - P2/eyes\n    # - P2/fader\n    # - P2/UNKNOWN1\n    # - P2/find\n    # - P2/flash\n    # - P2/landing\n    # - P2/lo\n    # - P2/mat\n    # - P2/mrkv\n    # - P2/pnt\n    # - P2/prog\n    # - P2/proxy\n    # - P2/rail\n    # - P2/shape\n    # - P2/slotheap\n    # - P2/speaker\n    # - P2/splicemap\n    # - P2/spliceobj\n    # - P2/stepside\n    # - P2/stream\n    # - P2/vec\n    # - P2/vis\n    # - P2/water\n    # - P2/xform\n    # - P2/zap\n\n  - [0x1A1C70, databin]\n  - [0x1A20D0]\n"
  },
  {
    "path": "config/sly1_may19.yaml",
    "content": "name: Sly Cooper May 19 2002 Prototype\nsha1: 3e5fdf0c479a0f548e90b05d7fc558cd8e94f5c1\n\noptions:\n  basename: sly1_may19\n  target_path: disc/sly1_may19.elf\n  elf_path: SCUS_971.98\n  base_path: ../\n  platform: ps2\n  compiler: GCC\n\n  asm_path: splat/may19/asm\n  src_path: splat/may19/src\n  build_path: build\n\n  find_file_boundaries: False\n  disasm_unknown: True\n  named_regs_for_c_funcs: False\n\n  create_undefined_funcs_auto: True\n  undefined_funcs_auto_path: config/undefined_funcs_auto_may19.txt\n\n  create_undefined_syms_auto: True\n  undefined_syms_auto_path: config/undefined_syms_auto_may19.txt\n\n  symbol_addrs_path: config/symbol_addrs_may19.txt\n\n  extensions_path: tools/splat_ext\n\n  section_order: [\".text\", \".rodata\", \".data\", \".bss\"]\n\n  auto_all_sections: [\".rodata\", \".data\", \".bss\"]\n\nsubalign: 0x4\n\nsegments:\n  - [0, databin, elf_header]\n\n  - name: main\n    type: code\n    start: 0x001000\n    vram: 0x100000\n    bss_size: 0x3B1304\n    subsegments:\n    - [0x001000, asm, sce/crt0] # starts with 2 nops\n    - [0x10c0, c, P2/ps2t/spaprops.ic]\n\n    #----------------------------------------\n    # Splice sources\n    #----------------------------------------\n    - [0x11de8, cpp, P2/splice/bif]\n    - [0x19d50, cpp, P2/splice/eval]\n    - [0x1b8f0, cpp, P2/splice/frame]\n    - [0x1bde0, cpp, P2/splice/gc]\n    - [0x1c6a8, cpp, P2/splice/method]\n    - [0x1c6f8, cpp, P2/splice/pair]\n    - [0x1c810, cpp, P2/splice/proc]\n    - [0x1c890, cpp, P2/splice/ref]\n    - [0x1d468, cpp, P2/splice/serialize]\n    - [0x1d810, cpp, P2/splice/sidebag]\n    - [0x1dbf8, cpp, P2/splice/spliceutils]\n    - [0x1ddc0, cpp, P2/splice/splotheap]\n    - [0x1e0f0, cpp, P2/splice/vecmat]\n\n    #----------------------------------------\n    # P2 sources\n    #----------------------------------------\n    - [0x1e888, c, P2/989snd]\n    - [0x203e0, c, P2/brx]\n    - [0x210a8, c, P2/ac]\n    - [0x237c0, c, P2/act]\n    - [0x25530, c, P2/actseg]\n    - [0x25a08, c, P2/alarm]\n    - [0x26548, c, P2/alo]\n    - [0x2ecb0, c, P2/aseg]\n    - [0x30d90, c, P2/asega]\n    - [0x33520, c, P2/barrier]\n    - [0x33a20, c, P2/bas]\n    - [0x33e88, c, P2/basic]\n    - [0x33f18, c, P2/bez]\n    - [0x34d60, c, P2/binoc]\n    - [0x3b480, c, P2/bis]\n    - [0x3c960, c, P2/bbmark]\n    - [0x3d468, c, P2/blend]\n    - [0x3e098, c, P2/blip]\n    - [0x3fd58, c, P2/bomb]\n    - [0x40fc0, c, P2/bone]\n    - [0x41278, c, P2/bq]\n    - [0x41608, c, P2/break]\n    - [0x42978, c, P2/bsp]\n    - [0x43190, c, P2/button]\n    - [0x45630, c, P2/cat]\n    - [0x460e8, c, P2/can]\n    - [0x46e10, c, P2/cd]\n    - [0x47388, c, P2/chkpnt]\n    - [0x47f48, c, P2/clip]\n    - [0x49410, c, P2/clock]\n    - [0x496c8, c, P2/cm]\n    - [0x4cb58, c, P2/cnvo]\n    - [0x4ce48, c, P2/coin]\n    - [0x4f808, c, P2/cplcy]\n    - [0x51578, c, P2/credit]\n    - [0x51ac8, c, P2/crout]\n    - [0x51f58, c, P2/crusher]\n    - [0x52a50, c, P2/crv]\n    - [0x54be8, c, P2/cycle]\n    - [0x56770, c, P2/dart]\n    - [0x571d8, c, P2/dartgun]\n    - [0x58158, c, P2/dialog]\n    - [0x595b0, c, P2/difficulty]\n    - [0x59cf8, c, P2/dl]\n    - [0x5a150, c, P2/dmas]\n    - [0x5a838, c, P2/dsp]\n    - [0x5ac98, c, P2/dysh]\n    - [0x5b538, c, P2/dzg]\n    - [0x5cb88, c, P2/emitter]\n    - [0x62108, c, P2/eyes]\n    - [0x625d0, c, P2/fader]\n    - [0x627e0, c, P2/find]\n    - [0x631e8, c, P2/flash]\n    - [0x63468, c, P2/fly]\n    - [0x64dd8, c, P2/font]\n    - [0x677b8, c, P2/frm]\n    - [0x68a30, c, P2/freeze]\n    - [0x69480, c, P2/frzg]\n    - [0x69590, c, P2/game]\n    - [0x6a3f8, c, P2/geom]\n    - [0x6a770, c, P2/gifs]\n    - [0x6afd8, c, P2/glbs]\n    - [0x6bff8, c, P2/glob]\n    - [0x720f8, c, P2/gomer]\n    - [0x729d0, c, P2/gs]\n    - [0x748f8, c, P2/hg]\n    - [0x75550, c, P2/hide]\n    - [0x764a8, c, P2/hnd]\n    - [0x76518, c, P2/ik]\n    - [0x76e90, c, P2/jack]\n    - [0x7b0d0, c, P2/jlo]\n    - [0x7c478, c, P2/joy]\n    - [0x7da08, c, P2/jt]\n    - [0x866e8, c, P2/jp]\n    - [0x880f8, c, P2/jsg]\n    - [0x89630, c, P2/jump]\n    - [0x8c068, c, P2/keyhole]\n    - [0x8d170, c, P2/landing]\n    - [0x8d250, c, P2/lgn]\n    - [0x8fcd8, c, P2/lo]\n    - [0x910d8, c, P2/light]\n    - [0x92c48, c, P2/lookat]\n    - [0x93028, c, P2/main]\n    - [0x93b88, c, P2/map2d]\n    - [0x93c78, c, P2/mark]\n    - [0x96598, c, P2/mat]\n    - [0x98840, c, P2/mecha]\n    - [0x99c70, c, P2/mb]\n    - [0x9aec0, c, P2/memcard]\n    - [0x9aec8, c, P2/memory]\n    - [0x9b608, c, P2/menu]\n    - [0x9f7f0, c, P2/missile]\n    - [0xa0770, c, P2/mouthgame]\n    - [0xa1208, c, P2/mpeg]\n    - [0xa2838, c, P2/mrkv]\n    - [0xa2898, c, P2/ms]\n    - [0xa2e00, c, P2/murray]\n    - [0xa3410, c, P2/path]\n    - [0xa4dd0, c, P2/phasemem]\n    - [0xa4e28, c, P2/pipe]\n    - [0xa4fc0, c, P2/pnt]\n    - [0xa50d8, c, P2/po]\n    - [0xa5c08, c, P2/prog]\n    - [0xa6020, c, P2/prompt]\n    - [0xa7750, c, P2/proxy]\n    - [0xa7da0, c, P2/puffer]\n    - [0xaa248, c, P2/pzo]\n    - [0xac6e0, c, P2/rail]\n    - [0xac7c0, c, P2/rat]\n    - [0xade58, c, P2/rchm]\n    - [0xaf900, c, P2/render]\n    - [0xb0890, c, P2/rip]\n    - [0xb69e0, c, P2/rog]\n    - [0xbb3c0, c, P2/rope]\n    - [0xbbc78, c, P2/rumble]\n    - [0xbc000, c, P2/rwm]\n    - [0xbd618, c, P2/sampler]\n    - [0xbd970, c, P2/sc]\n    - [0xbe370, c, P2/screen]\n    - [0xc2d18, c, P2/sensor]\n    - [0xc6018, c, P2/shadow]\n    - [0xc6f08, c, P2/shape]\n    - [0xc7190, c, P2/shd]\n    - [0xc95e0, c, P2/shdanim]\n    - [0xca988, c, P2/sky]\n    - [0xcaa28, c, P2/slotheap]\n    - [0xcac48, c, P2/sm]\n    - [0xcbd98, c, P2/smartguard]\n    - [0xcc968, c, P2/so]\n    - [0xd1af8, c, P2/solve]\n    - [0xd3580, c, P2/sort]\n    - [0xd3710, c, P2/sound]\n    - [0xd6570, c, P2/speaker]\n    - [0xd6770, c, P2/spire]\n    - [0xd6850, c, P2/splicemap]\n    - [0xd6df8, c, P2/spliceobj]\n    - [0xd8050, c, P2/sprbuf]\n    - [0xd8640, c, P2/sqtr]\n    - [0xd9060, c, P2/squish]\n    - [0xd97a0, c, P2/step]\n    - [0xdb4c0, c, P2/stepact]\n    - [0xdb798, c, P2/stepcane]\n    - [0xdc540, c, P2/stepguard]\n    - [0xe1cf8, c, P2/stephang]\n    - [0xe3838, c, P2/stephide]\n    - [0xe5eb0, c, P2/steppipe]\n    - [0xe7110, c, P2/steppower]\n    - [0xe7628, c, P2/steprun]\n    - [0xe8188, c, P2/stepside]\n    - [0xe88b8, c, P2/stepski]\n    - [0xe9e30, c, P2/stepzap]\n    - [0xec048, c, P2/stream]\n    - [0xec360, c, P2/suv]\n    - [0xf0788, c, P2/sw]\n    - [0xf32e8, c, P2/tail]\n    - [0xf3e28, c, P2/tank]\n    - [0xf5940, c, P2/target]\n    - [0xf5b88, c, P2/text]\n    - [0xf78b8, c, P2/thread]\n    - [0xf7b38, c, P2/tn]\n    - [0xfa030, c, P2/transition]\n    - [0xfa758, c, P2/turret]\n    - [0xfb1b0, c, P2/tv]\n    - [0xfdec8, c, P2/ub]\n    - [0xff688, c, P2/ui]\n    - [0x1005b0, c, P2/update]\n    - [0x100ef0, c, P2/util]\n    - [0x102000, c, P2/vec]\n    - [0x102cc8, c, P2/vife]\n    - [0x10a658, c, P2/vifs]\n    - [0x10ac98, c, P2/vis]\n    - [0x10b070, c, P2/water]\n    - [0x10be78, c, P2/waypoint]\n    - [0x10c398, c, P2/wibu_ee]\n    - [0x10c4e8, c, P2/wipe]\n    - [0x10cd18, c, P2/wm]\n    - [0x10ee10, c, P2/wr]\n    - [0x110338, c, P2/xform]\n    - [0x111da0, c, P2/zap]\n\n    #----------------------------------------\n\n    - [0x113e00, data]\n\n    - [0x12e900, bin, vutext]\n\n    - [0x192d00, rodata]\n\n  - [0x1a1f80, databin]\n  - [0xBC8E6D]\n"
  },
  {
    "path": "config/symbol_addrs.txt",
    "content": "\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// MISC/UNKNOWN\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n_start = 0x100008; // type:func\n_exit = 0x1000B8; // type:func\n\n_gpReg = 0x2832F0;\n\ng_chzCiphertext = 0x2483b8; // size:0x9\ng_chzThePasswordIs = 0x24a848; // size:0x14\n\n//g_rng = 0x276680; // size:0x5c\n//g_prng = 0x27696c; // size:0x4\n\n// start of .vutext section\nD_00211E10 = 0x211E10; // size:0x4\n\n\nD_00270458 = 0x270458; // size:0x4\nSMP_00274f78 = 0x274f78; // size:0xC\n\n////////////////////////////////////////////////////////////////\n// ps2t/spaprops.ic\n////////////////////////////////////////////////////////////////\nBuildEopids__Fv = 0x109488; // type:func\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// P2 ENGINE\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\n////////////////////////////////////////////////////////////////\n// P2/splice/bif.cpp\n////////////////////////////////////////////////////////////////\nRefOpAdd__FiP4CRefP6CFrame      = 0x112698; // type:func\nRefOpSub__FiP4CRefP6CFrame      = 0x112968; // type:func\nRefOpMult__FiP4CRefP6CFrame     = 0x112C38; // type:func\nRefOpDiv__FiP4CRefP6CFrame      = 0x113240; // type:func\nRefOpPrint__FiP4CRefP6CFrame    = 0x113730; // type:func\nRefOpPrintFrame__FiP4CRefP6CFrame = 0x113780; // type:func\nRefOpPrintSidebag__FiP4CRefP6CFrame = 0x1137D0; // type:func\nRefOpIntEqual__FiP4CRefP6CFrame = 0x113820; // type:func\nRefCmp__FP4CRef4CMPK            = 0x113888; // type:func\nRefOpL__FiP4CRefP6CFrame        = 0x1139E8; // type:func\nRefOpLE__FiP4CRefP6CFrame       = 0x113A18; // type:func\nRefOpG__FiP4CRefP6CFrame        = 0x113A48; // type:func\nRefOpGE__FiP4CRefP6CFrame       = 0x113A78; // type:func\nRefOpEqv__FiP4CRefP6CFrame      = 0x113AA8; // type:func\nRefEqualHelper__FP4CRefT0       = 0x113B60; // type:func\nRefOpEqual__FiP4CRefP6CFrame    = 0x113E48; // type:func\nRefOpIsBoolean__FiP4CRefP6CFrame = 0x113E78; // type:func\nRefOpIsNum__FiP4CRefP6CFrame    = 0x113EE0; // type:func\nRefOpIsFloat__FiP4CRefP6CFrame  = 0x113F48; // type:func\nRefOpIsInteger__FiP4CRefP6CFrame = 0x113FB0; // type:func\nRefOpIsSymbol__FiP4CRefP6CFrame = 0x114018; // type:func\nRefOpIsVector__FiP4CRefP6CFrame = 0x114080; // type:func\nRefOpIsMatrix__FiP4CRefP6CFrame = 0x1140E8; // type:func\nRefOpIsClq__FiP4CRefP6CFrame    = 0x114150; // type:func\nRefOpIsLm__FiP4CRefP6CFrame     = 0x1141B8; // type:func\nRefOpIsSmp__FiP4CRefP6CFrame    = 0x114220; // type:func\nRefOpIsList__FiP4CRefP6CFrame   = 0x114288; // type:func\nRefOpIsNull__FiP4CRefP6CFrame   = 0x114300; // type:func\nRefOpIsObject__FiP4CRefP6CFrame = 0x114360; // type:func\nRefOpIsNullObj__FiP4CRefP6CFrame = 0x1143C8; // type:func\nRefOpIsMethod__FiP4CRefP6CFrame = 0x114438; // type:func\nRefOpIsProcedure__FiP4CRefP6CFrame = 0x1144A0; // type:func\nRefOpAreNear__FiP4CRefP6CFrame  = 0x114518; // type:func\nRefOpNot__FiP4CRefP6CFrame      = 0x1145C8; // type:func\nRefOpCons__FiP4CRefP6CFrame     = 0x114638; // type:func\nRefOpCar__FiP4CRefP6CFrame      = 0x1146E0; // type:func\nRefOpCdr__FiP4CRefP6CFrame      = 0x114740; // type:func\nRefOpSetCadr__FiP4CRefP6CFrame4BIFK = 0x1147B8; // type:func\nRefOpSetCar__FiP4CRefP6CFrame   = 0x114858; // type:func\nRefOpSetCdr__FiP4CRefP6CFrame   = 0x114888; // type:func\nRefOpLength__FiP4CRefP6CFrame   = 0x1148B8; // type:func\nRefOpNth__FiP4CRefP6CFrame      = 0x114950; // type:func\nRefOpIsMember__FiP4CRefP6CFrame = 0x1149F0; // type:func\nRefOpList__FiP4CRefP6CFrame     = 0x114B80; // type:func\nRefOpAppend__FiP4CRefP6CFrame   = 0x114BB0; // type:func\nRefOpMap__FiP4CRefP6CFrame      = 0x114D18; // type:func\nRefOpFilter__FiP4CRefP6CFrame   = 0x114F48; // type:func\nRefOpForEach__FiP4CRefP6CFrame  = 0x1151C0; // type:func\nRefOpEval__FiP4CRefP6CFrame     = 0x115398; // type:func\nRefOpVector__FiP4CRefP6CFrame   = 0x115440; // type:func\nRefOpMatrix__FiP4CRefP6CFrame   = 0x115510; // type:func\nRefOpSetMusicRegister__FiP4CRefP6CFrame = 0x1156B0; // type:func\nRefOpClq__FiP4CRefP6CFrame      = 0x115710; // type:func\nRefOpLm__FiP4CRefP6CFrame       = 0x1157E0; // type:func\nRefOpSmp__FiP4CRefP6CFrame      = 0x1158B8; // type:func\nRefOpGetElement__FiP4CRefP6CFrame = 0x1159B8; // type:func\nRefOpRandomSeed__FiP4CRefP6CFrame = 0x115B78; // type:func\nRefOpRandom__FiP4CRefP6CFrame   = 0x115C00; // type:func\nRefUfo__FP4CRef4UFOK            = 0x115CA0; // type:func\nRefOpSqrt__FiP4CRefP6CFrame     = 0x115D48; // type:func\nRefOpSin__FiP4CRefP6CFrame      = 0x115D78; // type:func\nRefOpCos__FiP4CRefP6CFrame      = 0x115DA8; // type:func\nRefOpTan__FiP4CRefP6CFrame      = 0x115DD8; // type:func\nRefOpAsin__FiP4CRefP6CFrame     = 0x115E08; // type:func\nRefOpAcos__FiP4CRefP6CFrame     = 0x115E38; // type:func\nRefOpAtan__FiP4CRefP6CFrame     = 0x115E68; // type:func\nRefOpRadNormalize__FiP4CRefP6CFrame = 0x115E98; // type:func\nRefOpAtan2__FiP4CRefP6CFrame    = 0x115EC8; // type:func\nRefOpVectorDotProduct__FiP4CRefP6CFrame = 0x115F70; // type:func\nRefOpVectorCrossProduct__FiP4CRefP6CFrame = 0x115FF8; // type:func\nRefOpVectorLth__FiP4CRefP6CFrame = 0x116080; // type:func\nRefOpVectorDistance__FiP4CRefP6CFrame = 0x116108; // type:func\nRefOpVectorDistanceSquared__FiP4CRefP6CFrame = 0x1161F8; // type:func\nRefOpVectorNormalize__FiP4CRefP6CFrame = 0x1162D0; // type:func\nRefOpVectorProjectNormal__FiP4CRefP6CFrame  = 0x116400; // type:func\nRefOpVectorProjectTangent__FiP4CRefP6CFrame = 0x116490; // type:func\nRefOpVectorBallisticVelocity__FiP4CRefP6CFrame = 0x116520; // type:func\nRefOpVectorRadianNormal__FiP4CRefP6CFrame = 0x116600; // type:func\nRefOpMatrixTranspose__FiP4CRefP6CFrame = 0x1166C0; // type:func\nRefOpMatrixInvert__FiP4CRefP6CFrame = 0x116740; // type:func\nRefOpMatrixCalculateDmat__FiP4CRefP6CFrame = 0x1167C0; // type:func\nRefOpMatrixInterpolateRotate__FiP4CRefP6CFrame = 0x116840; // type:func\nRefOpMatrixDecomposeToTranslate__FiP4CRefP6CFrame = 0x116978; // type:func\nRefOpMatrixDecomposeToRotate__FiP4CRefP6CFrame = 0x1169E8; // type:func\nRefOpMatrixDecomposeToEuler__FiP4CRefP6CFrame = 0x116A88; // type:func\nRefOpMatrixDecomposeToRadianNormal__FiP4CRefP6CFrame = 0x116B08; // type:func\nRefOpMatrixLookAt__FiP4CRefP6CFrame = 0x116BC8; // type:func\nRefOpMatrixTiltUpright__FiP4CRefP6CFrame = 0x116C80; // type:func\nRefOpClqEvaluate__FiP4CRefP6CFrame = 0x116D20; // type:func\nRefOpClqEvaluateLm__FiP4CRefP6CFrame = 0x116DC8; // type:func\nRefOpClqFit__FiP4CRefP6CFrame   = 0x116EA8; // type:func\nRefOpLmLimit__FiP4CRefP6CFrame  = 0x116FE8; // type:func\nRefOpLmCheck__FiP4CRefP6CFrame  = 0x117080; // type:func\nRefOpFloor__FiP4CRefP6CFrame    = 0x117118; // type:func\nRefOpCeiling__FiP4CRefP6CFrame  = 0x117180; // type:func\nRefOpRound__FiP4CRefP6CFrame    = 0x1171F0; // type:func\nRefOpTruncate__FiP4CRefP6CFrame = 0x117260; // type:func\nRefOpAbs__FiP4CRefP6CFrame      = 0x1172C8; // type:func\nRefOpMaximum__FiP4CRefP6CFrame  = 0x117360; // type:func\nRefOpMinimum__FiP4CRefP6CFrame  = 0x117478; // type:func\nRefOpModulo__FiP4CRefP6CFrame   = 0x117598; // type:func\nRefOpCurrentTime__FiP4CRefP6CFrame = 0x117610; // type:func\nRefOpScheduleCallback__FiP4CRefP6CFrame = 0x117668; // type:func\nRefOpDeferObjectUpdate__FiP4CRefP6CFrame = 0x117880; // type:func\nRefOpObjectOption__FiP4CRefP6CFrame4BIFK = 0x117910; // type:func\nRefOpAddO__FiP4CRefP6CFrame     = 0x117A30; // type:func\nRefOpEnsureO__FiP4CRefP6CFrame  = 0x117A60; // type:func\nRefOpSetO__FiP4CRefP6CFrame     = 0x117A90; // type:func\nRefOpGetO__FiP4CRefP6CFrame     = 0x117AC0; // type:func\nRefPairFromAplo__FiPP2LO        = 0x117AF0; // type:func\nRefOpFindObject__FiP4CRefP6CFrame = 0x117BC8; // type:func\nRefOpFindObjects__FiP4CRefP6CFrame = 0x117C48; // type:func\nRefOpFindNearestObject__FiP4CRefP6CFrame = 0x117D00; // type:func\nRefOpFindNearestObjects__FiP4CRefP6CFrame = 0x117D78; // type:func\nRefOpFindPlayerObject__FiP4CRefP6CFrame = 0x117E20; // type:func\nRefOpFindWorldObject__FiP4CRefP6CFrame = 0x117E78; // type:func\nRefOpFindCameraObject__FiP4CRefP6CFrame = 0x117ED0; // type:func\nRefOpFindClassObjects__FiP4CRefP6CFrame = 0x117F28; // type:func\nRefOpFindObjectsInBoundingBox__FiP4CRefP6CFrame = 0x117FE0; // type:func\nRefOpFindObjectsInBoundingSphere__FiP4CRefP6CFrame = 0x1180C0; // type:func\nRefOpHitTestObjectsImpl__F4BIFKiP4CRefP6CFrame = 0x118198; // type:func\nRefOpHitTestObjects__FiP4CRefP6CFrame = 0x1183B8; // type:func\nRefOpHitTestObjectsFirst__FiP4CRefP6CFrame = 0x118458; // type:func\nRefOpConvertObjectPosition__FiP4CRefP6CFrame = 0x1184F8; // type:func\nRefOpConvertObjectVector__FiP4CRefP6CFrame = 0x118580; // type:func\nRefOpConvertObjectMatrix__FiP4CRefP6CFrame = 0x118608; // type:func\nRefOpNearClipCenter__FiP4CRefP6CFrame = 0x118698; // type:func\nRefOpStartSound__FiP4CRefP6CFrame = 0x118720; // type:func\nRefOpStopSound__FiP4CRefP6CFrame = 0x1187E8; // type:func\nRefOpStartRumble__FiP4CRefP6CFrame = 0x118850; // type:func\nRefOpEmitSmokeCloud__FiP4CRefP6CFrame = 0x1188F0; // type:func\nRefOpPredictAnimationEffect__FiP4CRefP6CFrame = 0x118988; // type:func\n__8VU_FLOATf                    = 0x118CF0; // type:func\n__9VU_VECTORRC6VECTOR           = 0x118D10; // type:func\n__as__6VECTORG9VU_VECTOR        = 0x118D20; // type:func\n__ml__FG8VU_FLOATG9VU_VECTOR    = 0x118D30; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/eval.cpp\n////////////////////////////////////////////////////////////////\nRefEvalSymbol__FP5CPairP6CFrame     = 0x118D48; // type:func\nRefEvalSet__FP5CPairP6CFrame        = 0x118DB8; // type:func\nRefEvalDefine__FP5CPairP6CFrame     = 0x118E80; // type:func\nRefEvalAssert__FP5CPairP6CFrame     = 0x118F48; // type:func\nRefEvalIf__FP5CPairP6CFrame         = 0x119030; // type:func\nRefEvalOr__FP5CPairP6CFrame         = 0x119128; // type:func\nRefEvalAnd__FP5CPairP6CFrame        = 0x119218; // type:func\nRefEvalCond__FP5CPairP6CFrame       = 0x119310; // type:func\nRefEvalCase__FP5CPairP6CFrame       = 0x1194A8; // type:func\nRefEvalLet__FP5CPairP6CFrame        = 0x1196C8; // type:func\nRefEvalWhile__FP5CPairP6CFrame      = 0x119878; // type:func\nRefEvalLambda__FP5CPairP6CFrame     = 0x119970; // type:func\nRefEvalLambdaBody__FP5CPairP6CFrame = 0x119A58; // type:func\nRefEvalBegin__FP5CPairP6CFrame      = 0x119AF8; // type:func\nRefEvalApply__FP5CPairP6CFrame      = 0x119BB0; // type:func\nRefEvalImport__FP5CPairP6CFrame     = 0x119FA0; // type:func\nRefEval__FP5CPairP6CFrame           = 0x11A080; // type:func\n\nchzSpliceAssert                     = 0x249200; // size:0x10\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/frame.cpp\n////////////////////////////////////////////////////////////////\nSetSingleParent__6CFrameP6CFrame = 0x11A328; // type:func\nAddParent__6CFrameP6CFrame       = 0x11A338; // type:func\nRefAddBinding__6CFrameUiP4CRef   = 0x11A358; // type:func\nRefSetBinding__6CFrameUiP4CRef   = 0x11A400; // type:func\nFFindBinding__6CFrameUiiP4CRef   = 0x11A498; // type:func\nPrefFindBinding__6CFrameUii      = 0x11A4D8; // type:func\nCloneTo__6CFrameP6CFrame         = 0x11A5B0; // type:func\nPframeNew__Fv                    = 0x11A630; // type:func\nDeleteFrame__FP6CFrame           = 0x11A670; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/gc.cpp\n////////////////////////////////////////////////////////////////\n__3CGc                          = 0x11A678; // type:func\n_$_3CGc                         = 0x11A680; // type:func\nStartup__3CGc                   = 0x11A6A8; // type:func\nShutdown__3CGc                  = 0x11A6B8; // type:func\nAddRootFrame__3CGcP6CFrame      = 0x11A6C0; // type:func\nAddRootSidebag__3CGcP8CSidebag  = 0x11A708; // type:func\nPushFrame__3CGcP6CFrame         = 0x11A728; // type:func\nPframePop__3CGc                 = 0x11A748; // type:func\nPushPair__3CGcP5CPair           = 0x11A770; // type:func\nPpairPop__3CGc                  = 0x11A790; // type:func\nPushProc__3CGcP5CProc           = 0x11A7B8; // type:func\nPprocPop__3CGc                  = 0x11A7D8; // type:func\nUpdateRecyclable__3CGc          = 0x11A800; // type:func\nMarkLiveObjects__3CGc           = 0x11A850; // type:func\nCollect__3CGc                   = 0x11AB58; // type:func\ngc__static_initialization_and_destruction_0 = 0x11ADF8; // type:func\n_GLOBAL_$I$g_gc                 = 0x11AE38; // type:func\n_GLOBAL_$D$g_gc                 = 0x11AE58; // type:func\n\ng_gc                            = 0x259F38; // size:0x2314\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/method.cpp\n////////////////////////////////////////////////////////////////\nPmethodNew__Fv = 0x11AE78; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/pair.cpp\n////////////////////////////////////////////////////////////////\nCloneTo__5CPairP5CPairP6CFrame = 0x11AEB8; // type:func\nPpairNew__Fv                   = 0x11AF28; // type:func\nDeletePair__FP5CPair           = 0x11AF78; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/proc.cpp\n////////////////////////////////////////////////////////////////\nCloneTo__5CProcP5CProcP6CFrame = 0x11af98; // type:func\nPprocNew__Fv                   = 0x11afc8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/ref.cpp\n////////////////////////////////////////////////////////////////\n__4CRef = 0x11B008; // type:func\n__4CRefRC4CRef = 0x11B018; // type:func\n_$_4CRef = 0x11B060; // type:func\n__as__4CRefRC4CRef = 0x11B0A8; // type:func\n__eq__4CRefRC4CRef = 0x11B0F8; // type:func\nCloneTo__4CRefP4CRefP6CFrame = 0x11B258; // type:func\nDecref__4CRef = 0x11B418; // type:func\nIncref__4CRef = 0x11B4A8; // type:func\nSetTag__4CRef4TAGK = 0x11B538; // type:func\nSetS32__4CRefi = 0x11B570; // type:func\nSetF32__4CReff = 0x11B5B0; // type:func\nSetBool__4CRefi = 0x11B5F0; // type:func\nSetSymid__4CRefUi = 0x11B640; // type:func\nSetBifk__4CRef4BIFK = 0x11B680; // type:func\nSetPair__4CRefP5CPair = 0x11B6C0; // type:func\nSetProc__4CRefP5CProc = 0x11B700; // type:func\nSetVector__4CRefP6VECTOR = 0x11B740; // type:func\nSetMatrix__4CRefP7MATRIX4 = 0x11B788; // type:func\nSetClq__4CRefP3CLQ = 0x11B7D0; // type:func\nSetLm__4CRefP2LM = 0x11B818; // type:func\nSetSmp__4CRefP3SMP = 0x11B860; // type:func\nSetBasic__4CRefP5BASIC = 0x11B8A8; // type:func\nSetMethod__4CRefP7CMethod = 0x11B8E8; // type:func\nRefCoerceS32__4CRef = 0x11B928; // type:func\nRefCoerceF32__4CRef = 0x11B9A8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/serialize.cpp\n////////////////////////////////////////////////////////////////\nPpairSerializeIn__FP18CBinaryInputStream = 0x11BA28; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/sidebag.cpp\n////////////////////////////////////////////////////////////////\nRefAddBinding__8CSidebagiP4CRef = 0x11BD28; // type:func\nRefSetBinding__8CSidebagiP4CRef = 0x11BDD0; // type:func\nFFindBinding__8CSidebagiP4CRef  = 0x11BE90; // type:func\nCloneTo__8CSidebagP8CSidebag    = 0x11BEE0; // type:func\nPsidebagNew__Fv                 = 0x11BF30; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/spliceutils.cpp\n////////////////////////////////////////////////////////////////\nStartupSplice__Fv = 0x11BF70; // type:func\nShutdownSplice__Fv = 0x11C040; // type:func\nspliceutils__static_initialization_and_destruction_0 = 0x11C0A8; // type:func\n_GLOBAL_$I$g_splotheapPair = 0x11C0E8; // type:func\n_GLOBAL_$D$g_splotheapPair = 0x11C108; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/splotheap.cpp\n////////////////////////////////////////////////////////////////\nStartup__10CSplotheapii         = 0x11C128; // type:func\nShutdown__10CSplotheap          = 0x11C1D0; // type:func\nPvAllocUnsafe__10CSplotheap     = 0x11C1D8; // type:func\nPvAllocClear__10CSplotheap      = 0x11C240; // type:func\nPsplotLookup__10CSplotheapi     = 0x11C288; // type:func\nUpdateRecyclable__10CSplotheap  = 0x11C2A0; // type:func\nUnmarkAll__10CSplotheap         = 0x11C2B0; // type:func\nFreeGarbage__10CSplotheap       = 0x11C2E8; // type:func\nPvFromPsplot__FP5SPLOT          = 0x11C3B8; // type:func\nPsplotFromPv__FPv               = 0x11C3C0; // type:func\nFIsPvGarbage__FPv               = 0x11C3C8; // type:func\nMarkPvAlive__FPv                = 0x11C3F0; // type:func\nFUN_0011C418                    = 0x11C418; // type:func\nFUN_0011C498                    = 0x11C498; // type:func\nFUN_0011C4E8                    = 0x11C4E8; // type:func\n\ng_splotheapPair                 = 0x25C250; // size:0x1C\ng_splotheapFrame                = 0x25C270; // size:0x1C\ng_splotheapUnk1                 = 0x25C290; // size:0x1C\ng_splotheapProc                 = 0x25C2B0; // size:0x1C\ng_splotheapMethod               = 0x25C2D0; // size:0x1C\n\n\n////////////////////////////////////////////////////////////////\n// P2/splice/vecmat.cpp\n////////////////////////////////////////////////////////////////\nPvectorNew__Fv = 0x11c508; // type:func\nIncrefVector__FP6VECTOR = 0x11c580; // type:func\nDecrefVector__FP6VECTOR = 0x11c5b0; // type:func\njunk_0011C610 = 0x11C610; // type:func\nPmatrixNew__Fv = 0x11c618; // type:func\nIncrefMatrix__FP7MATRIX4 = 0x11c690; // type:func\nDecrefMatrix__FP7MATRIX4 = 0x11c6c0; // type:func\nDeleteMatrix__FP7MATRIX4 = 0x11c720; // type:func\nPclqNew__Fv = 0x11c748; // type:func\nIncrefClq__FP3CLQ = 0x11c7c0; // type:func\nDecrefClq__FP3CLQ = 0x11c7f0; // type:func\njunk_0011C850 = 0x11C850; // type:func\nPlmNew__Fv = 0x11c858; // type:func\nIncrefLm__FP2LM = 0x11c8d0; // type:func\nDecrefLm__FP2LM = 0x11c900; // type:func\njunk_0011C960 = 0x11C960; // type:func\nPsmpNew__Fv = 0x11c968; // type:func\nIncrefSmp__FP3SMP = 0x11c9e0; // type:func\nDecrefSmp__FP3SMP = 0x11ca20; // type:func\nStartupSpliceStructuredTypeFactories__Fv = 0x11ca90; // type:func\nShutdownSpliceStructuredTypeFactories__Fv = 0x11cbb0; // type:func\n\n_t18CStructTypeFactory1Z6VECTOR$s_cmax  = 0x25C2F0; // size:0x4\n_t18CStructTypeFactory1Z7MATRIX4$s_cmax = 0x25C2F4; // size:0x4\n_t18CStructTypeFactory1Z3CLQ$s_cmax     = 0x25C2F8; // size:0x4\n_t18CStructTypeFactory1Z2LM$s_cmax      = 0x25C2FC; // size:0x4\n_t18CStructTypeFactory1Z3SMP$s_cmax     = 0x25C300; // size:0x4\n\n_t18CStructTypeFactory1Z6VECTOR$s_acref  = 0x27B300; // size:0x4\n_t18CStructTypeFactory1Z7MATRIX4$s_acref = 0x27B304; // size:0x4\n_t18CStructTypeFactory1Z3CLQ$s_acref     = 0x27B308; // size:0x4\n_t18CStructTypeFactory1Z2LM$s_acref      = 0x27B30C; // size:0x4\n_t18CStructTypeFactory1Z3SMP$s_acref     = 0x27B310; // size:0x4\n\n_t18CStructTypeFactory1Z6VECTOR$s_slotheap  = 0x62C558; // size:0x10\n_t18CStructTypeFactory1Z7MATRIX4$s_slotheap = 0x62C568; // size:0x10\n_t18CStructTypeFactory1Z3CLQ$s_slotheap     = 0x62C578; // size:0x10\n_t18CStructTypeFactory1Z2LM$s_slotheap      = 0x62C588; // size:0x10\n_t18CStructTypeFactory1Z3SMP$s_slotheap     = 0x62C598; // size:0x10\n\n\n////////////////////////////////////////////////////////////////\n// P2/989snd.c\n////////////////////////////////////////////////////////////////\n// Unmangled names were in the header with extern \"C\"\nsnd_StartSoundSystem = 0x0011cbb8; //type:func size:632\nsnd_FlushSoundCommands = 0x0011ce30; //type:func size:556\njunk_0x0011d060 = 0x0011d060; //type:func size:24\nsnd_GotReturns__Fv = 0x0011d078; //type:func size:152\nsnd_PrepareReturnBuffer__FPUii = 0x0011d110; //type:func size:36\njunk_0x0011d138 = 0x0011d138; //type:func size:8\nsnd_BankLoadByLoc = 0x0011d140; //type:func size:356\nsnd_BankLoadByLoc_CB = 0x0011d2a8; //type:func size:316\njunk_0x0011d3e8 = 0x0011d3e8; //type:func size:56\nsnd_ResolveBankXREFS = 0x0011d420; //type:func size:44\nsnd_UnloadBank = 0x0011d450; //type:func size:48\nsnd_SetMasterVolume = 0x0011d480; //type:func size:52\nsnd_GetMasterVolume = 0x0011d4b8; //type:func size:40\nsnd_SetPlaybackMode = 0x0011d4e0; //type:func size:48\njunk_0x0011d510 = 0x0011d510; //type:func size:16\nsnd_SetMixerMode = 0x0011d520; //type:func size:52\nsnd_SetGroupVoiceRange = 0x0011d558; //type:func size:60\nsnd_PlaySoundVolPanPMPB = 0x0011d598; //type:func size:60\njunk_0x0011d5d8 = 0x0011d5d8; //type:func size:40\nsnd_StopSound = 0x0011d600; //type:func size:48\njunk_0x0011d630 = 0x0011d630; //type:func size:16\nsnd_PauseSound = 0x0011d640; //type:func size:48\nsnd_ContinueSound = 0x0011d670; //type:func size:48\njunk_0x0011d6a0 = 0x0011d6a0; //type:func size:8\nsnd_PauseAllSoundsInGroup = 0x0011d6a8; //type:func size:48\nsnd_ContinueAllSoundsInGroup = 0x0011d6d8; //type:func size:48\nsnd_SoundIsStillPlaying = 0x0011d708; //type:func size:40\nsnd_SoundIsStillPlaying_CB = 0x0011d730; //type:func size:48\nsnd_IsSoundALooper = 0x0011d760; //type:func size:44\njunk_0x0011d790 = 0x0011d790; //type:func size:8\nsnd_SetSoundVolPan = 0x0011d798; //type:func size:60\nsnd_GetSoundOriginalPitch = 0x0011d7d8; //type:func size:44\njunk_0x0011d808 = 0x0011d808; //type:func size:8\nsnd_SetSoundPitch = 0x0011d810; //type:func size:52\njunk_0x0011d848 = 0x0011d848; //type:func size:24\nsnd_AutoVol = 0x0011d860; //type:func size:60\njunk_0x0011d8a0 = 0x0011d8a0; //type:func size:16\nsnd_SetMIDIRegister = 0x0011d8b0; //type:func size:60\nsnd_GetMIDIRegister = 0x0011d8f0; //type:func size:44\njunk_0x0011d920 = 0x0011d920; //type:func size:8\nsnd_SetGlobalExcite = 0x0011d928; //type:func size:48\njunk_0x0011d958 = 0x0011d958; //type:func size:16\nsnd_SendIOPCommandAndWait__FiiPc = 0x0011d968; //type:func size:404\nsnd_SendIOPCommandNoWait__FiiPcPFiUl_vUl = 0x0011db00; //type:func size:724\nsnd_PostMessage__Fv = 0x0011ddd8; //type:func size:64\nsnd_SendCurrentBatch__Fv = 0x0011de18; //type:func size:316\nsnd_InitVAGStreamingEx = 0x0011df58; //type:func size:180\nsnd_StopAllStreams = 0x0011e010; //type:func size:44\njunk_0x0011e040 = 0x0011e040; //type:func size:8\nsnd_PlayVAGStreamByLoc = 0x0011e048; //type:func size:96\njunk_0x0011e0a8 = 0x0011e0a8; //type:func size:8\nsnd_ContinueVAGStream = 0x0011e0b0; //type:func size:48\nsnd_IsVAGStreamBuffered_CB = 0x0011e0e0; //type:func size:48\nsnd_StreamSafeCheckCDIdle = 0x0011e110; //type:func size:40\nsnd_StreamSafeCdRead = 0x0011e138; //type:func size:188\nsnd_StreamSafeCdSync = 0x0011e1f8; //type:func size:168\nsnd_StreamSafeCdBreak = 0x0011e2a0; //type:func size:72\nsnd_StreamSafeCdGetError = 0x0011e2e8; //type:func size:60\nsnd_SetReverbType = 0x0011e328; //type:func size:52\nsnd_SetReverbDepth = 0x0011e360; //type:func size:60\nsnd_PreAllocReverbWorkArea = 0x0011e3a0; //type:func size:52\njunk_0x0011e3d8 = 0x0011e3d8; //type:func size:80\nsnd_InitMovieSound = 0x0011e428; //type:func size:56\nsnd_ResetMovieSound = 0x0011e460; //type:func size:36\njunk_0x0011e488 = 0x0011e488; //type:func size:16\nsnd_CloseMovieSound = 0x0011e498; //type:func size:36\nsnd_StartMovieSound = 0x0011e4c0; //type:func size:56\nsnd_GetTransStatus = 0x0011e4f8; //type:func size:36\njunk_0x0011e520 = 0x0011e520; //type:func size:24\nsnd_GetDopplerPitchMod = 0x0011e538; //type:func size:36\n\ngCommBusy = 0x0025c340; // size:0x4\ngAwaitingInts = 0x0025c344; // size:0x4\ngUnkBankLoadError = 0x0025c348; // size:0x4\ngStreamingInited = 0x0025c34c; // size:0x4\ngCdCallback = 0x0025c350; // size:0x4\ngSSRead = 0x0025c354; // size:0x4\ngSSReadDone = 0x0025c358; // size:0x4\ngLoadingFromFS = 0x0025c35c; // size:0x4\ngSndCommandBuffePtr = 0x0025c360; // size:0x8\ngCommandBuffeBytesAvail = 0x0025c368; // size:0x8\ngSndCommandReturnDefPtr = 0x0025c370; // size:0x8\ngReturnValuesPtr = 0x0025c378; // size:0x8\ngCommandFillBuffer = 0x0025c380; // size:0x4\ngCaching = 0x0025c384; // size:0x4\ngLoadBusy = 0x0025c388; // size:0x4\ngLoadReturnDef = 0x0025c390; // size:0x10\ngLoadCB = 0x0025c3a0; // size:0x4\ngLoadUserData = 0x0025c3a8; // size:0x8\ngSyncBuffer = 0x0025c3c0; // size:0x40\ngSyncSendBuffer = 0x0025c400; // size:0x40\ngSyncStringBuffer = 0x0025c440; // size:0x100\ngSndCommandBuffer1 = 0x0025c540; // size:0x1000\ngSndCommandBuffer2 = 0x0025d540; // size:0x1000\ngSndCommandReturnDef1 = 0x0025e540; // size:0x1000\ngSndCommandReturnDef2 = 0x0025f540; // size:0x1000\ngActualReturnValues1 = 0x00260540; // size:0x420\ngActualReturnValues2 = 0x00260980; // size:0x420\ngStats = 0x00260dc0; // size:0x20\ngLoadReturnValue = 0x00260e00; // size:0x10\ngLoadParams = 0x00260e40; // size:0x20\ngSLClientData = 0x0027b4c8; // size:0x28\ngSLClientLoaderData = 0x027b4f0; // size:0x28\n\n\n////////////////////////////////////////////////////////////////\n// P2/brx.c\n////////////////////////////////////////////////////////////////\nStartupBrx__Fv = 0x11e560; // type:func\nPloNew__F3CIDP2SWP3ALO3OIDi = 0x11E580; // type:func\nLoadOptionFromBrx__FPvP5EOPIDP18CBinaryInputStream = 0x11E680; // type:func\nLoadOptionsFromBrx__FPvP18CBinaryInputStream = 0x11EC40; // type:func\nIploFromStockOid__Fi = 0x11ECA0; // type:func\nLoadSwObjectsFromBrx__FP2SWP3ALOP18CBinaryInputStream = 0x11ECB8; // type:func\nSetLoDefaults__FP2LO = 0x11EDA8; // type:func\n\ng_aeopid = 0x2505D8;\n\n\n////////////////////////////////////////////////////////////////\n// P2/ac.c\n////////////////////////////////////////////////////////////////\nFindKey__FfiiiPcPfT5PPv                                = 0x11EE70; // type:func\nEvaluateAcp__FP3ACPP3ALOffiP6VECTORT5                  = 0x11EF40; // type:func\nGetAcpTimes__FP3ACPPiPPf                               = 0x11EF48; // type:func\nEvaluateAcr__FP3ACRP3ALOffiP7MATRIX3P6VECTOR           = 0x11EF60; // type:func\nEvaluateAcrEul__FP3ACRP3ALOffiP6VECTORT5               = 0x11EF68; // type:func\nGetAcrTimes__FP3ACRPiPPf                               = 0x11EF70; // type:func\nEvaluateAcs__FP3ACSP3ALOfiP7MATRIX3                    = 0x11EF88; // type:func\nGetAcsTimes__FP3ACSPiPPf                               = 0x11EF90; // type:func\nEvaluateAcg__FP3ACGP3ALOffiPfT5                        = 0x11EFA8; // type:func\nGetAcgTimes__FP3ACGPiPPf                               = 0x11EFB0; // type:func\nLoadAcgbFromBrx__FP4ACGBP18CBinaryInputStream          = 0x11EFC8; // type:func\nEvaluateAcgb__FP4ACGBP3ALOffiPfT5                      = 0x11F0C8; // type:func\nGetAcgbTimes__FP4ACGBPiPPf                             = 0x11F180; // type:func\nLoadAcgbwFromBrx__FP5ACGBWP18CBinaryInputStream        = 0x11F210; // type:func\nEvaluateAcgbw__FP5ACGBWP3ALOffiPfT5                    = 0x11F320; // type:func\nGetAcgbwTimes__FP5ACGBWPiPPf                           = 0x11F3E8; // type:func\nEvaluateAcgl__FP4ACGLP3ALOffiPfT5                      = 0x11F478; // type:func\nLoadAcglFromBrx__FP4ACGLP18CBinaryInputStream          = 0x11F568; // type:func\nGetAcglTimes__FP4ACGLPiPPf                             = 0x11F620; // type:func\nEvaluateApacg__FPP3ACGP3ALOffiP6VECTORN25              = 0x11F6B0; // type:func\nLoadApacgFromBrx__FPP3ACGP6VECTORP18CBinaryInputStream = 0x11F798; // type:func\nGetApacgTimes__FPP3ACGPiPPf                            = 0x11F850; // type:func\nEvaluateAkvb__FiP3KVBffiP6VECTORT5                     = 0x11F9F8; // type:func\nLoadAkvbFromBrx__FPiPP3KVBP18CBinaryInputStream        = 0x11FA88; // type:func\nGetAkvbTimes__FiP3KVBPiPPf                             = 0x11FB98; // type:func\nEvaluateAcpc__FP4ACPCP3ALOffiP6VECTORT5                = 0x11FC20; // type:func\nLoadAcpcFromBrx__FP4ACPCP18CBinaryInputStream          = 0x11FC90; // type:func\nGetAcpcTimes__FP4ACPCPiPPf                             = 0x11FDB8; // type:func\nEvaluateAcpb__FP4ACPBP3ALOffiP6VECTORT5                = 0x11FDD8; // type:func\nLoadAcpbFromBrx__FP4ACPBP18CBinaryInputStream          = 0x11FE40; // type:func\nGetAcpbTimes__FP4ACPBPiPPf                             = 0x11FED8; // type:func\nEvaluateAcrc__FP4ACRCP3ALOffiP7MATRIX3P6VECTOR         = 0x11FF08; // type:func\nEvaluateAcrcEul__FP4ACRCP3ALOffiP6VECTORT5             = 0x11FFA8; // type:func\nLoadAcrcFromBrx__FP4ACRCP18CBinaryInputStream          = 0x11FFD8; // type:func\nGetAcrcTimes__FP4ACRCPiPPf                             = 0x120110; // type:func\nEvaluateAcrb__FP4ACRBP3ALOffiP7MATRIX3P6VECTOR         = 0x120130; // type:func\nEvaluateAcrbEul__FP4ACRBP3ALOffiP6VECTORT5             = 0x1201D0; // type:func\nLoadAcrbFromBrx__FP4ACRBP18CBinaryInputStream          = 0x1201F0; // type:func\nGetAcrbTimes__FP4ACRBPiPPf                             = 0x1202C0; // type:func\nEvaluateAcsc__FP4ACSCP3ALOfiP7MATRIX3                  = 0x1202F0; // type:func\nLoadAcscFromBrx__FP4ACSCP18CBinaryInputStream          = 0x120360; // type:func\nGetAcscTimes__FP4ACSCPiPPf                             = 0x120388; // type:func\nEvaluateAcsb__FP4ACSBP3ALOfiP7MATRIX3                  = 0x1203A8; // type:func\nLoadAcsbFromBrx__FP4ACSBP18CBinaryInputStream          = 0x120418; // type:func\nGetAcsbTimes__FP4ACSBPiPPf                             = 0x120440; // type:func\nEvaluateAcpbl__FP5ACPBLP3ALOffiP6VECTORT5              = 0x120470; // type:func\nEvaluateAcrbl__FP5ACRBLP3ALOffiP7MATRIX3P6VECTOR       = 0x120700; // type:func\nEvaluateAcgblt__FP6ACGBLTP3ALOffiPfT5                  = 0x120AA8; // type:func\nEvaluateAcgblp__FP6ACGBLPP3ALOffiPfT5                  = 0x120D58; // type:func\nPacpNew__F4ACVK                                        = 0x120FB0; // type:func\nPacrNew__F4ACVK                                        = 0x121050; // type:func\nPacsNew__F4ACVK                                        = 0x1210F0; // type:func\nPacgNew__F4ACGK                                        = 0x121160; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/act.c\n////////////////////////////////////////////////////////////////\nPactNew__FP2SWP3ALOP5VTACT                             = 0x121228; // type:func\nPactNewClone__FP3ACTP2SWP3ALO                          = 0x121280; // type:func\nCloneAct__FP3ACTT0                                     = 0x1212D8; // type:func\nInitAct__FP3ACTP3ALO                                   = 0x121338; // type:func\nRetractAct__FP3ACTi                                    = 0x121358; // type:func\nGetActPositionGoal__FP3ACTfP6VECTORT2                  = 0x1214B8; // type:func\nGetActRotationGoal__FP3ACTfP7MATRIX3P6VECTOR           = 0x121508; // type:func\nGetActTwistGoal__FP3ACTPfT1                            = 0x121568; // type:func\nGetActScale__FP3ACTP7MATRIX3                           = 0x121580; // type:func\nGGetActPoseGoal__FP3ACTi                               = 0x1215A8; // type:func\nCalculateActDefaultAck__FP3ACT                         = 0x1215C0; // type:func\nSnapAct__FP3ACTi                                       = 0x121648; // type:func\nCalculateAloPositionSpring__FP3ALOfP6VECTORN22         = 0x121760; // type:func\nProjectActPosition__FP3ACT                             = 0x1218C0; // type:func\nCalculateAloRotationSpring__FP3ALOfP7MATRIX3P6VECTORT3 = 0x121C48; // type:func\nProjectActRotation__FP3ACT                             = 0x121DE0; // type:func\nProjectActPose__FP3ACTi                                = 0x122488; // type:func\nPredictAloPosition__FP3ALOfP6VECTORT2                  = 0x122550; // type:func\nPredictAloRotation__FP3ALOfP7MATRIX3P6VECTOR           = 0x1225D0; // type:func\nAdaptAct__FP3ACT                                       = 0x1226D8; // type:func\nInitActval__FP6ACTVALP3ALO                             = 0x122708; // type:func\nGetActvalPositionGoal__FP6ACTVALfP6VECTORT2            = 0x1227B0; // type:func\nGetActvalRotationGoal__FP6ACTVALfP7MATRIX3P6VECTOR     = 0x1227F0; // type:func\nGetActvalTwistGoal__FP6ACTVALPfT1                      = 0x122840; // type:func\nGetActvalScale__FP6ACTVALP7MATRIX3                     = 0x122858; // type:func\nGGetActvalPoseGoal__FP6ACTVALi                         = 0x122878; // type:func\nInitActref__FP6ACTREFP3ALO                             = 0x122890; // type:func\nGetActrefPositionGoal__FP6ACTREFfP6VECTORT2            = 0x122920; // type:func\nGetActrefRotationGoal__FP6ACTREFfP7MATRIX3P6VECTOR     = 0x122968; // type:func\nGetActrefTwistGoal__FP6ACTREFPfT1                      = 0x1229C0; // type:func\nGetActrefScale__FP6ACTREFP7MATRIX3                     = 0x1229E0; // type:func\nGGetActrefPoseGoal__FP6ACTREFi                         = 0x122A00; // type:func\nInitActadj__FP6ACTADJP3ALO                             = 0x122A18; // type:func\nGetActadjPositionGoal__FP6ACTADJfP6VECTORT2            = 0x122A80; // type:func\nGetActadjRotationGoal__FP6ACTADJfP7MATRIX3P6VECTOR     = 0x122B30; // type:func\nGetActadjTwistGoal__FP6ACTADJPfT1                      = 0x122C48; // type:func\nGetActadjScale__FP6ACTADJP7MATRIX3                     = 0x122CB0; // type:func\nGGetActadjPoseGoal__FP6ACTADJi                         = 0x122D90; // type:func\nInitActbank__FP7ACTBANKP3ALO                           = 0x122DA0; // type:func\nGetActbankRotationGoal__FP7ACTBANKfP7MATRIX3P6VECTOR   = 0x122DE0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/actseg.c\n////////////////////////////////////////////////////////////////\nRetractActseg__FP6ACTSEGi = 0x122F28; // type:func\nCloneActseg__FP6ACTSEGT0 = 0x122F88; // type:func\nGetActsegPositionGoal__FP6ACTSEGfP6VECTORT2 = 0x122FE0; // type:func\nGetActsegRotationGoal__FP6ACTSEGfP7MATRIX3P6VECTOR = 0x123120; // type:func\nGetActsegTwistGoal__FP6ACTSEGPfT1 = 0x123270; // type:func\nGetActsegScale__FP6ACTSEGP7MATRIX3 = 0x1232E8; // type:func\nGGetActsegPoseGoal__FP6ACTSEGi = 0x123358; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/alarm.c\n////////////////////////////////////////////////////////////////\nBreakAlbrk__FP5ALBRK                          = 0x1233C0; // type:func\nSetAlbrkAlarm__FP5ALBRKP5ALARM                = 0x123400; // type:func\nInitAlarm__FP5ALARM                           = 0x123408; // type:func\nPostAlarmLoad__FP5ALARM                       = 0x123448; // type:func\nCloneAlarm__FP5ALARMT0                        = 0x123540; // type:func\nUpdateAlarm__FP5ALARMf                        = 0x123578; // type:func\nPostAlarmLoadCallbackHookup__FP5ALARM5MSGIDPv = 0x1236C8; // type:func\nSetAlarmAlarms__FP5ALARM6ALARMS               = 0x123888; // type:func\nTriggerAlarm__FP5ALARM4ALTK                   = 0x123AB0; // type:func\nDisableAlarmAlbrk__FP5ALARM                   = 0x123B18; // type:func\nEnableAlarmSensors__FP5ALARM                  = 0x123B28; // type:func\nDisableAlarmSensors__FP5ALARM                 = 0x123BB0; // type:func\nNotifyAlarmSensorsOnTrigger__FP5ALARM         = 0x123C20; // type:func\nAddAlarmAlbrk__FP5ALARM3OID                   = 0x123C90; // type:func\nAddAlarmSensor__FP5ALARM3OID                  = 0x123CB8; // type:func\nAddAlarmStepguard__FP5ALARM3OID               = 0x123CE0; // type:func\nSetAlarmRsmg__FP5ALARMi3OIDN22                = 0x123D08; // type:func\nFGetAlarmSensorList__FP5ALARMPv               = 0x123D40; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/alo.c\n////////////////////////////////////////////////////////////////\nFIsZeroV__FP6VECTOR                                        = 0x123DC0; // type:func\nFIsZeroW__FP6VECTOR                                        = 0x123E00; // type:func\nFIsZeroDv__FP6VECTOR                                       = 0x123E48; // type:func\nFIsZeroDw__FP6VECTOR                                       = 0x123E88; // type:func\nInitAlo__FP3ALO                                            = 0x123ED0; // type:func\nAddAloHierarchy__FP3ALO                                    = 0x124050; // type:func\nOnAloAdd__FP3ALO                                           = 0x1240F8; // type:func\nRemoveAloHierarchy__FP3ALO                                 = 0x124338; // type:func\nOnAloRemove__FP3ALO                                        = 0x1243E0; // type:func\nUpdateAloOrig__FP3ALO                                      = 0x124540; // type:func\nSetAloParent__FP3ALOT0                                     = 0x1245A8; // type:func\nApplyAloProxy__FP3ALOP5PROXY                               = 0x124868; // type:func\nBindAlo__FP3ALO                                            = 0x1249A8; // type:func\nPostAloLoad__FP3ALO                                        = 0x124A48; // type:func\nPostAloLoadCallback__FP3ALO5MSGIDPv                        = 0x124CC0; // type:func\nSnipAloObjects__FP3ALOiP4SNIP                              = 0x124DF8; // type:func\nUpdateAloHierarchy__FP3ALOf                                = 0x124EE8; // type:func\nUpdateAlo__FP3ALOf                                         = 0x124FC0; // type:func\nInvalidateAloLighting__FP3ALO                              = 0x1250C8; // type:func\nUpdateAloXfWorld__FP3ALO                                   = 0x125108; // type:func\nUpdateAloXfWorldHierarchy__FP3ALO                          = 0x125138; // type:func\nPresetAloAccel__FP3ALOf                                    = 0x125438; // type:func\nProjectAloTransform__FP3ALOfi                              = 0x125440; // type:func\nPredictAloTransform__FP3ALOT0fP6VECTORP7MATRIX3T3T3        = 0x125750; // type:func\nPredictAloTransformAdjust__FP3ALOT0fP6VECTORP7MATRIX3T3T3  = 0x1259D8; // type:func\nDupAloRo__FP3ALOP2ROT1                                     = 0x125B70; // type:func\nRenderFastShadow__FP3ALOP2CMP2RO                           = 0x125BF0; // type:func\nRenderAloAll__FP3ALOP2CMP2RO                               = 0x125C90; // type:func\nRenderAloSelf__FP3ALOP2CMP2RO                              = 0x1261C0; // type:func\nRenderAloGlobset__FP3ALOP2CMP2RO                           = 0x126270; // type:func\nRenderAloLine__FP3ALOP2CMP6VECTORT2ff                      = 0x1268B8; // type:func\nSetAloOverrideCel__FP3ALOG4RGBA                            = 0x126A48; // type:func\nFUN_00126ab0                                               = 0x126AB0; // type:func\nUpdateAloThrob__FP3ALOf                                    = 0x126AC8; // type:func\nSetAloBlotContext__FP3ALOP4BLOT                            = 0x126BC0; // type:func\nEnsureAloFader__FP3ALO                                     = 0x126C58; // type:func\nFadeAloIn__FP3ALOf                                         = 0x126CB8; // type:func\nFadeAloOut__FP3ALOf                                        = 0x126D60; // type:func\nAdjustAloRtckMat__FP3ALOP2CM4RTCKP6VECTORP7MATRIX4         = 0x126DE8; // type:func\nCloneAloHierarchy__FP3ALOT0                                = 0x126F78; // type:func\nCloneAlo__FP3ALOT0                                         = 0x127048; // type:func\nHandleAloMessage__FP3ALO5MSGIDPv                           = 0x127378; // type:func\nTranslateAloToPos__FP3ALOP6VECTOR                          = 0x1273F0; // type:func\njunk_00127468                                              = 0x127468; // type:func\nRotateAloToMat__FP3ALOP7MATRIX3                            = 0x127478; // type:func\nSetAloVelocityVec__FP3ALOP6VECTOR                          = 0x1274F8; // type:func\nSetAloVelocityXYZ__FP3ALOfff                               = 0x127558; // type:func\nSetAloAngularVelocityVec__FP3ALOP6VECTOR                   = 0x127590; // type:func\nSetAloAngularVelocityXYZ__FP3ALOfff                        = 0x1275F0; // type:func\nSetAloVelocityLocal__FP3ALOP6VECTOR                        = 0x127628; // type:func\nGetAloVelocityLocal__FP3ALOP6VECTOR                        = 0x127678; // type:func\nMatchAloOtherObject__FP3ALOT0                              = 0x1276C0; // type:func\nCalculateAloMovement__FP3ALOT0P6VECTORN42                  = 0x1278A8; // type:func\nCalculateAloTransform__FP3ALOT0iP6VECTORP7MATRIX3T3T3      = 0x127B20; // type:func\nCalculateAloTransformAdjust__FP3ALOT0P6VECTORP7MATRIX3T2T2 = 0x127E60; // type:func\nConvertAloPos__FP3ALOT0P6VECTORT2                          = 0x128018; // type:func\nConvertAloVec__FP3ALOT0P6VECTORT2                          = 0x1280C0; // type:func\nConvertAloMat__FP3ALOT0P7MATRIX3T2                         = 0x128150; // type:func\nFDrivenAlo__FP3ALO                                         = 0x128230; // type:func\nRetractAloDrive__FP3ALO                                    = 0x128278; // type:func\nConvertAloMovement__FP3ALOT0P6VECTORN82                    = 0x128330; // type:func\nCalculateAloDrive__FP3ALOP3CLQP2LMffPfN25                  = 0x128598; // type:func\nFGetAloChildrenList__FP3ALOPv                              = 0x1288F0; // type:func\nPactsegNewAlo__FP3ALO                                      = 0x128998; // type:func\nLoadAloFromBrx__FP3ALOP18CBinaryInputStream                = 0x1289C0; // type:func\nLoadAloAloxFromBrx__FP3ALOP18CBinaryInputStream            = 0x128C10; // type:func\nBindAloAlox__FP3ALO                                        = 0x128DB8; // type:func\nAdjustAloRotation__FP3ALOP7MATRIX3P6VECTOR                 = 0x128E88; // type:func\nUnadjustAloRotation__FP3ALOP7MATRIX3                       = 0x128FD0; // type:func\nSetAloInitialVelocity__FP3ALOP6VECTOR                      = 0x1290B8; // type:func\nSetAloInitialAngularVelocity__FP3ALOP6VECTOR               = 0x1290E0; // type:func\nPasegdEnsureAlo__FP3ALO                                    = 0x129108; // type:func\nSetAloFastShadowRadius__FP3ALOf                            = 0x129170; // type:func\nGetAloFastShadowRadius__FP3ALOPf                           = 0x129188; // type:func\nSetAloFastShadowDepth__FP3ALOf                             = 0x1291A0; // type:func\nGetAloFastShadowDepth__FP3ALOPf                            = 0x1291B8; // type:func\nPshadowAloEnsure__FP3ALO                                   = 0x1291D0; // type:func\nSetAloCastShadow__FP3ALOi                                  = 0x129228; // type:func\nSetAloShadowShader__FP3ALO3OID                             = 0x129288; // type:func\nSetAloShadowNearRadius__FP3ALOf                            = 0x1292B8; // type:func\nSetAloShadowFarRadius__FP3ALOf                             = 0x1292E8; // type:func\nSetAloShadowNearCast__FP3ALOf                              = 0x129318; // type:func\nSetAloShadowFarCast__FP3ALOf                               = 0x129348; // type:func\nSetAloShadowConeAngle__FP3ALOf                             = 0x129378; // type:func\nSetAloShadowFrustrumUp__FP3ALOP6VECTOR                     = 0x1293A8; // type:func\nSetAloDynamicShadowObject__FP3ALO3OID                      = 0x1293D8; // type:func\nPshadowInferAlo__FP3ALO                                    = 0x129400; // type:func\nGetAloCastShadow__FP3ALOPi                                 = 0x129440; // type:func\nGetAloShadowShader__FP3ALOP3OID                            = 0x129450; // type:func\nGetAloShadowNearRadius__FP3ALOPf                           = 0x129480; // type:func\nGetAloShadowFarRadius__FP3ALOPf                            = 0x1294B0; // type:func\nGetAloShadowNearCast__FP3ALOPf                             = 0x1294E0; // type:func\nGetAloShadowFarCast__FP3ALOPf                              = 0x129510; // type:func\nGetAloShadowConeAngle__FP3ALOPf                            = 0x129540; // type:func\nGetAloShadowFrustrumUp__FP3ALOP6VECTOR                     = 0x129598; // type:func\nGetAloEuler__FP3ALOP6VECTOR                                = 0x1295C8; // type:func\nSetAloEuler__FP3ALOP6VECTOR                                = 0x129648; // type:func\nEnsureAloActRestore__FP3ALO                                = 0x1296E0; // type:func\nEnsureAloActla__FP3ALO                                     = 0x129730; // type:func\nRecacheAloActList__FP3ALO                                  = 0x129780; // type:func\nInsertAloAct__FP3ALOP3ACT                                  = 0x1299E0; // type:func\nResortAloActList__FP3ALO                                   = 0x129A58; // type:func\nPasegaFindAlo__FP3ALO3OID                                  = 0x129B98; // type:func\nPsmaFindAlo__FP3ALO3OID                                    = 0x129C20; // type:func\nPasegaFindAloNearest__FP3ALO                               = 0x129CA8; // type:func\nCreateAloActadj__FP3ALOiPP6ACTADJ                          = 0x129D00; // type:func\nFIsAloStatic__FP3ALO                                       = 0x129D70; // type:func\nResolveAlo__FP3ALO                                         = 0x129DF8; // type:func\nSetAloPositionSpring__FP3ALOf                              = 0x129E10; // type:func\nSetAloPositionSpringDetail__FP3ALOP3CLQ                    = 0x129E88; // type:func\nSetAloPositionDamping__FP3ALOf                             = 0x129EE0; // type:func\nSetAloPositionDampingDetail__FP3ALOP3CLQ                   = 0x129F58; // type:func\nSetAloRotationSpring__FP3ALOf                              = 0x129FB0; // type:func\nSetAloRotationSpringDetail__FP3ALOP3CLQ                    = 0x12A028; // type:func\nSetAloRotationDamping__FP3ALOf                             = 0x12A080; // type:func\nSetAloRotationDampingDetail__FP3ALOP3CLQ                   = 0x12A0F8; // type:func\nSetAloPositionSmooth__FP3ALOf                              = 0x12A150; // type:func\nSetAloPositionSmoothMaxAccel__FP3ALOf                      = 0x12A1A0; // type:func\nSetAloPositionSmoothDetail__FP3ALOP4SMPA                   = 0x12A200; // type:func\nSetAloRotationSmooth__FP3ALOf                              = 0x12A270; // type:func\nSetAloRotationSmoothMaxAccel__FP3ALOf                      = 0x12A2C0; // type:func\nSetAloRotationSmoothDetail__FP3ALOP4SMPA                   = 0x12A320; // type:func\nSetAloDefaultAckPos__FP3ALO3ACK                            = 0x12A390; // type:func\nSetAloDefaultAckRot__FP3ALO3ACK                            = 0x12A398; // type:func\nSetAloRestorePosition__FP3ALOi                             = 0x12A3A0; // type:func\nFUN_0012a3c8                                               = 0x12A3C8; // type:func\nFUN_0012a3e8                                               = 0x12A3E8; // type:func\nFUN_0012a418                                               = 0x12A418; // type:func\nSetAloRestorePositionAck__FP3ALO3ACK                       = 0x12A430; // type:func\nSetAloRestoreRotation__FP3ALOi                             = 0x12A478; // type:func\nSetAloRestoreRotationAck__FP3ALO3ACK                       = 0x12A4A0; // type:func\nFUN_0012a4e8                                               = 0x12A4E8; // type:func\nSetAloLookAt__FP3ALO3ACK                                   = 0x12A528; // type:func\nSetAloLookAtIgnore__FP3ALOf                                = 0x12A580; // type:func\nGetAloLookAtIgnore__FP3ALOPf                               = 0x12A5B8; // type:func\nSetAloLookAtPanFunction__FP3ALOP3CLQ                       = 0x12A5D0; // type:func\nGetAloLookAtPanFunction__FP3ALOP3CLQ                       = 0x12A610; // type:func\nSetAloLookAtPanLimits__FP3ALOP2LM                          = 0x12A630; // type:func\nGetAloLookAtPanLimits__FP3ALOP2LM                          = 0x12A678; // type:func\nSetAloLookAtTiltFunction__FP3ALOP3CLQ                      = 0x12A6A0; // type:func\nGetAloLookAtTiltFunction__FP3ALOP3CLQ                      = 0x12A6E0; // type:func\nSetAloLookAtTiltLimits__FP3ALOP2LM                         = 0x12A700; // type:func\nGetAloLookAtTiltLimits__FP3ALOP2LM                         = 0x12A748; // type:func\nSetAloLookAtEnabledPriority__FP3ALOi                       = 0x12A770; // type:func\nGetAloLookAtEnabledPriority__FP3ALOPi                      = 0x12A7A8; // type:func\nSetAloLookAtDisabledPriority__FP3ALOi                      = 0x12A7C0; // type:func\nGetAloLookAtDisabledPriority__FP3ALOPi                     = 0x12A7F8; // type:func\nFUN_0012a810                                               = 0x12A810; // type:func\nFUN_0012a848                                               = 0x12A848; // type:func\nFUN_0012a860                                               = 0x12A860; // type:func\nFUN_0012a888                                               = 0x12A888; // type:func\nFUN_0012a8b8                                               = 0x12A8B8; // type:func\nFUN_0012a8c8                                               = 0x12A8C8; // type:func\nSetAloRotationMatchesVelocity__FP3ALOff3ACK                = 0x12A8D8; // type:func\nPtargetEnsureAlo__FP3ALO                                   = 0x12A970; // type:func\nSetAloTargetAttacks__FP3ALOi                               = 0x12A9C8; // type:func\nSetAloTargetRadius__FP3ALOf                                = 0x12AA00; // type:func\nSetAloTargetHitTest__FP3ALOi                               = 0x12AA28; // type:func\nSetAloScrollingMasterSpeeds__FP3ALOff                      = 0x12AA50; // type:func\nSetAloEyesClosed__FP3ALOf                                  = 0x12AAE8; // type:func\nEnsureAloSfx__FP3ALO                                       = 0x12ABA8; // type:func\nSetAloSfxid__FP3ALO5SFXID                                  = 0x12ABD0; // type:func\nSetAloSfxidSpl__FP3ALO5SFXID                               = 0x12AC08; // type:func\nGetAloSfxid__FP3ALOP5SFXID                                 = 0x12AC88; // type:func\nSetAloSStart__FP3ALOf                                      = 0x12ACA0; // type:func\nGetAloSStart__FP3ALOPf                                     = 0x12ACD8; // type:func\nSetAloSFull__FP3ALOf                                       = 0x12ACF8; // type:func\nSetAloSndRepeat__FP3ALOP2LM                                = 0x12AD30; // type:func\nGetAloSFull__FP3ALOPf                                      = 0x12AD78; // type:func\nSetAloUVolume__FP3ALOf                                     = 0x12AD98; // type:func\nSetAloUDoppler__FP3ALOf                                    = 0x12ADD0; // type:func\nGetAloUDoppler__FP3ALOPf                                   = 0x12AE08; // type:func\nSetAloUVolumeSpl__FP3ALOf                                  = 0x12AE20; // type:func\nGetAloUVolume__FP3ALOPf                                    = 0x12AE58; // type:func\nSetAloUPitch__FP3ALOf                                      = 0x12AE78; // type:func\nSetAloUPitchSpl__FP3ALOf                                   = 0x12AEB0; // type:func\nGetAloUPitch__FP3ALOPf                                     = 0x12AEE8; // type:func\nGetAloSndRepeat__FP3ALOP2LM                                = 0x12AF00; // type:func\nStartAloSound__FP3ALO5SFXIDfffP2LM                         = 0x12AF38; // type:func\nStopAloSound__FP3ALO                                       = 0x12B010; // type:func\nEnsureAloThrob__FP3ALO                                     = 0x12B040; // type:func\nSetAloThrobKind__FP3ALO6THROBK                             = 0x12B0B0; // type:func\nGetAloThrobKind__FP3ALOP6THROBK                            = 0x12B128; // type:func\nSetAloThrobInColor__FP3ALOP6VECTOR                         = 0x12B140; // type:func\nGetAloThrobInColor__FP3ALOP6VECTOR                         = 0x12B180; // type:func\nSetAloThrobOutColor__FP3ALOP6VECTOR                        = 0x12B1A0; // type:func\nGetAloThrobOutColor__FP3ALOP6VECTOR                        = 0x12B1E0; // type:func\nSetAloThrobDtInOut__FP3ALOf                                = 0x12B200; // type:func\nGetAloThrobDtInOut__FP3ALOPf                               = 0x12B238; // type:func\nSetAloInteractCane__FP3ALOi                                = 0x12B250; // type:func\nGetAloInteractCane__FP3ALOPi                               = 0x12B260; // type:func\nSetAloInteractCaneSweep__FP3ALOi                           = 0x12B270; // type:func\nGetAloInteractCaneSweep__FP3ALOPi                          = 0x12B278; // type:func\nSetAloInteractCaneRush__FP3ALOi                            = 0x12B288; // type:func\nGetAloInteractCaneRush__FP3ALOPi                           = 0x12B290; // type:func\nSetAloInteractCaneSmash__FP3ALOi                           = 0x12B2A0; // type:func\nGetAloInteractCaneSmash__FP3ALOPi                          = 0x12B2A8; // type:func\nSetAloInteractBomb__FP3ALOi                                = 0x12B2B8; // type:func\nGetAloInteractBomb__FP3ALOPi                               = 0x12B2C0; // type:func\nSetAloInteractShock__FP3ALOi                               = 0x12B2D0; // type:func\nGetAloInteractShock__FP3ALOPi                              = 0x12B2D8; // type:func\nFAbsorbAloWkr__FP3ALOP3WKR                                 = 0x12B2E8; // type:func\nSetAloPoseCombo__FP3ALO3OID                                = 0x12B2F8; // type:func\nSetAloForceCameraFade__FP3ALOi                             = 0x12B420; // type:func\nSetAloRealClock__FP3ALOi                                   = 0x12B4C8; // type:func\nFUN_0012b550                                               = 0x12B550; // type:func\nFUN_0012b590                                               = 0x12B590; // type:func\nFUN_0012b5b8                                               = 0x12B5B8; // type:func\njunk_0012B6A0                                              = 0x12B6A0; // type:func\nFUN_0012b6b8                                               = 0x12B6B8; // type:func\nanticrack_itm_firewall                                     = 0x12B760; // type:func\n\n// TODO: Where do these belong to?\ng_vtactseg = 0x2197c0;\ns_shadow = 0x27b520;\n\n\n////////////////////////////////////////////////////////////////\n// P2/aseg.c\n////////////////////////////////////////////////////////////////\nStartupAseg__Fv                                             = 0x12B868; // type:func\nInitAseg__FP4ASEG                                           = 0x12B870; // type:func\nLoadAsegFromBrx__FP4ASEGP18CBinaryInputStream               = 0x12B8C8; // type:func\nLoadAsegEventsFromBrx__FP4ASEGP18CBinaryInputStreamiPiPP2EA = 0x12BC38; // type:func\nCloneAseg__FP4ASEGP2LO                                      = 0x12C140; // type:func\nPostAsegLoad__FP4ASEG                                       = 0x12C160; // type:func\nPostAsegLoadCallback__FP4ASEG5MSGIDPv                       = 0x12C208; // type:func\nApplyAsegOvr__FP4ASEGP3ALOiP3OVRffiPP5ASEGA                 = 0x12C288; // type:func\nApplyAseg__FP4ASEGP3ALOffiPP5ASEGA                          = 0x12C7B0; // type:func\nPasegaApplyAseg__FP4ASEGP3ALOffi                            = 0x12C7D8; // type:func\nPasegaFindAseg__FP4ASEGP3ALO                                = 0x12C808; // type:func\nEnsureAseg__FP4ASEGP3ALO4SEEKffiPP5ASEGA                    = 0x12C840; // type:func\nPasegaEnsureAseg__FP4ASEGP3ALO4SEEKffi                      = 0x12C8F8; // type:func\nApplyAsegCur__FP4ASEGP3ALOffiPP5ASEGA                       = 0x12C918; // type:func\nFWipingAseg__FP4ASEG                                        = 0x12C9A8; // type:func\nFindAsegClosestPoint__FP4ASEGP3ALOP6VECTORfPfT2T2           = 0x12C9E8; // type:func\nPeaFindAsegLabel__FP4ASEG3OID                               = 0x12CBE8; // type:func\nTFindAsegLabel__FP4ASEG3OID                                 = 0x12CCC0; // type:func\nPchnFindAseg__FP4ASEGP3ALO                                  = 0x12CCE8; // type:func\nPredictAsegEffect__FP4ASEGffP3ALOT3iP6VECTORP7MATRIX3T6T6   = 0x12CD78; // type:func\nGetAsegWaypoints__FP4ASEGP3ALOPiPPP8WAYPOINT                = 0x12D1B0; // type:func\nStripAsegChn__FP4ASEGP3CHN                                  = 0x12D2A8; // type:func\nStripAsegAlo__FP4ASEGP3ALO                                  = 0x12D398; // type:func\nLoadAsegblFromBrx__FP6ASEGBLP18CBinaryInputStream           = 0x12D3E0; // type:func\nPostAsegblLoad__FP6ASEGBL                                   = 0x12D3E8; // type:func\nCloneAsegbl__FP6ASEGBLP2LO                                  = 0x12D3F0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/asega.c\n////////////////////////////////////////////////////////////////\nPasegaNew__FP2SW                                       = 0x12D3F8; // type:func\nSetAsegaHandsOff__FP5ASEGAi                            = 0x12D448; // type:func\nUpdateAsegaIeaCur__FP5ASEGA                            = 0x12D4A8; // type:func\nPactsegFindAsega__FP5ASEGA3OID                         = 0x12D570; // type:func\njunk_0012D5C8                                          = 0x12D5C8; // type:func\nHandleAsegaEvent__FP5ASEGAP2EAPi                       = 0x12D5D0; // type:func\nHandleAsegaEventsFF__FP5ASEGAP4ASEGPi                  = 0x12E4E0; // type:func\nHandleAsegaEvents__FP5ASEGAP4ASEGPi                    = 0x12E5D0; // type:func\nRemoveAsega__FP5ASEGA                                  = 0x12E710; // type:func\nRetractAsega__FP5ASEGA                                 = 0x12E760; // type:func\nFUN_0012e928                                           = 0x12E928; // type:func\nUFromEaErrorFunc__FP2EAf                               = 0x12E968; // type:func\nFWrapAsegaTime__FP5ASEGAPfT1                           = 0x12E9E0; // type:func\nUpdateAsega__FP5ASEGAf                                 = 0x12EBD8; // type:func\nSeekAsega__FP5ASEGA4SEEKff                             = 0x12F0A0; // type:func\nSnapAsega__FP5ASEGAi                                   = 0x12F190; // type:func\nAdaptAsega__FP5ASEGA                                   = 0x12F1D8; // type:func\nFindChnClosestPointLocal__FP3CHNP3ALOP6VECTORfffPfT2T2 = 0x12F210; // type:func\nSetAsegaSpeed__FP5ASEGAf                               = 0x12F6B0; // type:func\nSetAsegaMasterSpeed__FP5ASEGAf                         = 0x12F6D0; // type:func\nSetAsegaPriority__FP5ASEGAi                            = 0x12F718; // type:func\nSendAsegaMessage__FP5ASEGA5MSGIDPv                     = 0x12F760; // type:func\nSubscribeAsegaStruct__FP5ASEGAPFPv5MSGIDPv_vPv         = 0x12F7E0; // type:func\nSubscribeAsegaObject__FP5ASEGAP2LO                     = 0x12F810; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/barrier.c\n////////////////////////////////////////////////////////////////\nInitBarrier__FP7BARRIER                    = 0x12F840; // type:func\nCloneBarrier__FP7BARRIERT0                 = 0x12F888; // type:func\nPostBarrierLoad__FP7BARRIER                = 0x12F8C8; // type:func\nUpdateBarrier__FP7BARRIERf                 = 0x12F9B8; // type:func\nFIgnoreBarrierIntersection__FP7BARRIERP2SO = 0x12FA88; // type:func\nNotifyBarrierImpact__FP7BARRIERP2XPi       = 0x12FB68; // type:func\nAddBarrierObject__FP7BARRIER3OID           = 0x12FCB0; // type:func\nAddBarrierClass__FP7BARRIER3CID            = 0x12FCD0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/bas.c\n////////////////////////////////////////////////////////////////\n__18CBinaryAsyncStreamPv                        = 0x12FCF0; // type:func\n_$_18CBinaryAsyncStream                         = 0x12FD30; // type:func\nFOpenFile__18CBinaryAsyncStreamP13CFileLocation = 0x12FD78; // type:func\njunk_0012FD98                                   = 0x12FD98; // type:func\nFOpenSector__18CBinaryAsyncStreamUiUi           = 0x12FDA0; // type:func\nClose__18CBinaryAsyncStream                     = 0x12FDE8; // type:func\nStartSpooling__18CBinaryAsyncStream             = 0x12FE70; // type:func\nFSpooling__18CBinaryAsyncStream                 = 0x12FF10; // type:func\nFSpoolingComplete__18CBinaryAsyncStream         = 0x12FF20; // type:func\nFinishSpooling__18CBinaryAsyncStream            = 0x12FFE8; // type:func\nSpool__18CBinaryAsyncStream                     = 0x130070; // type:func\nSkip__18CBinaryAsyncStreami                     = 0x1300D8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/basic.c\n////////////////////////////////////////////////////////////////\nFIsBasicDerivedFrom__FP5BASIC3CID = 0x1300e8; // type:func\nEnsureBasicSidebag__FP5BASIC = 0x130110; // type:func\nGetBasicCid__FP5BASICP3CID = 0x130158; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/bez.c\n////////////////////////////////////////////////////////////////\nEvaluateBezierWeightedFloat__FfffffffffPfN29 = 0x130168; // type:func\nEvaluateBezierFloat__FfffffffPfN27 = 0x1303F0; // type:func\nEvaluateBezierPos__FfffP6VECTORN63 = 0x130540; // type:func\nEvaluateBezierMat__FfffP7MATRIX3P6VECTORT3T4T3T4T4 = 0x130748; // type:func\nTesselateBezier__FfffP6VECTORN33iT3 = 0x130B48; // type:func\nSBezierPosLength__FffP6VECTORN32 = 0x130C20; // type:func\nLimitBezierMulti__Fie = 0x130C58; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/binoc.c\n////////////////////////////////////////////////////////////////\nInitBei__FP3BEIP3CLQffi = 0x130F48; // type:func\nGEvaluateBei__FP3BEIi = 0x131000; // type:func\nInitBinoc__FP5BINOC5BLOTK = 0x1310F0; // type:func\nResetBinoc__FP5BINOC = 0x131140; // type:func\nPostBinocLoad__FP5BINOC = 0x131198; // type:func\nDrawBinocCompass = 0x1316E8; // type:func\nDrawBinocZoom = 0x131F60; // type:func\nDrawBinocReticle = 0x132500; // type:func\nDrawBinocOutline = 0x133B58; // type:func\nFUN_00134aa0 = 0x134AA0; // type:func\nFUN_00134b48 = 0x134B48; // type:func\nDrawBinocFilter = 0x135228; // type:func\nFUN_00135550 = 0x135550; // type:func\nopen_close_binoc = 0x1356C0; // type:func\nFUN_001357f0 = 0x1357F0; // type:func\nFUN_00135858 = 0x135858; // type:func\nFUN_001358d0 = 0x1358D0; // type:func\njunk_00135E20 = 0x135E20; // type:func\nFUN_00135E30 = 0x135E30; // type:func\njunk_00135E40 = 0x135E40; // type:func\nFUN_00135E48 = 0x135E48; // type:func\njunk_00135E70 = 0x135E70; // type:func\nSetBinocBfk = 0x135E78; // type:func\nFUN_00135f48 = 0x135F48; // type:func\nFUN_00136040 = 0x136040; // type:func\nFUN_00136238 = 0x136238; // type:func\nFUN_001363d0 = 0x1363D0; // type:func\nSetBinocAchzDraw = 0x136408; // type:func\nFDoneBinocAchz__FP5BINOC = 0x136530; // type:func\nSetBinocLookat__FP5BINOCP3ALO = 0x1365A0; // type:func\nSetBinocZoom__FP5BINOCf = 0x1365A8; // type:func\nFUN_001365f0 = 0x1365F0; // type:func\nFUN_00136648 = 0x136648; // type:func\nDrawBinoc = 0x1366A0; // type:func\nGetBinocReticleFocus__FP5BINOCPfT1 = 0x136EC8; // type:func\nFUN_00136ef8 = 0x136EF8; // type:func\nFUN_00136fa8 = 0x136FA8; // type:func\nbinoc__static_initialization_and_destruction_0 = 0x136FE8; // type:func\nSetPos__8CTextBoxff = 0x137228; // type:func\nSetSize__8CTextBoxff = 0x137238; // type:func\nSetTextColor__8CTextBoxP4RGBA = 0x137248; // type:func\nSetHorizontalJust__8CTextBox2JH = 0x137260; // type:func\nSetVerticalJust__8CTextBox2JV = 0x137268; // type:func\n_GLOBAL_$I$InitBei__FP3BEIP3CLQffi = 0x137270; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/bis.c\n////////////////////////////////////////////////////////////////\n__18CBinaryInputStreamPvii = 0x137290; // type:func\n_$_18CBinaryInputStream = 0x1372E0; // type:func\nFOpenSector__18CBinaryInputStreamUiUi = 0x137328; // type:func\nOpenMemory__18CBinaryInputStreamiPv = 0x137398; // type:func\nFOpenFile__18CBinaryInputStreamP13CFileLocation = 0x1373B0; // type:func\nClose__18CBinaryInputStream = 0x1373D0; // type:func\nDecrementCdReadLimit__18CBinaryInputStreami = 0x137480; // type:func\nPumpCd__18CBinaryInputStream = 0x137490; // type:func\nPumpHost__18CBinaryInputStream = 0x1377C0; // type:func\nPump__18CBinaryInputStream = 0x137820; // type:func\nDecompress__18CBinaryInputStream = 0x1378A0; // type:func\nRead__18CBinaryInputStreamiPv = 0x137A60; // type:func\nAlign__18CBinaryInputStreami = 0x137B60; // type:func\nU8Read__18CBinaryInputStream = 0x137B90; // type:func\nU16Read__18CBinaryInputStream = 0x137BE0; // type:func\nU32Read__18CBinaryInputStream = 0x137C40; // type:func\njunk_00137CB8 = 0x137CB8; // type:func\nS8Read__18CBinaryInputStream = 0x137CC0; // type:func\nS16Read__18CBinaryInputStream = 0x137D10; // type:func\nS32Read__18CBinaryInputStream = 0x137D78; // type:func\njunk_00137DF0 = 0x137DF0; // type:func\nF32Read__18CBinaryInputStream = 0x137DF8; // type:func\nReadVector__18CBinaryInputStreamP6VECTOR = 0x137E70; // type:func\nReadVector4__18CBinaryInputStreamP7VECTOR4 = 0x137E90; // type:func\nReadMatrix__18CBinaryInputStreamP7MATRIX3 = 0x137EB0; // type:func\nReadMatrix4__18CBinaryInputStreamP7MATRIX4 = 0x137F08; // type:func\nReadGeom__18CBinaryInputStreamP4GEOM = 0x137FB0; // type:func\nReadBspc__18CBinaryInputStreamP4GEOMP4BSPC = 0x138278; // type:func\nReadVbsp__18CBinaryInputStreamPiPP4VBSP = 0x138398; // type:func\nReadStringSw__18CBinaryInputStreamPPc = 0x1384A0; // type:func\njunk_00138510 = 0x138510; // type:func\nUnknown1__18CBinaryInputStream = 0x138518; // type:func\nUnknown2__18CBinaryInputStreamPPv = 0x138550; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/bbmark.c\n////////////////////////////////////////////////////////////////\nUpdateSwPox__FP2SWP3OXAT1UcUc         = 0x1385A0; // type:func\nPoxAddSw__FP2SWP3OXAT1                = 0x138738; // type:func\nPoxRemoveSw__FP2SWP3OXAT1             = 0x138788; // type:func\nPoxFromSoSo__FP2SOT0                  = 0x1387C0; // type:func\nPxpFirstFromSoSo__FP2SOT0             = 0x1387F8; // type:func\nAddSwAaobrObject__FP2SWP2SO           = 0x138828; // type:func\nRemoveSwAaobrObject__FP2SWP2SO        = 0x1388A0; // type:func\nInvalidateSwAaox__FP2SW               = 0x1389C8; // type:func\nUpdateSwAaox__FP2SW                   = 0x1389D0; // type:func\nInvalidateSwXpForObject__FP2SWP2SOi   = 0x138BE0; // type:func\nRecalcSwXpAll__FP2SWi                 = 0x138C00; // type:func\nRecalcSwOxfFilterForObject__FP2SWP2SO = 0x138F28; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/blend.c\n////////////////////////////////////////////////////////////////\nVerifyAeaEquivalence__FiP2EAiT1                  = 0x138FF0; // type:func\nEnsureAsegBlendDynamic__FP3ALOiiPviPiT5PP6ASEGBL = 0x139038; // type:func\nFillBlAmrsg__FiiPviiP3OID                        = 0x139600; // type:func\nCalculateBlendAmrsg__FiiPviiP4MRSGPf             = 0x139740; // type:func\nImrsgLookUp__FffiP4MRSGPf                        = 0x139970; // type:func\njunk_001399F0                                    = 0x1399F0; // type:func\nReblendAsegbl__FP6ASEGBLiiPv                     = 0x1399F8; // type:func\nSetAsegblSlerp__FP6ASEGBLP3ALO                   = 0x139B38; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/blip.c\n////////////////////////////////////////////////////////////////\nBuildBlipAqwGifs__FiPP2QW             = 0x139B70; // type:func\nStartupBlips__Fv                      = 0x139C38; // type:func\nPblipNew__FP5BLIPG                    = 0x139C70; // type:func\nRemoveBlip__FP4BLIP                   = 0x139D28; // type:func\nPblipgNew__FP2SW                      = 0x139D68; // type:func\nInitBlipg__FP5BLIPG                   = 0x139DE8; // type:func\nOnBlipgAdd__FP5BLIPG                  = 0x139E80; // type:func\nOnBlipgRemove__FP5BLIPG               = 0x139EC8; // type:func\nSetBlipgShader__FP5BLIPG3OID          = 0x139F80; // type:func\nPropagateBlipgShader__FP5BLIPG        = 0x13A008; // type:func\nSetBlipgEmitb__FP5BLIPGP5EMITB        = 0x13A128; // type:func\nUpdateBlipg__FP5BLIPGf                = 0x13A3A0; // type:func\nSubscribeBlipgObject__FP5BLIPGP2LO    = 0x13A418; // type:func\nCblipeProjectBlipTransformAccel__FP7MATRIX4G8VU_FLOATP5BLIPPP5BLIPVP5BLIPXi6BLIPOKP6VECTORT7 = 0x13A498; // type:func\nProjectBlipgTransformAccel__FP5BLIPGf = 0x13A618; // type:func\nProjectBlipgTransform__FP5BLIPGfi     = 0x13A940; // type:func\nRenderBlipgSelf__FP5BLIPGP2CMP2RO     = 0x13AD08; // type:func\nDrawBlipg__FP3RPL                     = 0x13AD80; // type:func\nPropagateBlipgShaders__Fi             = 0x13B430; // type:func\n\ng_aqwBlipeGifsNormal     = 0x261314; // size:0x4\ng_aqwBlipeGifsClampedAdd = 0x261318; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/bomb.c\n////////////////////////////////////////////////////////////////\nInitBomb__FP4BOMB                             = 0x13B4C0; // type:func\nLoadBombFromBrx__FP4BOMBP18CBinaryInputStream = 0x13B598; // type:func\nCloneBomb__FP4BOMBT0                          = 0x13B5C8; // type:func\nPostBombLoad__FP4BOMB                         = 0x13B610; // type:func\nHandleBombMessage__FP4BOMB5MSGIDPv            = 0x13B708; // type:func\nUpdateBomb__FP4BOMBf                          = 0x13B778; // type:func\nFUN_0013b828                                  = 0x13B828; // type:func\nFUN_0013b9d8                                  = 0x13B9D8; // type:func\nFUN_0013ba70                                  = 0x13BA70; // type:func\nFAbsorbBombWkr__FP4BOMBP3WKR                  = 0x13BBA0; // type:func\nFUN_0013bc80                                  = 0x13BC80; // type:func\nPrimeBomb__FP4BOMBf                           = 0x13BE00; // type:func\nApplyBombThrow__FP4BOMBP2PO                   = 0x13BE18; // type:func\nDetonateBomb__FP4BOMB                         = 0x13BF68; // type:func\nPsfxEnsureBomb__FP4BOMB4ENSK                  = 0x13C950; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/bq.c\n////////////////////////////////////////////////////////////////\nInit__10CByteQueueiPv                 = 0x13C988; // type:func\nReset__10CByteQueue                   = 0x13C9B0; // type:func\nCbFill__10CByteQueueiP11CQueueInput   = 0x13C9D0; // type:func\nCbDrain__10CByteQueueiP12CQueueOutput = 0x13CAD8; // type:func\nCbFill__10CByteQueueiPUc              = 0x13CC00; // type:func\nFreeDrain__10CByteQueuei              = 0x13CC48; // type:func\nCbRead__17CQueueInputMemoryiPv        = 0x13CC80; // type:func\nCbRead__15CQueueInputFileiPv          = 0x13CCE8; // type:func\njunk_0013CCF0                         = 0x13CCF0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/break.c\n////////////////////////////////////////////////////////////////\nInitBrk__FP3BRK                             = 0x13CCF8; // type:func\nLoadBrkFromBrx__FP3BRKP18CBinaryInputStream = 0x13CD80; // type:func\nCloneBrk__FP3BRKT0                          = 0x13CDE8; // type:func\nPostBrkLoad__FP3BRK                         = 0x13CE40; // type:func\nPostBrkLoadCallbackHookup__FP3BRK5MSGIDPv   = 0x13CE80; // type:func\nUpdateBrk__FP3BRKf                          = 0x13D068; // type:func\nFAbsorbBrkWkr__FP3BRKP3WKR                  = 0x13D0B0; // type:func\nBreakBrk__FP3BRK                            = 0x13D278; // type:func\nSetBrkBroken__FP3BRKi                       = 0x13D820; // type:func\nSetBrkExclude__FP3BRK3OID                   = 0x13D868; // type:func\nSetBrkRemain__FP3BRK3OID                    = 0x13D8B0; // type:func\nSetBrkFixed__FP3BRK3OID                     = 0x13D900; // type:func\nSetBrkRemainFixed__FP3BRK3OID               = 0x13D950; // type:func\nSetBrkOnPlayer__FP3BRKi                     = 0x13D9A0; // type:func\nGetBrkOnPlayer__FP3BRKPi                    = 0x13D9E0; // type:func\nSetBrkOnBomb__FP3BRKi                       = 0x13D9F0; // type:func\nGetBrkOnBomb__FP3BRKPi                      = 0x13DA30; // type:func\nAddBrkTouchObject__FP3BRK3OID               = 0x13DA48; // type:func\nAddBrkTouchClass__FP3BRK3CID                = 0x13DA80; // type:func\nFUN_0013DAB8                                = 0x13DAB8; // type:func\nPsfxEnsureBrk__FP3BRK4ENSK                  = 0x13DAF0; // type:func\nFCheckBrkTouchObject__FP3BRKP2SO            = 0x13DB28; // type:func\nUpdateBrkp__FP4BRKPf                        = 0x13DC38; // type:func\nHandleBrkpMessage__FP4BRKP5MSGIDPv          = 0x13DCA8; // type:func\nFIgnoreBrkpIntersection__FP4BRKPP2SO        = 0x13DD08; // type:func\nSetBrkpBrkps__FP4BRKP5BRKPS                 = 0x13DD78; // type:func\nInitBreak__FP5BREAK                         = 0x13DDB8; // type:func\nInitFragile__FP7FRAGILE                     = 0x13DDF0; // type:func\nAdjustFragileNewXp__FP7FRAGILEP2XPi         = 0x13DE38; // type:func\nAdjustZapbreakNewXp__FP8ZAPBREAKP2XPi       = 0x13DEE8; // type:func\nUpdateZapbreak__FP8ZAPBREAKf                = 0x13df68; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/bsp.c\n////////////////////////////////////////////////////////////////\nClsgClipEdgeToBsp__FP3BSPP6VECTORT1PiiP3LSG = 0x13DFD8; // type:func\nPruneBsp__FP3BSPP6VECTORfPP3BSP             = 0x13E430; // type:func\nPbspPointInBspQuick__FP6VECTORP3BSP         = 0x13E658; // type:func\nCloneBspc__FP4GEOMP4BSPCT0T1                = 0x13E6C8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/button.c\n////////////////////////////////////////////////////////////////\nPostAshLoad__FP2SWP3ASHP3ALO                      = 0x13E7C0; // type:func\nFFoundAshAseg__FP3ASHP4ASEG                       = 0x13E868; // type:func\nFAddAshAseg__FP3ASHP4ASEG                         = 0x13E8D8; // type:func\nFAddAshOid__FP3ASH3OID                            = 0x13E8F8; // type:func\nInitBtn__FP3BTN                                   = 0x13E918; // type:func\nLoadBtn__FP3BTNP3ALO                              = 0x13E950; // type:func\nPostBtnLoad__FP3BTN                               = 0x13EA38; // type:func\nRestoreBtnFromCheckpointCallback__FP3BTN5MSGIDPv  = 0x13EAE0; // type:func\nSetBtnRsmg__FP3BTNi3OIDN22                        = 0x13EB30; // type:func\nSetBtnButtons__FP3BTN7BUTTONS                     = 0x13EB68; // type:func\nFAddRsmg__FP4RSMGiPii3OIDN24                      = 0x13EC00; // type:func\nTriggerRsmg__FP2SWiP4RSMGP2LOi                    = 0x13ECB0; // type:func\nRunBtnAsegs__FP3BTN4IASHii                        = 0x13ED90; // type:func\nTriggerBtn__FP3BTNii                              = 0x13EF50; // type:func\nUntriggerBtn__FP3BTNi                             = 0x13F070; // type:func\nInitButton__FP6BUTTON                             = 0x13F0E0; // type:func\nLoadButtonFromBrx__FP6BUTTONP18CBinaryInputStream = 0x13F110; // type:func\nInsertButtonPos__FP6BUTTONP3PNTP6VECTOR           = 0x13F140; // type:func\nInsertButtonMat__FP6BUTTONP3XFMP7MATRIX3          = 0x13F1D8; // type:func\nPostButtonLoad__FP6BUTTON                         = 0x13F290; // type:func\nCloneButton__FP6BUTTONT0                          = 0x13F6C0; // type:func\nSetButtonButtons__FP6BUTTON7BUTTONS               = 0x13F6F8; // type:func\nFCheckButtonObject__FP6BUTTONP2SO                 = 0x13F718; // type:func\nIposFindButtonClosest__FP6BUTTONPf                = 0x13F8A0; // type:func\nImatFindButtonClosest__FP6BUTTONPf                = 0x13F940; // type:func\nPresetButtonAccel__FP6BUTTONf                     = 0x13FA10; // type:func\nUpdateButtonInternalXps__FP6BUTTON                = 0x13FAE8; // type:func\nUpdateButton__FP6BUTTONf                          = 0x13FD20; // type:func\nFAbsorbButtonWkr__FP6BUTTONP3WKR                  = 0x140028; // type:func\nInitVolbtn__FP6VOLBTN                             = 0x1400A8; // type:func\nLoadVolbtnFromBrx__FP6VOLBTNP18CBinaryInputStream = 0x140100; // type:func\nPostVolbtnLoad__FP6VOLBTN                         = 0x140140; // type:func\nCloneVolbtn__FP6VOLBTNT0                          = 0x140200; // type:func\nSetVolbtnButtons__FP6VOLBTN7BUTTONS               = 0x140238; // type:func\nUpdateVolbtn__FP6VOLBTNf                          = 0x140258; // type:func\nFGetVolbtnPushObjectsWithinList__FP6VOLBTNPv      = 0x140550; // type:func\nAddBtnAseg__FP3BTNP3ALO3OID                       = 0x1405D0; // type:func\nAddButtonAseg__FP6BUTTON3OID                      = 0x1405F0; // type:func\nAddVolbtnAseg__FP6VOLBTN3OID                      = 0x140618; // type:func\nAddBtnOffAseg__FP3BTNP3ALO3OID                    = 0x140640; // type:func\nAddButtonOffAseg__FP6BUTTON3OID                   = 0x140660; // type:func\nAddVolbtnOffAseg__FP6VOLBTN3OID                   = 0x140688; // type:func\nAddButtonPushObject__FP6BUTTON3OID                = 0x1406B0; // type:func\nAddButtonNoPushObject__FP6BUTTON3OID              = 0x1406D0; // type:func\nAddButtonPushClass__FP6BUTTON3CID                 = 0x1406F0; // type:func\nAddButtonNoPushClass__FP6BUTTON3CID               = 0x140710; // type:func\nAddVolbtnPushObject__FP6VOLBTN3OID                = 0x140730; // type:func\nSetButtonRsmg__FP6BUTTONi3OIDN22                  = 0x140750; // type:func\nSetVolbtnRsmg__FP6VOLBTNi3OIDN22                  = 0x140770; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/cat.c\n////////////////////////////////////////////////////////////////\nStartupCatalog__Fv = 0x140790; // type:func\nFUN_001407A0__FPUi = 0x1407A0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/cd.c\n////////////////////////////////////////////////////////////////\nCpchzTokenizePath__FPc = 0x1407A8; // type:func\nFValidCdMmode__Fv      = 0x140968; // type:func\nSetCdMmode__Fv         = 0x1409A8; // type:func\nStartupCd__Fv          = 0x1409D8; // type:func\nUpdateCd__Fv           = 0x1409E0; // type:func\nCdPath__FPcT0i         = 0x140B60; // type:func\nReadCd__FUiUiPv        = 0x140C28; // type:func\nReadCdDirect__FUiUiPv  = 0x140CC8; // type:func\nFCdCompleted__Fi       = 0x140D68; // type:func\njunk_00140D88          = 0x140D88; // type:func\n\ng_cds = 0x2613EC; // size:0x4\ng_scecd = 0x2613F0; // size:0x4\ns_retCdRead = 0x2613F4; // size:0x4\ns_retCdError = 0x2613F8; // size:0x4\n\ns_cdmode = 0x247AA0; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/chkpnt.c\n////////////////////////////////////////////////////////////////\nResetChkmgrCheckpoints__FP6CHKMGR = 0x140D90; // type:func\nSaveChkmgrCheckpoint__FP6CHKMGR3OIDT1 = 0x140E10; // type:func\nReturnChkmgrToCheckpoint__FP6CHKMGR = 0x140ED0; // type:func\nRestoreChkmgrFromCheckpoint__FP6CHKMGR = 0x140F48; // type:func\nIchkAllocChkmgr__FP6CHKMGR = 0x140FF8; // type:func\nFGetChkmgrIchk__FP6CHKMGRi = 0x141008; // type:func\nSetChkmgrIchk__FP6CHKMGRi = 0x141040; // type:func\nClearChkmgrIchk__FP6CHKMGRi = 0x1410A0; // type:func\nLoadVolFromBrx__FP3VOLP18CBinaryInputStream = 0x141108; // type:func\nFCheckVolPoint__FP3VOLP6VECTOR = 0x141170; // type:func\nInitChkpnt__FP6CHKPNT = 0x1411A8; // type:func\nLoadChkpntFromBrx__FP6CHKPNTP18CBinaryInputStream = 0x141210; // type:func\nBindChkpnt__FP6CHKPNT = 0x141338; // type:func\nPostChkpntLoad__FP6CHKPNT = 0x141438; // type:func\nCloneChkpnt__FP6CHKPNTT0 = 0x1415D0; // type:func\nUpdateChkpnt__FP6CHKPNTf = 0x141690; // type:func\nFUN_001417f0 = 0x1417F0; // type:func\nTriggerChkpnt__FP6CHKPNT = 0x141870; // type:func\nFUN_001419A0 = 0x1419A0; // type:func\nFUN_001419C0 = 0x1419C0; // type:func\nFUN_001419E0 = 0x1419E0; // type:func\n\ng_chkmgr = 0x261420; // size:0x430\n\n\n////////////////////////////////////////////////////////////////\n// P2/clip.c\n////////////////////////////////////////////////////////////////\nPsoHitTestLineObjects__FiP6VECTORT1iPP2SOP3LSG         = 0x1419E8; // type:func\nFUN_00141b48                                           = 0x141B48; // type:func\nClsgClipEdgeToObject__FP2SOP6VECTORT1iP3LSG            = 0x141C28; // type:func\nClsgClipEdgeToObjectPruned__FP2SOP3BSPP6VECTORT2iP3LSG = 0x141C90; // type:func\nClsgClipCylinderToObject__FP2SOP6VECTORT1fiP3LSG       = 0x141D00; // type:func\nClsgClipLineToSphere__FP6VECTORfT0T0iP3LSG             = 0x141D88; // type:func\nClsgClipEdgeToSphere__FP6VECTORfT0T0iP3LSG             = 0x141F48; // type:func\nClsgClipCylinderToSphere__FP6VECTORfT0T0fiP3LSG        = 0x142170; // type:func\nClsgClipEdgeToCylinder__FP6VECTORT0fT0T0iP3LSG         = 0x142278; // type:func\njunk_00142990                                          = 0x142990; // type:func\nSgnCompareMaa__FP3MAAT0                                = 0x142998; // type:func\nClsgMergeAlsg__FiP3LSG                                 = 0x1429F8; // type:func\nClsgClipCylinderToBsp__FP4BSPCP4GEOMP6VECTORT2fiP3LSG  = 0x142B78; // type:func\njunk_00142EC8                                          = 0x142EC8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/clock.c\n////////////////////////////////////////////////////////////////\nSetClockRate__Ff = 0x142ED0; // type:func\nMarkClockTick__FP5CLOCK = 0x142F10; // type:func\nMarkClockTickRealOnly__FP5CLOCK = 0x143030; // type:func\nResetClock__FP5CLOCKf = 0x1430B8; // type:func\nSetClockEnabled__FP5CLOCKi = 0x1430C0; // type:func\nStartupClock__Fv = 0x1430C8; // type:func\nTickNow__Fv = 0x1430F8; // type:func\n\nD_0024CD4C = 0x24cd4c; // size:0x4\ng_rtClock = 0x261850; // size:0x4\ng_rtClockPowerUp = 0x261854; // size:0x4\ng_clock = 0x261858; // size:0x20\ns_tickLastRaw = 0x261878; // size:0x4\ncWrapAround = 0x27c000; // size:0x8\n\n\n////////////////////////////////////////////////////////////////\n// P2/cm.c\n////////////////////////////////////////////////////////////////\nStartupCm__Fv = 0x143140; // type:func\nCalcCmAdjust__FP2CMP2SOP6CPDEFIP6VECTOR = 0x143148; // type:func\nSpringCm__FfffP2CMP6VECTORP6VECTORP6VECTOR = 0x143180; // type:func\nAdjustCmCpdefi__FP2CMP2SOfP6CPDEFI = 0x143208; // type:func\nResetCmAdjust__FP2CMP2SOP6CPDEFI = 0x1433E0; // type:func\nGetCmCpdefi__FP2CMP2SOfP6CPDEFI = 0x143418; // type:func\nBuildCmFgfn__FP2CMfP4FGFN = 0x1434C8; // type:func\nRecalcCmFrustrum__FP2CM = 0x143560; // type:func\nInitCm__FP2CM = 0x143648; // type:func\nSetSwCameraFov__Ff = 0x1437C0; // type:func\nFUN_001437e8 = 0x1437E8; // type:func\nSetSwCameraFarClip__Ff = 0x143810; // type:func\nFUN_00143838 = 0x143838; // type:func\nFUN_00143860 = 0x143860; // type:func\nFUN_00143888 = 0x143888; // type:func\nSetSwCameraRgbaFog__FP2SWP4RGBA = 0x1438B0; // type:func\nFUN_001438d8 = 0x1438D8; // type:func\nSetCmPos__FP2CMP6VECTOR = 0x143900; // type:func\nSetCmMat__FP2CMP7MATRIX3 = 0x143920; // type:func\nSetCmFov__FP2CMf = 0x143940; // type:func\nSetCmNearClip__FP2CMf = 0x143968; // type:func\nSetCmFarClip__FP2CMf = 0x143988; // type:func\nSetCmSProgress__FP2CMf = 0x1439A8; // type:func\nFUN_001439c8__FP2CMf = 0x1439C8; // type:func\nFUN_001439e8__FP2CMf = 0x1439E8; // type:func\nSetCmRgbaFog__FP2CMP4RGBA = 0x143A08; // type:func\nSetCmMrdRatio__FP2CMf = 0x143A38; // type:func\nResetCm = 0x143A60; // type:func\nClearCmFadeObjects__FP2CM = 0x143AF0; // type:func\nAddCmFadeObject = 0x143AF8; // type:func\nRemoveCmFadeObject = 0x143B20; // type:func\nFUN_00143BA8 = 0x143BA8; // type:func\nUpdateCmFade = 0x143BE0; // type:func\nUpdateCmLast = 0x143E40; // type:func\nSetupCmRotateToCam = 0x144008; // type:func\nConvertCmScreenToWorld = 0x144128; // type:func\nConvertCmWorldToScreen = 0x1441C0; // type:func\nSetupCm__FP2CM = 0x144270; // type:func\nCombineEyeLookAtProj = 0x1442C8; // type:func\nBuildFrustrum = 0x1443C8; // type:func\nUpdateCmMat4 = 0x144540; // type:func\nDrawCm__FP2CM = 0x144848; // type:func\nSetCmPosMat__FP2CMP6VECTORP7MATRIX3 = 0x1448C8; // type:func\nSetCmLookAt = 0x144938; // type:func\nConvertWorldToCylindVelocity = 0x144978; // type:func\nConvertCylindToWorldVelocity = 0x144AA0; // type:func\nResetCmLookAtSmooth = 0x144B70; // type:func\nSetCmLookAtSmooth = 0x144BE8; // type:func\nAdjustCmJoy__FP2CMP3JOY5JOYIDPf = 0x144FF8; // type:func\njunk_00145080 = 0x145080; // type:func\nSetCmPolicy__FP2CM3CPPP5CPLCYP2SOPv = 0x145088; // type:func\nRevokeCmPolicy__FP2CMi3CPPP5CPLCYP2SOPv = 0x1451F0; // type:func\nFInsideCmMrd = 0x1453B0; // type:func\nDecomposeCylind = 0x145438; // type:func\nDecomposeSphere = 0x1454E0; // type:func\nSetCmCut__FP2CMPf = 0x1455C0; // type:func\nSetResetFlag__FP2CM = 0x1455E0; // type:func\nClearCmCut__FP2CM = 0x1455F0; // type:func\nAdaptCm = 0x145610; // type:func\nSetCm = 0x145718; // type:func\nPsoEnemyStepguard = 0x145810; // type:func\nFUN_00145950 = 0x145950; // type:func\nFUN_00145b68 = 0x145B68; // type:func\nFUN_00145DD8 = 0x145DD8; // type:func\nFUN_00145de8 = 0x145DE8; // type:func\nFUN_00145e68 = 0x145E68; // type:func\nPushLookkCm__FP2CM5LOOKK = 0x145FB8; // type:func\nLookkPopCm__FP2CM = 0x145FD8; // type:func\nLookkCurCm__FP2CM = 0x145FF8; // type:func\nSetCmSniperFocus__FP2CMP3PNTff = 0x146018; // type:func\nFUN_00146028__FP2CM = 0x146028; // type:func\nFUN_00146038 = 0x146038; // type:func\ncm__static_initialization_and_destruction_0__Fii = 0x1460B8; // type:func\n_GLOBAL_$I$StartupCm__Fv = 0x1460E0; // type:func\n\ng_posEyeDefault = 0x261880; // size:0x10\ng_posCenterDefault = 0x261890; // size:0x10\ng_sNearFog = 0x2618a0; // size:0x4\ng_sFarFog = 0x2618a4; // size:0x4\ng_uFogMax = 0x2618a8; // size:0x4\ng_rgbaFog = 0x2618b0; // size:0x4\n// ...\nDT_CmJoltMax = 0x2618c8; // size:0x4\nSW_CmJolt = 0x2618cc; // size:0x4\ns_clqUToUJolt = 0x2618d0; // size:0x10\ns_dposJolt = 0x2618e0; // size:0x10\ns_rotJolt = 0x2618f0; // size:0x10\ns_vecRange = 0x261900; // size:0x10\ns_vecOffset = 0x261910; // size:0x10\nR_SetCmSpring = 0x261920; // size:0x4\nR_SetCmDamping = 0x261924; // size:0x4\n\nD_00261928 = 0x261928; // size:0x24\nD_0026194C = 0x26194c; // size:0x4\nD_00261950 = 0x261950; // size:0x4\n\ns_smpSquishEye = 0x261958; // size:0xc\n\nD_00261970 = 0x261970; // size:0x4\nD_00261974 = 0x261974; // size:0x4\nD_00261978 = 0x261978; // size:0x4\nD_0026197C = 0x26197c; // size:0x4\nD_00261980 = 0x261980; // size:0x4\nD_00261984 = 0x261984; // size:0x4\nD_00261988 = 0x261988; // size:0x4\nD_0026198C = 0x26198c; // size:0x4\n\ng_pcm = 0x261990; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/cnvo.c\n////////////////////////////////////////////////////////////////\nInitCnvo__FP4CNVO                             = 0x146100; // type:func\nLoadCnvoFromBrx__FP4CNVOP18CBinaryInputStream = 0x146130; // type:func\nPostCnvoLoad__FP4CNVO                         = 0x146178; // type:func\nAdjustCnvoXpVelocity__FP4CNVOP2XPi            = 0x1461A8; // type:func\nSetCnvoBeltSpeed__FP4CNVOf                    = 0x146240; // type:func\nMatchCnvoScrollerToBeltSpeed__FP4CNVO         = 0x146298; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/coin.c\n////////////////////////////////////////////////////////////////\nInitDprize__FP6DPRIZE = 0x146340; // type:func\nLoadDprizeFromBrx__FP6DPRIZEP18CBinaryInputStream = 0x1463C0; // type:func\nCloneDprize__FP6DPRIZET0 = 0x146418; // type:func\nPostDprizeLoad__FP6DPRIZE = 0x146470; // type:func\nProjectDprizeTransform__FP6DPRIZEfi = 0x146518; // type:func\nFFilterDprizeObjects__FP6DPRIZEP2SO = 0x146D10; // type:func\nCheckDprizeBounce__FP6DPRIZE = 0x146DB0; // type:func\nCheckDprizeCollect__FP6DPRIZE = 0x1471B0; // type:func\nFAbsorbDprizeWkr__FP6DPRIZEP3WKR = 0x1473E0; // type:func\nUpdateDprize__FP6DPRIZEf = 0x147428; // type:func\nRenderDprizeAll__FP6DPRIZEP2CMP2RO = 0x1478F0; // type:func\nSetDprizeDprizes__FP6DPRIZE7DPRIZES = 0x147AB0; // type:func\nInitCoin__FP4COIN = 0x147E40; // type:func\nFUN_00147ed0 = 0x147ED0; // type:func\nFUN_00147ef8 = 0x147EF8; // type:func\nUpdateCoin__FP4COINf = 0x147FB0; // type:func\nCreateSwCharm__FP2SW = 0x148038; // type:func\nAddLife__FPv = 0x148178; // type:func\nOnCoinSmack__FP4COIN = 0x1481A0; // type:func\nSetCoinDprizes__FP4COIN7DPRIZES = 0x148298; // type:func\nInitCharm__FP5CHARM = 0x148400; // type:func\nSetCharmDprizes__FP5CHARM7DPRIZES = 0x148470; // type:func\nInitKey__FP3KEY = 0x148510; // type:func\nSetKeyDprizes__FP3KEY7DPRIZES = 0x148598; // type:func\nFUN_00148698 = 0x148698; // type:func\nFUN_00148718 = 0x148718; // type:func\nFUN_00148748 = 0x148748; // type:func\nFUN_00148770 = 0x148770; // type:func\nFUN_00148828 = 0x148828; // type:func\nFUN_00148888 = 0x148888; // type:func\nFUN_00148910__FPfT0 = 0x148910; // type:func\nFUN_00148938 = 0x148938; // type:func\nCpdprizeAttractSwDprizes__FP2SW3CIDP6VECTORiPP6DPRIZE = 0x148AC0; // type:func\nRemoveSwExtraneousCharms__FP2SW = 0x148CE0; // type:func\nFUN_00148d90 = 0x148D90; // type:func\nFUN_00148e18 = 0x148E18; // type:func\nFUN_00148e40 = 0x148E40; // type:func\nFUN_00148ef8 = 0x148EF8; // type:func\nincrement_and_show_life_count = 0x148F80; // type:func\nCollectLifetkn__FP7LIFETKN = 0x148FF0; // type:func\nFUN_00149168 = 0x149168; // type:func\nbreak_bottle = 0x149190; // type:func\n\ns_asnipDprize = 0x2619A0; // size:0x3c\n\n\n////////////////////////////////////////////////////////////////\n// P2/cplcy.c\n////////////////////////////////////////////////////////////////\nInitCplcy = 0x149398; // type:func\nFActiveCplcy = 0x1493A0; // type:func\nSetCpmanCpmt = 0x1493B8; // type:func\nFUN_001493c0 = 0x1493C0; // type:func\nPosCplookAnchor = 0x1493C8; // type:func\nFUN_00149458 = 0x149458; // type:func\nplays_binoc_sfx = 0x149508; // type:func\nPushCplookLookk__FP6CPLOOK5LOOKK = 0x1495E8; // type:func\nLookkPopCplook__FP6CPLOOK = 0x149610; // type:func\nLookkCurCplook__FP6CPLOOK = 0x149638; // type:func\nInitCplook = 0x149660; // type:func\nFUN_001496c0 = 0x1496C0; // type:func\nUpdateCplook = 0x149760; // type:func\nFUN_0014a7b8 = 0x14A7B8; // type:func\nInitCpalign = 0x14A888; // type:func\nFUN_0014a8d0 = 0x14A8D0; // type:func\nUpdateCpalign = 0x14A8F8; // type:func\nFUN_0014aa90 = 0x14AA90; // type:func\nFUN_0014aa98 = 0x14AA98; // type:func\nUpdateCpaseg = 0x14AAA0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/credit.c\n////////////////////////////////////////////////////////////////\nInitCredit__FP6CREDIT5BLOTK = 0x14ABD0; // type:func\nPostCreditLoad__FP6CREDIT = 0x14AC48; // type:func\nSetCreditClock__FP6CREDITPf = 0x14AD00; // type:func\nUpdateCredit__FP6CREDIT = 0x14AD70; // type:func\nDrawCredit__FP6CREDIT = 0x14ADE0; // type:func\nPlaceCredit__FP6CREDITffi = 0x14AEA0; // type:func\nVacateCredit__FP6CREDIT = 0x14AF10; // type:func\nSetCreditLine__FP6CREDITiPcf = 0x14AF38; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/crout.c\n////////////////////////////////////////////////////////////////\nCroutDecomp__FiPfT1 = 0x14B0C0; // type:func\nCroutSolve__FiPfN21 = 0x14B3E0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/crusher.c\n// TODO: The rest of the functions aren't in the prototype.\n// Figure out what they do and mangle the names.\n////////////////////////////////////////////////////////////////\nOnCrfodAdd__FP5CRFOD             = 0x14B550; // type:func\nOnCrfodRemove__FP5CRFOD          = 0x14B588; // type:func\nCloneCrfod__FP5CRFODT0           = 0x14B5C0; // type:func\nInitCrfodb__FP6CRFODB            = 0x14B608; // type:func\nPostCrfodbLoad__FP6CRFODB        = 0x14B640; // type:func\nCalcHeadingVector__FfP6VECTOR    = 0x14B678; // type:func\nUpdateCrfodbGoal__FP6CRFODBi     = 0x14B6A8; // type:func\nFDetectCrfodb__FP6CRFODB         = 0x14BB08; // type:func\nFAbsorbCrfodbWkr__FP6CRFODBP3WKR = 0x14BCE8; // type:func\nFUN_0014bd38                     = 0x14BD38; // type:func\nSgsNextCrfodkAI__FP6CRFODK       = 0x14BDC8; // type:func\nFDetectCrfodk__FP6CRFODK         = 0x14BEA8; // type:func\nFAbsorbCrfodkWkr__FP6CRFODKP3WKR = 0x14BEF8; // type:func\nFUN_0014bf88                     = 0x14BF88; // type:func\nInitCrbrain__FP7CRBRAIN          = 0x14C018; // type:func\npost_load_crbrain                = 0x14C138; // type:func\nFUN_0014c2f0                     = 0x14C2F0; // type:func\nFUN_0014c5e8                     = 0x14C5E8; // type:func\nFUN_0014c668                     = 0x14C668; // type:func\nupdate_crbrain                   = 0x14C6E0; // type:func\nFUN_0014c788                     = 0x14C788; // type:func\nFUN_0014c820                     = 0x14C820; // type:func\nFUN_0014c838                     = 0x14C838; // type:func\nFUN_0014c858                     = 0x14C858; // type:func\nFUN_0014cba8                     = 0x14CBA8; // type:func\nFUN_0014cd70                     = 0x14CD70; // type:func\nFUN_0014cdc8                     = 0x14CDC8; // type:func\nhandle_crbrain_message           = 0x14CF30; // type:func\n\nDAT_0027c008 = 0x27C008; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/crv.c\n////////////////////////////////////////////////////////////////\nSMeasureApos__FiP6VECTORPf                                       = 0x14D0A8; // type:func\nGWrapApos__FfiPfi                                                = 0x14D138; // type:func\nIposFindAposG__FfiPfiT2T2                                        = 0x14D1A0; // type:func\nEvaluateAposG__FfiP6VECTORPfiT2T2                                = 0x14D280; // type:func\nFindAposClosestPointAll__FP6VECTORP6CONSTRiT0N20PiPf             = 0x14D3A8; // type:func\nFindAposClosestPointSegment__FP6VECTORP6CONSTRiT0iiT0T0PiPf      = 0x14D680; // type:func\nConvertApos__FiP6VECTORP7MATRIX4T2                               = 0x14D938; // type:func\nPcrvNew__F4CRVK                                                  = 0x14D9A8; // type:func\nSFromCrvU__FP3CRVf                                               = 0x14DA18; // type:func\nUFromCrvS__FP3CRVf                                               = 0x14DA28; // type:func\nIcvFindCrvU__FP3CRVfPfT2                                         = 0x14DA38; // type:func\nIcvFindCrvS__FP3CRVfPfT2                                         = 0x14DA68; // type:func\nGMeasureCrvU__FP5CRVMCf                                          = 0x14DA98; // type:func\nUMaxCrv__FP3CRV                                                  = 0x14DB40; // type:func\nSMaxCrv__FP3CRV                                                  = 0x14DB58; // type:func\njunk_0014DB70                                                    = 0x14DB70; // type:func\nSMeasureCrvSegmentU__FP5CRVMSf                                   = 0x14DB78; // type:func\nFindCrvClosestPointOnLineSegmentFromU__FP3CRVP6VECTORT1fT1T1PfT6 = 0x14DBD0; // type:func\njunk_0014DCF8                                                    = 0x14DCF8; // type:func\nDuGetCrvSearchIncrement__FP3CRV                                  = 0x14DD00; // type:func\nLoadCrvlFromBrx__FP4CRVLP18CBinaryInputStream                    = 0x14DD28; // type:func\nEvaluateCrvlFromU__FP4CRVLfP6VECTORT2                            = 0x14DE08; // type:func\nEvaluateCrvlFromS__FP4CRVLfP6VECTORT2                            = 0x14DE40; // type:func\nRenderCrvlSegment__FP4CRVLiP7MATRIX4P2CMG4RGBAi                  = 0x14DE78; // type:func\nConvertCrvl__FP4CRVLP7MATRIX4T1                                  = 0x14DF68; // type:func\nSFromCrvlU__FP4CRVLf                                             = 0x14DF98; // type:func\nUFromCrvlS__FP4CRVLf                                             = 0x14E000; // type:func\nMeasureCrvl__FP4CRVL                                             = 0x14E068; // type:func\nFindCrvlClosestPointAll__FP4CRVLP6VECTORP6CONSTRT1T1PfT5         = 0x14E090; // type:func\nFindCrvlClosestPointFromU__FP4CRVLP6VECTORfP6CONSTRT1T1PfT6      = 0x14E170; // type:func\nFindCrvlClosestPointFromS__FP4CRVLP6VECTORfP6CONSTRT1T1PfT6      = 0x14E2A0; // type:func\nLoadCrvcFromBrx__FP4CRVCP18CBinaryInputStream                    = 0x14E3D0; // type:func\nInvalidateCrvcCache__FP4CRVC                                     = 0x14E500; // type:func\nFillCrvcCache__FP4CRVCi                                          = 0x14E510; // type:func\nEvaluateCrvcFromU__FP4CRVCfP6VECTORT2                            = 0x14E5B8; // type:func\nEvaluateCrvcFromS__FP4CRVCfP6VECTORT2                            = 0x14E6A8; // type:func\nRenderCrvcSegment__FP4CRVCiP7MATRIX4P2CMG4RGBAi                  = 0x14E710; // type:func\nConvertCrvc__FP4CRVCP7MATRIX4T1                                  = 0x14E828; // type:func\nSFromCrvcU__FP4CRVCf                                             = 0x14E910; // type:func\nUFromCrvcS__FP4CRVCf                                             = 0x14E990; // type:func\nMeasureCrvc__FP4CRVC                                             = 0x14EA48; // type:func\nFindCrvcClosestPointAll__FP4CRVCP6VECTORP6CONSTRT1T1PfT5         = 0x14EB10; // type:func\nFindCrvcClosestPointFromU__FP4CRVCP6VECTORfP6CONSTRT1T1PfT6      = 0x14EC70; // type:func\nFindCrvcClosestPointFromS__FP4CRVCP6VECTORfP6CONSTRT1T1PfT6      = 0x14ED98; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/dart.c\n////////////////////////////////////////////////////////////////\nInitDart__FP4DART                             = 0x14EE40; // type:func\nOnDartAdd__FP4DART                            = 0x14EE70; // type:func\nRemoveDart__FP4DART                           = 0x14EF00; // type:func\nCloneDart__FP4DARTT0                          = 0x14EF40; // type:func\nLoadDartFromBrx__FP4DARTP18CBinaryInputStream = 0x14EF88; // type:func\nHandleDartMessage__FP4DART5MSGIDPv            = 0x14EFB8; // type:func\nPostDartLoad__FP4DART                         = 0x14F020; // type:func\nUpdateDart__FP4DARTf                          = 0x14F058; // type:func\nSetDartDarts__FP4DART5DARTS                   = 0x14F110; // type:func\nApplyDartThrow__FP4DARTP2PO                   = 0x14F168; // type:func\nUpdateDartAirborne__FP4DARTf                  = 0x14F270; // type:func\n\ns_asnipDart = 0x261CC8;\n\n\n////////////////////////////////////////////////////////////////\n// P2/dartgun.c\n////////////////////////////////////////////////////////////////\nInitDartgun__FP7DARTGUN                     = 0x14F740; // type:func\nHandleDartgunMessage__FP7DARTGUN5MSGIDPv    = 0x14F770; // type:func\nBindDartgun__FP7DARTGUN                     = 0x14F850; // type:func\nFUN_0014f900                                = 0x14F900; // type:func\nPostDartgunLoad__FP7DARTGUN                 = 0x14F920; // type:func\nUpdateDartgun__FP7DARTGUNf                  = 0x14FA88; // type:func\nFIgnoreDartgunIntersection__FP7DARTGUNP2SO  = 0x14FBE0; // type:func\nBreakDartgun__FP7DARTGUN                    = 0x14FC38; // type:func\nSetDartgunGoalState__FP7DARTGUN3OID         = 0x14FCE8; // type:func\nTrackDartgun__FP7DARTGUNP3OID               = 0x14FDA8; // type:func\nFPrepareDartgunToFire__FP7DARTGUN           = 0x14FEC0; // type:func\nFireDartgun__FP7DARTGUN                     = 0x150008; // type:func\nAgeDartgunStuckDart__FP7DARTGUN             = 0x150298; // type:func\nPratGetDartgunRatTarget__FP7DARTGUN         = 0x150338; // type:func\nAddDartgunRatTarget__FP7DARTGUN3OID         = 0x1503E0; // type:func\nStartDartgunTargetAreaChange__FP7DARTGUN    = 0x150408; // type:func\nAddDartgunTargetAreaTarget__FP7DARTGUNP3ALO = 0x150418; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/dialog.c\n////////////////////////////////////////////////////////////////\nInitDialog__FP6DIALOG                             = 0x1504E0; // type:func\nLoadDialogFromBrx__FP6DIALOGP18CBinaryInputStream = 0x150528; // type:func\nLoadDialogEventsFromBrx__FP6DIALOGP18CBinaryInputStreamPiPP2DE = 0x150570; // type:func\nPostDialogLoad__FP6DIALOG                         = 0x1506F0; // type:func\nSetDialogInstruct__FP6DIALOG                      = 0x150750; // type:func\nSetDialogConfront__FP6DIALOG                      = 0x150760; // type:func\nGetDialogPlayed__FP6DIALOGPi                      = 0x150770; // type:func\nSetDialogPlayed__FP6DIALOGi                       = 0x150780; // type:func\nSetDialogDialogs__FP6DIALOG7DIALOGS               = 0x150790; // type:func\nUpdateDialog__FP6DIALOGf                          = 0x150AE8; // type:func\nHandleDialogEvent__FP6DIALOGP2DE                  = 0x150DC0; // type:func\nHandleDialogMessage__FP6DIALOG5MSGIDPv            = 0x1512A8; // type:func\nFPauseDialog__FP6DIALOG                           = 0x151300; // type:func\nFUN_001516c0                                      = 0x1516C0; // type:func\nHandleDialogEvents__FP6DIALOG                     = 0x1517C0; // type:func\nFUN_00151860__FP6DIALOGP4BLOT                     = 0x151860; // type:func\nTriggerDialog__FP6DIALOG                          = 0x1518B8; // type:func\nUntriggerDialog__FP6DIALOG                        = 0x1519A8; // type:func\n\n// TODO: Is this in the right place?\ng_pdialogPlaying = 0x27051C;\n\n\n////////////////////////////////////////////////////////////////\n// P2/difficulty.c\n////////////////////////////////////////////////////////////////\nPdifficultyEnsureSw = 0x1519E0; // type:func\nFUN_00151A58 = 0x151A58; // type:func\nOnDifficultyGameLoad__FP10DIFFICULTY = 0x151A68; // type:func\nOnDifficultyWorldPreLoad = 0x151A88; // type:func\nOnDifficultyWorldPostLoad = 0x151D28; // type:func\nOnDifficultyInitialTeleport__FP10DIFFICULTY = 0x151E18; // type:func\nOnDifficultyPlayerDeath = 0x151E20; // type:func\nOnDifficultyTriggerCheckpoint__FP10DIFFICULTYP6CHKPNT = 0x151ED8; // type:func\nOnDifficultyCollectKey__FP10DIFFICULTY = 0x151FC8; // type:func\nOnDifficultyBreak = 0x152010; // type:func\nChangeSuck__FfP10DIFFICULTY = 0x152410; // type:func\n\ng_difficultyMedium = 0x261d70; // size:0x5c\ng_difficultyHard = 0x261e30; // size:0x5c\ng_difficultyEasy = 0x261e90; // size:0x5c\ng_difficulty = 0x261ef0; // size:0x20\n\n\n////////////////////////////////////////////////////////////////\n// P2/dl.c\n////////////////////////////////////////////////////////////////\nInitDl__FP2DLi = 0x152438; // type:func\nClearDl__FP2DL = 0x152440; // type:func\nClearDle__FP3DLE = 0x152450; // type:func\nPdleFromDlEntry__FP2DLPv = 0x152460; // type:func\nAppendDlEntry__FP2DLPv = 0x152470; // type:func\nPrependDlEntry__FP2DLPv = 0x1524D8; // type:func\nInsertDlEntryBefore__FP2DLPvT1 = 0x152540; // type:func\njunk_001525F8 = 0x1525F8; // type:func\nRemoveDlEntry__FP2DLPv = 0x152600; // type:func\nFFindDlEntry__FP2DLPv = 0x1526D0; // type:func\nFIsDlEmpty__FP2DL = 0x152720; // type:func\nMergeDl__FP2DLT0 = 0x152730; // type:func\nCPvDl__FP2DL = 0x1527D8; // type:func\n\ns_pdliFirst = 0x27B314; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/dmas.c\n////////////////////////////////////////////////////////////////\nStartupDma__Fv = 0x152810; // type:func\n__4DMAS = 0x152888; // type:func\nClear__4DMAS = 0x1528C8; // type:func\nReset__4DMAS = 0x1528E0; // type:func\nAllocGlobal__4DMASi = 0x1528F0; // type:func\nAllocSw__4DMASii = 0x152938; // type:func\nAllocStack__4DMASi = 0x152980; // type:func\nAllocStatic__4DMASiP2QW = 0x1529C8; // type:func\nDetach__4DMASPiPP2QW = 0x1529E0; // type:func\nDetachCopySw__4DMASPiPP2QWT2i = 0x152A50; // type:func\nSend__4DMASP10sceDmaChan = 0x152AE0; // type:func\njunk_00152B30 = 0x152B30; // type:func\nAddDmaCnt__4DMAS = 0x152B38; // type:func\nAddDmaRefs__4DMASiP2QW = 0x152B80; // type:func\nAddDmaCall__4DMASP2QW = 0x152C18; // type:func\nAddDmaRet__4DMAS = 0x152CA0; // type:func\nAddDmaBulk__4DMASiP2QW = 0x152CE0; // type:func\nAddDmaEnd__4DMAS = 0x152D30; // type:func\nEndDmaCnt__4DMAS = 0x152D70; // type:func\nEndPrim__4DMASi = 0x152E18; // type:func\njunk_00152E20 = 0x152E20; // type:func\n\n_vt$4DMAS = 0x24A0E0; // size:0x10\n\ng_pdcVif0 = 0x261f14; // size:0x4\ng_pdcVif1 = 0x261f18; // size:0x4\ng_pdcGif = 0x261f1c; // size:0x4\ng_pdcFromSpr = 0x261f20; // size:0x4\ng_pdcToSpr = 0x261f24; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/dysh.c\n////////////////////////////////////////////////////////////////\nInitDysh__FP4DYSH               = 0x152E28; // type:func\nSetDyshShadow__FP4DYSHP6SHADOW  = 0x152E48; // type:func\nRenderDyshSelf__FP4DYSHP2CMP2RO = 0x153328; // type:func\nDrawDysh__FP3RPL                = 0x1533A8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/dzg.c\n////////////////////////////////////////////////////////////////\nInitDzg__FP3DZGi                     = 0x153528; // type:func\nClearDzgSolution__FP3DZG             = 0x153608; // type:func\nAppendDzgDz__FP3DZGP2DZ              = 0x1536C8; // type:func\nFillDzgDz__FP3DZGiP2DZiPP2XPPiPPP2SO = 0x153780; // type:func\nEnforceDzgDz__FP3DZGP2DZ             = 0x153A50; // type:func\nSolveDzg__FP3DZGiiPP2XPPiPPP2SO      = 0x153EC0; // type:func\nSolveDzgFric__FP3DZGiiPP2XPPiPPP2SOf = 0x154088; // type:func\nApplyDzg__FP3DZGiPiPPP2SOff          = 0x154370; // type:func\nSolveInequalities__FiPfN21           = 0x154880; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/emitter.c\n////////////////////////////////////////////////////////////////\nInitEmitb__FP5EMITB                                              = 0x1549C8; // type:func\nInitEmitter__FP7EMITTER                                          = 0x154C10; // type:func\nLoadEmitmeshFromBrx__FP8EMITMESHP18CBinaryInputStream            = 0x154C80; // type:func\nLoadEmitblipColorsFromBrx__FP8EMITBLIPiP2LOP18CBinaryInputStream = 0x154EE0; // type:func\nLoadEmitterFromBrx__FP7EMITTERP18CBinaryInputStream              = 0x154F98; // type:func\nCloneEmitter__FP7EMITTERT0                                       = 0x155080; // type:func\nBindEmitterCallback__FP7EMITTER5MSGIDPv                          = 0x1550B8; // type:func\nBindEmitter__FP7EMITTER                                          = 0x1550E8; // type:func\nPostEmitterLoad__FP7EMITTER                                      = 0x155270; // type:func\nHandleEmitterMessage__FP7EMITTER5MSGIDPv                         = 0x155678; // type:func\nPemitbCopyOnWrite__FP5EMITB                                      = 0x1556E8; // type:func\nPemitbEnsureEmitter__FP7EMITTER4ENSK                             = 0x155778; // type:func\nPemitterEnsureEmitter__FP7EMITTER4ENSK                           = 0x1557B8; // type:func\nAddEmitterSkeleton__FP7EMITTER3OIDT1ffff                         = 0x1557D0; // type:func\nModifyEmitterParticles__FP7EMITTER                               = 0x155868; // type:func\nUpdateEmitter__FP7EMITTERf                                       = 0x155AB0; // type:func\nFUN_00155f28                                                     = 0x155F28; // type:func\nPauseEmitter__FP7EMITTERf                                        = 0x155F78; // type:func\nPauseEmitterIndefinite__FP7EMITTER                               = 0x155F90; // type:func\nUnpauseEmitter__FP7EMITTER                                       = 0x155FA0; // type:func\nFPausedEmitter__FP7EMITTER                                       = 0x155FB0; // type:func\nSetEmitterEnabled__FP7EMITTERi                                   = 0x156000; // type:func\nGetEmitterEnabled__FP7EMITTERPi                                  = 0x156030; // type:func\nGetEmitterPaused__FP7EMITTERPi                                   = 0x156060; // type:func\nOnEmitterValuesChanged__FP7EMITTER                               = 0x156088; // type:func\nSetEmitterParticleCount__FP7EMITTERi                             = 0x156108; // type:func\nSetEmitterAutoPause__FP7EMITTERi                                 = 0x156178; // type:func\nSetEmitbRipt__FP5EMITB4RIPT                                      = 0x156188; // type:func\nSetEmitterRipt__FP7EMITTER4RIPT                                  = 0x156218; // type:func\nSetExploRipt__FP5EXPLO4RIPT                                      = 0x156250; // type:func\nWakeSoWater__FP2SOP5WATERfP6VECTORT3ff                           = 0x156288; // type:func\nStandardSmokeCloud__FP6VECTORf                                   = 0x1566C8; // type:func\nChooseEmitoPos__FP5EMITOiiP6VECTORT3                             = 0x156718; // type:func\nConvertEmitoPosVec__FP5EMITOP6VECTORT1                           = 0x156F08; // type:func\nCalculateEmitvx__FiP2LMiP6EMITVX                                 = 0x156FC8; // type:func\nChooseEmitVelocity__FP6EMITVXffP2LMP6VECTORiT4                   = 0x157098; // type:func\nChooseEmitvVelocityAge__FP5EMITVP6EMITVXP5EMITOiP6VECTORN24PfT7  = 0x157248; // type:func\nEmitRips__FP5EMITBP5EMITGiP6VECTORT3PfT5                         = 0x157320; // type:func\nEmitBlips__FP5EMITBP5EMITGiP6VECTORT3PfT5T3T3                    = 0x1575D8; // type:func\nOriginateParticles__FiP5EMITBP7EMITGEN                           = 0x1579B0; // type:func\nOriginateSplineSinkParticles__FiP5EMITBR7EMITGENT2               = 0x157B88; // type:func\nEmitParticles__FiP5EMITBP5EMITG                                  = 0x157E00; // type:func\nEmitRipsSphere__FP6VECTORT0iP7EMITRIPP5EMITVPP4RIPGP2LO          = 0x157EF8; // type:func\nStockSplashBig__FP6VECTORfP2SO                                   = 0x157FF8; // type:func\nStockSplashSmall__FP6VECTORfP2SO                                 = 0x158108; // type:func\nAddEmitoSkeleton__FP5EMITO3OIDT1ffffP2LO                         = 0x158198; // type:func\nBindEmitb__FP5EMITBP2LO                                          = 0x158288; // type:func\nSetEmitdvEmitb__FP6EMITDVP5EMITB                                 = 0x1583E8; // type:func\nCalculateEmitdvMatrix__FP6EMITDVfP7MATRIX4                       = 0x158480; // type:func\nPostExplLoad__FP4EXPL                                            = 0x1585F8; // type:func\nCalculateExplTransform__FP4EXPLP6VECTORP7MATRIX3                 = 0x158630; // type:func\nExplodeExpl__FP4EXPL                                             = 0x158730; // type:func\nExplodeExplParams__FP4EXPLUiP3ALOP6VECTORT3ff                    = 0x158778; // type:func\nExplodeExplExplso__FP4EXPLP6EXPLSO                               = 0x1587C0; // type:func\nLoadExplgFromBrx__FP5EXPLGP18CBinaryInputStream                  = 0x1587C8; // type:func\nCloneExplg__FP5EXPLGT0                                           = 0x158980; // type:func\nBindExplg__FP5EXPLG                                              = 0x158A10; // type:func\nExplodeExplgExplso__FP5EXPLGP6EXPLSO                             = 0x158A80; // type:func\nInitExplo__FP5EXPLO                                              = 0x158B00; // type:func\nLoadExploFromBrx__FP5EXPLOP18CBinaryInputStream                  = 0x158B30; // type:func\nCloneExplo__FP5EXPLOT0                                           = 0x158C28; // type:func\nBindExplo__FP5EXPLO                                              = 0x158C60; // type:func\nExplodeExploExplso__FP5EXPLOP6EXPLSO                             = 0x158D38; // type:func\nAddExploSkeleton__FP5EXPLO3OIDT1ffff                             = 0x158D40; // type:func\nPemitbEnsureExplo__FP5EXPLO4ENSK                                 = 0x158DD8; // type:func\nInitExpls__FP5EXPLS                                              = 0x158E10; // type:func\nBindExpls__FP5EXPLS                                              = 0x158E48; // type:func\nHandleExplsMessage__FP5EXPLS5MSGIDPv                             = 0x158F10; // type:func\nExplodeExplsExplso__FP5EXPLSP6EXPLSO                             = 0x158F80; // type:func\nPsfxEnsureExpls__FP5EXPLS4ENSK                                   = 0x159068; // type:func\nFireExplsExplso__FP5EXPLSP6EXPLSO                                = 0x1590A0; // type:func\nInferExpl__FPP4EXPLP3ALO                                         = 0x159478; // type:func\nFireSwTimedExplodeStyles__FP2SW                                  = 0x159588; // type:func\n\nDAT_0024a124 = 0x24A124; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/eyes.c\n////////////////////////////////////////////////////////////////\nInitEyes__FP4EYESP4SAAF       = 0x159680; // type:func\nPostEyesLoad__FP4EYES         = 0x1596E0; // type:func\nSetEyesEyess__FP4EYES5EYESS   = 0x159770; // type:func\nUpdateEyes__FP4EYESf          = 0x159890; // type:func\nSetEyesClosed__FP4EYESf       = 0x159A00; // type:func\nPsaiFromEyesShd__FP4EYESP3SHD = 0x159A80; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/fader.c\n////////////////////////////////////////////////////////////////\nUpdateFader__FP5FADERf = 0x159AD0; // type:func\nPfaderNew__FP3ALO      = 0x159BB0; // type:func\nRemoveFader__FP5FADER  = 0x159C28; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/UNKNOWN1\n////////////////////////////////////////////////////////////////\nFUN_00159ca0 = 0x159CA0; // type:func\nFUN_00159d00 = 0x159D00; // type:func\nFUN_00159ed0 = 0x159ED0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/find.c\n////////////////////////////////////////////////////////////////\nPdlFromSwOid__FP2SW3OID = 0x159F20; // type:func\nMatchSwObject__FP2LOiiiT0iPiPP2LOT6 = 0x159F48; // type:func\nCploFindSwObjects__FP2SWi3OIDP2LOiPP2LO = 0x15A198; // type:func\nPloFindSwObject__FP2SWi3OIDP2LO = 0x15A418; // type:func\nPloFindSwNearest__FP2SW3OIDP2LO = 0x15A448; // type:func\nPloFindSwChild__FP2SW3OIDP3ALO = 0x15A480; // type:func\nFIsCidDerivedFrom__F3CIDT0 = 0x15A4B8; // type:func\nCploFindSwObjectsByClass__FP2SWi3CIDP2LOiPP2LO = 0x15A4F0; // type:func\nPloFindSwObjectByClass__FP2SWi3CIDP2LO = 0x15A838; // type:func\nPaloFindLoCommonParent__FP2LOT0 = 0x15A868; // type:func\n\ng_mpcidpvt = 0x247448; // size:0x328\n\n\n////////////////////////////////////////////////////////////////\n// P2/flash.c\n////////////////////////////////////////////////////////////////\njunk_0015A8B0 = 0x15A8B0; // type:func\nInitFlash__FP5FLASH = 0x15A8B8; // type:func\nLoadFlashFromBrx__FP5FLASHP18CBinaryInputStream = 0x15A918; // type:func\nUpdateFlash__FP5FLASHf = 0x15A960; // type:func\nRenderFlashSelf__FP5FLASHP2CMP2RO = 0x15A9A8; // type:func\nFPosFlashWithin__FP5FLASHP6VECTOR = 0x15AA50; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/fly.c\n////////////////////////////////////////////////////////////////\nInitFly__FP3FLY                             = 0x15AAE0; // type:func\nLoadFlyFromBrx__FP3FLYP18CBinaryInputStream = 0x15AC08; // type:func\nCloneFly__FP3FLYT0                          = 0x15AD80; // type:func\nFreezeFly__FP3FLYi                          = 0x15AE38; // type:func\nPostFlyLoad__FP3FLY                         = 0x15AEB0; // type:func\nPresetFlyAccel__FP3FLYf                     = 0x15AF50; // type:func\nUpdateFly__FP3FLYf                          = 0x15B128; // type:func\nRenderFlySelf__FP3FLYP2CMP2RO               = 0x15B4D0; // type:func\nFAbsorbFlyWkr__FP3FLYP3WKR                  = 0x15B720; // type:func\nSetFlyFlys__FP3FLY4FLYS                     = 0x15B7B8; // type:func\nEmitFlyDroppings__FP3FLY                    = 0x15BC78; // type:func\nFFindFlyClosestLandingPos__FP3FLYP6VECTOR   = 0x15BD48; // type:func\nFlysAttemptedFlyLanding__FP3FLY             = 0x15BEF0; // type:func\nFShouldFlyFlee__FP3FLY                      = 0x15BFC0; // type:func\nFFilterFly__FPvP2SO                         = 0x15C058; // type:func\nFCheckFlyOpenSpaceBelow__FP3FLY             = 0x15C0A0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/font.c\n////////////////////////////////////////////////////////////////\nStartupFont__Fv                                = 0x15C178; // type:func\nFUN_0015c188                                   = 0x15C188; // type:func\nFUN_0015c1c0                                   = 0x15C1C0; // type:func\nFUN_0015c200                                   = 0x15C200; // type:func\nCopyTo__5CFontP5CFont                          = 0x15C260; // type:func\nSetupDraw__5CFontP8CTextBoxP4GIFS              = 0x15C2E8; // type:func\nCleanupDraw__5CFontP8CTextBoxP4GIFS            = 0x15C3C0; // type:func\nDxFromPchz__5CFontPc                           = 0x15C418; // type:func\nDyWrapPchz__5CFontPcf                          = 0x15C4A8; // type:func\nClineWrapPchz__5CFontPcf                       = 0x15C4E8; // type:func\njunk_0015C630                                  = 0x15C630; // type:func\nDrawPchz__5CFontPcP8CTextBoxT2P4GIFS           = 0x15C638; // type:func\nPushScaling__5CFontff                          = 0x15C8b8; // type:func\nPopScaling__5CFont                             = 0x15C900; // type:func\nPfontClone__8CFontBrxff                        = 0x15C930; // type:func\nCopyTo__8CFontBrxP8CFontBrx                    = 0x15C9B0; // type:func\nFValid__8CFontBrxc                             = 0x15CA38; // type:func\nDxFromCh__8CFontBrxc                           = 0x15CA60; // type:func\nFEnsureLoaded__8CFontBrxP4GIFS                 = 0x15CAB8; // type:func\nSetupDraw__8CFontBrxP8CTextBoxP4GIFS           = 0x15CB88; // type:func\nSwitchTex0__8CFontBrxP4GIFS                    = 0x15CC80; // type:func\nDxDrawCh__8CFontBrxcffUiP4GIFS                 = 0x15CD18; // type:func\nFUN_0015cf70                                   = 0x15CF70; // type:func\nDrawPart__8CFontBrxffffffffUiP4GIFS            = 0x15D338; // type:func\nEdgeRect__8CFontBrxP9CTextEdgeP8CTextBoxP4GIFS = 0x15D4E0; // type:func\nLoadFromBrx__8CFontBrxP18CBinaryInputStream    = 0x15D8A8; // type:func\nPostLoad__8CFontBrxP3GSB                       = 0x15D998; // type:func\nPglyffFromCh__8CFontBrxc                       = 0x15DAB8; // type:func\n__9CRichTextPcP5CFont                          = 0x15DB28; // type:func\nReset__9CRichText                              = 0x15DB80; // type:func\nSetBaseColor__9CRichTextP4RGBA                 = 0x15DBB8; // type:func\nChNext__9CRichText                             = 0x15DBE0; // type:func\nCch__9CRichText                                = 0x15DF58; // type:func\nTrim__9CRichTexti                              = 0x15DFA0; // type:func\nDx__9CRichText                                 = 0x15DFF8; // type:func\nClineWrap__9CRichTextf                         = 0x15E068; // type:func\nFUN_0015e1b0                                   = 0x15E1B0; // type:func\nDxMaxLine__9CRichText                          = 0x15E1F0; // type:func\nGetExtents__9CRichTextPfT1f                    = 0x15E290; // type:func\nDraw__9CRichTextP8CTextBoxT1P4GIFS             = 0x15E318; // type:func\nPostFontsLoad__Fv                              = 0x15E5F0; // type:func\njunk_0015E678                                  = 0x15E678; // type:func\n\ng_pfont = 0x26227C; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/frm.c\n////////////////////////////////////////////////////////////////\nVU1_Interrupt__Fi = 0x15E6A8; // type:func\nStartupFrame__Fv = 0x15E810; // type:func\nOpenFrame__Fv = 0x15E9F0; // type:func\nEnsureVu1Code__FP4VIFSPvT1 = 0x15EAE0; // type:func\nFinalizeFrameVifs__FP4VIFSPiPP2QW = 0x15EB20; // type:func\nFinalizeFrameGifs__FP4GIFSPiPP2QW = 0x15EBF0; // type:func\nCloseFrame__Fv = 0x15EC68; // type:func\nPrepareGsForFrameRender__FP3FRM = 0x15ED50; // type:func\ncheck_anticrack_antigrab__Fv = 0x15EDB8; // type:func\nFrameRenderLoop__FPv = 0x15EE80; // type:func\nRenderFrame__FP3FRMi = 0x15EF88; // type:func\nClearPendingFrame__FP3FRM = 0x15EFE8; // type:func\nFlushFrames__Fi = 0x15F210; // type:func\nBlendPrevFrame__Fv = 0x15F320; // type:func\n\ng_cframe    = 0x2622cc; // size:0x4\ng_pvVu1Code = 0x26230c; // size:0x4\n\n// TODO: Should these be elsewhere?\ng_psliCur = 0x2622D4; // size:0x4\ng_aqwGifsBackgroundUpload = 0x274538; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/freeze.c\n////////////////////////////////////////////////////////////////\nRemergeSwObject__FP2SWP3ALO       = 0x15F678; // type:func\nMergeSwFreezeGroups__FP2SWP3ALOT1 = 0x15F6C0; // type:func\nSplinterSwFreezeGroup__FP2SWP3ALO = 0x15F710; // type:func\nMergeSwGroup__FP2SWP3MRG          = 0x15F7D8; // type:func\nAddSwMergeGroup__FP2SWP3MRG       = 0x15F8B0; // type:func\nRemoveFromArray__FPiPPvPv         = 0x15F930; // type:func\nRemoveSwMergeGroup__FP2SWP3MRG    = 0x15F9A0; // type:func\nRemergeSwObjects__FP2SW           = 0x15FA58; // type:func\nFreezeAloHierarchy__FP3ALOi       = 0x15FB28; // type:func\nGetAloFrozen__FP3ALOPi            = 0x15FBA0; // type:func\nFreezeAlo__FP3ALOi                = 0x15FBB8; // type:func\nFreezeSo__FP2SOi                  = 0x15FCD8; // type:func\nRefreezeSwObjects__FP2SW          = 0x15FD78; // type:func\nUpdateSwBusyList__FP2SW           = 0x15FF58; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/frzg.c\n////////////////////////////////////////////////////////////////\nPostFrzgLoad__FP4FRZG      = 0x15FF88; // type:func\nAddFrzgObject__FP4FRZG3OID = 0x160050; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/game.c\n// TODO mangle function names\n////////////////////////////////////////////////////////////////\nStartupGame__Fv = 0x160070; // type:func\n\njunk_00160090 = 0x160090; // type:func\nsearch_level_by_load_data = 0x1600A0; // type:func\nsearch_level_by_id = 0x160110; // type:func\nPchzFriendlyFromWid = 0x160148; // type:func\njunk_00160178 = 0x160178; // type:func\ncall_search_level_by_id = 0x160180; // type:func\nFFindLevel = 0x1601A0; // type:func\njunk_001601D0 = 0x1601D0; // type:func\nget_level_completion_by_id = 0x1601D8; // type:func\ntally_world_completion = 0x160208; // type:func\nget_game_completion__Fv = 0x1602A0; // type:func\nUnlockIntroCutsceneFromWid__Fi = 0x160340; // type:func\nDefeatBossFromWid = 0x1603E8; // type:func\nUnlockEndgameCutscenesFromFgs = 0x1604B8; // type:func\nPlayEndingFromCompletionFlags = 0x160578; // type:func\n\nInitGameState__FP2GS = 0x1605E8; // type:func\n\nFUN_00160650 = 0x160650; // type:func\n\nSetupGame__FPci = 0x160690; // type:func\nUpdateGameState__Ff = 0x1607D0; // type:func\n\nLsFromWid = 0x160810; // type:func\nGrflsFromWid__F3WID = 0x160850; // type:func\n\nUnloadGame__Fv = 0x160880; // type:func\nRetryGame__Fv = 0x1608E0; // type:func\nStartGame__Fv = 0x160918; // type:func\n\nFUN_00160948 = 0x160948; // type:func\nCalculatePercentCompletion__FP2GS = 0x160B28; // type:func\n\nSetCcharm__Fi = 0x160C48; // type:func\nFCharmAvailable__Fv = 0x160C58; // type:func\nFUN_00160C90 = 0x160C90; // type:func\nPfLookupDialog__FP2LS3OID = 0x160CA0; // type:func\n\nclr_8_bytes_1 = 0x160CC8; // type:func\nFUN_00160ce8__Fi = 0x160CE8; // type:func\nOnGameAlarmTriggered__FP4GAME = 0x160CF0; // type:func\nOnGameAlarmDisabled__FP4GAME = 0x160D00; // type:func\nGetGrfvault_unknown__Fv = 0x160D10; // type:func\n\nGetBlueprintInfo__FPiT0 = 0x160D30; // type:func\nCcharmMost__Fv = 0x160D98; // type:func\n\nreload_post_death = 0x160DA0; // type:func\n\n// data\nD_00247AB0 = 0x247ab0; // size:0x2c\ng_pgsCur = 0x2623c0; // size:0x4\ng_pwsCur = 0x2623c4; // size:0x4\ng_plsCur = 0x2623c8; // size:0x4\ng_worldlevelPrev = 0x2623cc; // size:0x4\nchz_none = 0x2623d0; // size:0x7\n\n// static\ng_gsCur = 0xea0; // size:0x1a00\n\n\n////////////////////////////////////////////////////////////////\n// P2/geom.c\n////////////////////////////////////////////////////////////////\nInitGeom__FP4GEOM             = 0x160E80; // type:func\nCloneGeom__FP4GEOMP7MATRIX4T0 = 0x160EA0; // type:func\nFUN_00161028                  = 0x161028; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/gifs.c\n////////////////////////////////////////////////////////////////\n__4GIFS                      = 0x1611B8; // type:func\nAddPrimEnd__4GIFS            = 0x161200; // type:func\nEndPrim__4GIFSi              = 0x161278; // type:func\nCheckReg__4GIFSii            = 0x1612E8; // type:func\nAddPrimBulk__4GIFSiiiUlPP2QW = 0x1612F8; // type:func\nAddPrimPack__4GIFSiiUl       = 0x1613C0; // type:func\nPackRGBA__4GIFSUi            = 0x161458; // type:func\nPackUV__4GIFSii              = 0x1614C8; // type:func\nPackSTQ__4GIFSfff            = 0x161520; // type:func\nPackXYZ__4GIFSiii            = 0x161588; // type:func\nPackXYZF__4GIFSiiii          = 0x1615F0; // type:func\nPackXYZFNoKick__4GIFSiiii    = 0x161670; // type:func\nPackAD__4GIFSll              = 0x161708; // type:func\njunk_00161760                = 0x161760; // type:func\nAddPrimList__4GIFSiUl        = 0x161768; // type:func\nListRGBAQ__4GIFSUif          = 0x1617E8; // type:func\njunk_00161858                = 0x161858; // type:func\nListUV__4GIFSii              = 0x161860; // type:func\nListXYZF__4GIFSiiii          = 0x1618C0; // type:func\njunk_00161950                = 0x161950; // type:func\nAddImage__4GIFSi             = 0x161958; // type:func\n\n_vt$DMAS = 0x24A6F8;\n\n\n////////////////////////////////////////////////////////////////\n// P2/glbs.c\n////////////////////////////////////////////////////////////////\n__4GLBS                              = 0x1619C0; // type:func\n_$_4GLBS                             = 0x161A88; // type:func\nSetTransform__4GLBSP6VECTORP7MATRIX3 = 0x161AB0; // type:func\nFindLights__4GLBSP6VECTORf           = 0x161B10; // type:func\nResetStrip__4GLBS                    = 0x161B80; // type:func\nBeginStrip__4GLBSP3SHD               = 0x161BB0; // type:func\nDrawPrelit__4GLBS                    = 0x161C00; // type:func\nDrawThreeWay__4GLBS                  = 0x161F70; // type:func\nEndStrip__4GLBS                      = 0x162508; // type:func\nSetNormal__4GLBSP6VECTOR             = 0x162680; // type:func\njunk_001626A0                        = 0x1626A0; // type:func\nSetRgba__4GLBSG4RGBA                 = 0x1626A8; // type:func\nSetUv__4GLBSP3UVF                    = 0x1626C0; // type:func\nAddVtx__4GLBSi                       = 0x1626D8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/glob.c\n////////////////////////////////////////////////////////////////\nBuildGlobsetSaaArray__FP7GLOBSET                         = 0x162810; // type:func\nLoadGlobsetFromBrx__FP7GLOBSETP18CBinaryInputStreamP3ALO = 0x162890; // type:func\nEnsureBuffer__FiP4VIFS                                   = 0x163938; // type:func\nEnsureBufferCel__FiP4VIFS                                = 0x163990; // type:func\nBuildSubcel__FP7GLOBSETiP6SUBCELiP7VECTORFiP4TWEFP8SUBPOSEFT4PfP4VIFS = 0x1639E8; // type:func\nBuildSubglobSinglePass__FP7GLOBSETP4GLOBiP7SUBGLOBP3SHDP7VECTORFT5P4RGBAP3UVFiP4VTXFP8SUBPOSEFT5T5PfP4VIFSP4SGVR = 0x163ED8; // type:func\nBuildSubglobThreeWay__FP7GLOBSETP4GLOBiP7SUBGLOBP3SHDP7VECTORFT5P4RGBAP3UVFiP4VTXFP8SUBPOSEFT5T5PfP4VIFSP4SGVR   = 0x164868; // type:func\nBuildSubglobLighting__FP4GLOBP7SUBGLOBP8SUBGLOBI = 0x165588; // type:func\nPostGlobsetLoad__FP7GLOBSETP3ALO                 = 0x165728; // type:func\nBindGlobset__FP7GLOBSETP3ALO                     = 0x165828; // type:func\nCloneGlobset__FP7GLOBSETP3ALOT0                  = 0x165920; // type:func\nCloneGlob__FP7GLOBSETP4GLOBP5GLOBI               = 0x165AE8; // type:func\nUpdateGlobset__FP7GLOBSETP3ALOf                  = 0x165FE0; // type:func\nUpdateAloConstraints__FP3ALO                     = 0x1660A0; // type:func\nUpdateAloInfluences__FP3ALOP2RO                  = 0x1660E8; // type:func\nPredrawGlob__FP7GLOBSETP4GLOBP5GLOBIP3ALO        = 0x1662A8; // type:func\nRotateVu1Buffer__Fv                              = 0x166658; // type:func\nDrawGlob__FP3RPL                                 = 0x166690; // type:func\nglob__static_initialization_and_destruction_0    = 0x167D20; // type:func\n_GLOBAL_$I$g_dro                                 = 0x167D48; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/gomer.c\n////////////////////////////////////////////////////////////////\nInitGomer__FP5GOMER               = 0x167D68; // type:func\nPostGomerLoad__FP5GOMER           = 0x167E08; // type:func\nRenderGomerSelf__FP5GOMERP2CMP2RO = 0x167EF0; // type:func\nFDetectGomer__FP5GOMER            = 0x167F10; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/gs.c\n// Graphics synthesizer\n////////////////////////////////////////////////////////////////\nBlendDisplayOnBufferMismatch__Fv = 0x168130; // type:func\nVBlankS_Interrupt__Fi = 0x1682C0; // type:func\nSyncVBlank__Fv = 0x1683B8; // type:func\nSwapGsBuffers__Fv = 0x1683E8; // type:func\nRestoreGsBuffers__Fv = 0x1684E8; // type:func\nGS_Interrupt__Fi = 0x1685B8; // type:func\nResetGs__Fv = 0x168698; // type:func\nSendDmaSyncGsFinish__FP10sceDmaChanP2QW = 0x1686E8; // type:func\nBuildClearGifs__FP2QWG4RGBAi = 0x168770; // type:func\nStartupGs__Fv = 0x1688B8; // type:func\nBlastAqwGifsBothFrames__FP2QW = 0x168A48; // type:func\nClearFrameBuffers__Fv = 0x168AF8; // type:func\nFadeFramesToBlack__Ff = 0x168B68; // type:func\nResetGsMemory__Fv = 0x168D00; // type:func\nNLog2__FUi = 0x168D30; // type:func\nInitGsb__FP3GSBii = 0x168D68; // type:func\nResetGsb__FP3GSB = 0x168D78; // type:func\nIgsAllocGsb__FP3GSBi = 0x168D88; // type:func\nBuildImageGifs__FiiiiiiP4GIFS = 0x168D98; // type:func\nBuildClutTex2__FP4CLUTi = 0x168E78; // type:func\nBuildClutGifs__FP4CLUTiP4GIFS = 0x168F48; // type:func\nBuildBmpTex0__FP3BMPi = 0x168FB0; // type:func\nBuildBmpGifs__FP3BMPiP4GIFS = 0x169088; // type:func\nFBuildUploadBitmapGifs__FiP3GSBP4GIFS = 0x1690C0; // type:func\nUploadBitmaps__FiP3GSB = 0x1692B0; // type:func\nPqwGifsBitmapUpload__Fi = 0x1693A8; // type:func\nPropagateSur__FP3SUR = 0x1694A0; // type:func\nReferenceShaderAqwRegs__FP3SHDP4SHDPP2QWiiP3SAI = 0x1694F8; // type:func\nReferenceUVAnimation__FP2QWiP3SAI = 0x169608; // type:func\nRebaseSurs__FiiPvT2 = 0x1696B8; // type:func\nPropagateSurs__Fv = 0x169718; // type:func\nPqwVifsBitmapUpload__Fi = 0x169780; // type:func\nDrawOnBitmap__FP3BMPP4GIFS = 0x169B18; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/hide.c\n////////////////////////////////////////////////////////////////\nStartupHide__Fv                                = 0x169C58; // type:func\nResetHideList__Fv                              = 0x169CA0; // type:func\nInitHshape__FP6HSHAPE                          = 0x169CD8; // type:func\nOnHshapeAdd__FP6HSHAPE                         = 0x169D20; // type:func\nOnHshapeRemove__FP6HSHAPE                      = 0x169D58; // type:func\nBindHshape__FP6HSHAPE                          = 0x169D90; // type:func\nCloneHshape__FP6HSHAPET0                       = 0x169DD8; // type:func\nGetHshapeHidePos__FP6HSHAPEfP6VECTORPf         = 0x169E20; // type:func\nGetHshapeClosestHidePos__FP6HSHAPEPfP6VECTORT1 = 0x169FC0; // type:func\nInitHpnt__FP4HPNT                              = 0x16A100; // type:func\nOnHpntAdd__FP4HPNT                             = 0x16A140; // type:func\nOnHpntRemove__FP4HPNT                          = 0x16A178; // type:func\nBindHpnt__FP4HPNT                              = 0x16A1B0; // type:func\nCloneHpnt__FP4HPNTT0                           = 0x16A1F8; // type:func\nGetHpntClosestHidePos__FP4HPNTP6VECTORPf       = 0x16A240; // type:func\nFUN_0016a320                                   = 0x16A320; // type:func\nInitHbsk__FP4HBSK                              = 0x16A3A8; // type:func\nLoadHbskFromBrx__FP4HBSKP18CBinaryInputStream  = 0x16A420; // type:func\nOnHbskAdd__FP4HBSK                             = 0x16A490; // type:func\nOnHbskRemove__FP4HBSK                          = 0x16A4C8; // type:func\nCloneHbsk__FP4HBSKT0                           = 0x16A500; // type:func\nFIgnoreHbskIntersection__FP4HBSKP2SO           = 0x16A548; // type:func\nPresetHbskAccel__FP4HBSKf                      = 0x16A580; // type:func\nSetHbskHbsks__FP4HBSK5HBSKS                    = 0x16A5F0; // type:func\nCdartStuckHbsk__FP4HBSK                        = 0x16A758; // type:func\nPdartOldestHbskStuck__FP4HBSK                  = 0x16A820; // type:func\nGetHbskClosestHidePos__FP4HBSKP6VECTORPf       = 0x16A910; // type:func\n\ng_dlHshape = 0x2626E8; // size:0xc\ng_dlHpnt   = 0x2626F8; // size:0xc\ng_dlHbsk   = 0x262708; // size:0xc\n\n\n////////////////////////////////////////////////////////////////\n// P2/hnd.c\n////////////////////////////////////////////////////////////////\nInitHnd__FP3HND                             = 0x16C470; // type:func\nLoadHndFromBrx__FP3HNDP18CBinaryInputStream = 0x16C4B8; // type:func\njunk_0016c4d8                               = 0x16C4D8; // type:func\n\nD_0024A7DC = 0x24A7DC; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/ik.c\n////////////////////////////////////////////////////////////////\nRenderIkhSelf__FP3IKHP2CMP2RO   = 0x16C4E8; // type:func\nRenderLikhSelf__FP4LIKHP2CMP2RO = 0x16C508; // type:func\nSolveAloIK__FP3ALO              = 0x16C528; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/jlo.c\n////////////////////////////////////////////////////////////////\nInitJlo__FP3JLO                               = 0x16CE00; // type:func\nLoadJloFromBrx__FP3JLOP18CBinaryInputStream   = 0x16CE80; // type:func\nPostJloLoad__FP3JLO                           = 0x16CF70; // type:func\nFUN_0016d040                                  = 0x16D040; // type:func\nPresetJloAccel__FP3JLOf                       = 0x16D0C0; // type:func\nUpdateJlo__FP3JLOf                            = 0x16D128; // type:func\nJlosNextJlo__FP3JLO                           = 0x16D1E0; // type:func\nSetJloJlovol__FP3JLOP6JLOVOL                  = 0x16D3F0; // type:func\nFireJlo__FP3JLO                               = 0x16D490; // type:func\nLandJlo__FP3JLO                               = 0x16D788; // type:func\nJumpJlo__FP3JLO                               = 0x16D828; // type:func\nFUN_0016d928                                  = 0x16D928; // type:func\nFUN_0016d9a8                                  = 0x16D9A8; // type:func\nHandleJloMessage__FP3JLO5MSGIDPv              = 0x16DA00; // type:func\nSetJloJlos__FP3JLO4JLOS                       = 0x16DAC0; // type:func\nActivateJlo__FP3JLO                           = 0x16DCF0; // type:func\nDeactivateJlo__FP3JLO                         = 0x16DD00; // type:func\nInitJloc__FP4JLOC                             = 0x16DD10; // type:func\nLoadJlocFromBrx__FP4JLOCP18CBinaryInputStream = 0x16DD90; // type:func\nPostJlocLoad__FP4JLOC                         = 0x16DDE8; // type:func\nPxfmChooseJloc__FP4JLOC                       = 0x16DE20; // type:func\nInitJlovol__FP6JLOVOL                         = 0x16DF30; // type:func\nBindJlovol__FP6JLOVOL                         = 0x16DF68; // type:func\nHandleJlovolMessage__FP6JLOVOL5MSGIDPv        = 0x16DFE0; // type:func\n\ng_pjloCur = 0x2629c8; // size:0x4\ns_asnipLoadJlo = 0x2629d0;\n\n\n////////////////////////////////////////////////////////////////\n// P2/joy.c\n////////////////////////////////////////////////////////////////\nStartupJoy__Fv = 0x16E0B8; // type:func\nAddGrfusr__Fi = 0x16E0F0; // type:func\nRemoveGrfusr__Fi = 0x16E118; // type:func\nUpdateGrfjoytFromGrfusr__Fv = 0x16E148; // type:func\nInitJoy__FP3JOYii = 0x16E1A0; // type:func\nUpdateJoy__FP3JOY = 0x16E238; // type:func\nSetJoyJoys__FP3JOY4JOYS4JOYK = 0x16E630; // type:func\nGetJoyXYDeflection__FP3JOYUcUcPfN23PUcT6PiP2LM = 0x16E738; // type:func\nFReadJoy__FP3JOY = 0x16E940; // type:func\nSetJoyBtnHandled__FP3JOYUs = 0x16EC20; // type:func\nTriggerJoyRumbleRumk__FP3JOY4RUMKf = 0x16EC38; // type:func\njunk_0016EC80 = 0x16EC80; // type:func\nStartJoySelection__FP3JOY = 0x16EC88; // type:func\nDxSelectionJoy__FP3JOY = 0x16EC98; // type:func\nDySelectionJoy__FP3JOY = 0x16EED0; // type:func\nUBtnpJoy__FP3JOY4BTNP = 0x16F108; // type:func\nAddCode__FP4CODE = 0x16F188; // type:func\njunk_0016F1F0 = 0x16F1F0; // type:func\n_ResetCodes__Fv = 0x16F1F8; // type:func\n_MatchCodes__FP3JOYUs = 0x16F238; // type:func\nUpdateCodes__Fv = 0x16F2E0; // type:func\nClearFchts__Fv = 0x16F408; // type:func\nAddFcht__Fi = 0x16F430; // type:func\njunk_0016F470 = 0x16F470; // type:func\nChetkido__Fv = 0x16F478; // type:func\nStartupCodes__Fv = 0x16F588; // type:func\n\ng_aja = 0x262A30; // size:0x20\ng_mpbtnpfbtn = 0x262A50; // size:0x18\ng_grfcht = 0x262C64; // size:0x4\ng_grfjoyt = 0x262C68; // size:0x4\ng_grfusr = 0x262C6C; // size:0x4\ng_joy = 0x262C70; // size:0xc4\ng_joyZero = 0x262D38; // size:0xc4\ng_pcode = 0x262DFC; // size:0x4\ng_tCodeCheck = 0x262E00;\n\n\n////////////////////////////////////////////////////////////////\n// P2/jt.c\n////////////////////////////////////////////////////////////////\nInitJt__FP2JT = 0x16F608; // type:func\nLoadJtFromBrx__FP2JTP18CBinaryInputStream = 0x16F7B0; // type:func\nPostJtLoad__FP2JT = 0x16F810; // type:func\nPresetJtAccelBase = 0x16FD70; // type:func\nPresetJtAccel__FP2JTf = 0x1701B0; // type:func\nAdjustJtNewXp__FP2JTP2XPi = 0x170410; // type:func\nAdjustJtDz__FP2JTiP2DZif = 0x170528; // type:func\nHandleJtGrfjtsc = 0x1705C8; // type:func\nUpdateJtInternalXps__FP2JT = 0x170660; // type:func\nFCheckJtXpBase__FP2JTP2XPi = 0x170790; // type:func\nAdjustJtXpVelocity__FP2JTP2XPi = 0x170820; // type:func\nHandleJtMessage__FP2JT5MSGIDPv = 0x170960; // type:func\nFTurnJtToTarget__FP2JT = 0x171180; // type:func\nUpdateJtBalance__FP2JT = 0x171238; // type:func\nRebuildJtXmg__FP2JTP3ALOfT1P6ACTADJP3XMG = 0x1719E8; // type:func\nFMatchJtXmg__FP2JTP3XMGP6ACTADJ = 0x171C80; // type:func\nUpdateJtStand__FP2JT = 0x171DD8; // type:func\nThrowJt__FP2JTP6VECTORff = 0x171F28; // type:func\nUnhookJt__FP2JT = 0x171FE0; // type:func\nCalculateJtToolSpin__FP2JTfP7MATRIX3 = 0x172078; // type:func\nRenderJtAll__FP2JTP2CMP2RO = 0x1721B0; // type:func\nFUN_00172530 = 0x172530; // type:func\nFUN_001725e0 = 0x1725E0; // type:func\nUpdateJtTool__FP2JT = 0x1727B0; // type:func\nFUN_00172898 = 0x172898; // type:func\nUpdateJtPosWorldPrev__FP2JT = 0x172AE0; // type:func\nFUN_00172b08 = 0x172B08; // type:func\nUpdateJtBounds__FP2JT = 0x172B88; // type:func\nPsoGetJtEffect__FP2JTPi = 0x172BF8; // type:func\nAddJtCustomXps__FP2JTP2SOiP3BSPT3PP2XP = 0x172CF0; // type:func\nCtTorqueJt__FP2JT = 0x172EB8; // type:func\nFUN_00172ee0 = 0x172EE0; // type:func\nGetJtCpdefiFlatten__FP2JTP6CPDEFI = 0x1733B8; // type:func\nFUN_00173708 = 0x173708; // type:func\nFUN_00173750 = 0x173750; // type:func\nUpdateJtActive__FP2JTP3JOYf = 0x173888; // type:func\nUpdateJt__FP2JTf = 0x174808; // type:func\nUpdateJtDrive__FP2JT = 0x174E20; // type:func\nChooseJtPhys__FP2JT = 0x174F50; // type:func\nEnableJtActadj__FP2JTi = 0x175078; // type:func\nSetJtJts__FP2JT3JTS4JTBS = 0x175170; // type:func\nProfileJt__FP2JTi = 0x1777F8; // type:func\nSetJtPuppet__FP2JTP5ASEGA = 0x177800; // type:func\nFUN_00177828 = 0x177828; // type:func\nPaloAbsorbWkr__FP3WKRiPP3ALO = 0x177838; // type:func\nNCmpWkr__FP3WKRT0 = 0x177968; // type:func\nUpdateJtEffect__FP2JT = 0x177990; // type:func\nFIsJtSoundBase__FP2JT = 0x177E20; // type:func\nCollectJtPrize__FP2JT3PCKP3ALO = 0x177E70; // type:func\nGetJtDiapi__FP2JTP6DIALOGP5DIAPI = 0x177EE0; // type:func\nPlayJtDialog__FP2JTP6DIALOG = 0x177F98; // type:func\n\ng_pjt = 0x262e10; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/jsg.c\n////////////////////////////////////////////////////////////////\nInitJsg__FP3JSG                      = 0x17B998; // type:func\nGetJsgLocation__FP3JSGP2LOP6VECTORPf = 0x17B9D0; // type:func\nSetJsgFocus__FP3JSGP2LO              = 0x17BB78; // type:func\nSetJsgTn__FP3JSGP2TN                 = 0x17BC20; // type:func\nNextJsgJsge__FP3JSG                  = 0x17BCD0; // type:func\nFIsJsgJsgeComplete__FP3JSGP4JSGE     = 0x17C428; // type:func\nUpdateJsgJsge__FP3JSG                = 0x17C660; // type:func\nReadJsgJoystick__FP3JSGP3JOY         = 0x17C718; // type:func\nFIsJsgActive__FP3JSG                 = 0x17CDA8; // type:func\nClearJsg__FP3JSG                     = 0x17CDE0; // type:func\nApplyJsg__FP3JSGP2JT                 = 0x17CE20; // type:func\nRetractJsg__FP3JSG                   = 0x17CE80; // type:func\nPjsgeAllocJsg__FP3JSG5JSGEK3OIDi     = 0x17CF38; // type:func\nAddJsgContext__FP3JSG3OID            = 0x17CFC8; // type:func\nAddJsgCut__FP3JSG3OID                = 0x17CFF0; // type:func\nAddJsgFocus__FP3JSG3OID              = 0x17D018; // type:func\nAddJsgLabel__FP3JSG3OID              = 0x17D040; // type:func\nAddJsgTunnel__FP3JSG3OID             = 0x17D078; // type:func\nAddJsgPause__FP3JSG3OIDf             = 0x17D0A0; // type:func\nAddJsgAseg__FP3JSG3OIDi              = 0x17D0D8; // type:func\nAddJsgJump__FP3JSG3OID5JSGJK5JSGLKi  = 0x17D100; // type:func\nAddJsgRun__FP3JSG3OIDfi              = 0x17D148; // type:func\nAddJsgClimb__FP3JSG3OIDfi            = 0x17D180; // type:func\nAddJsgAttack__FP3JSG3OID4FTAKi       = 0x17D1B8; // type:func\nAddJsgClock__FP3JSGf                 = 0x17D1E8; // type:func\nAddJsgUnknown__FP3JSG                = 0x17D220; // type:func\n\ns_jsge = 0x2BE478;\n\n\n////////////////////////////////////////////////////////////////\n// P2/jump.c\n////////////////////////////////////////////////////////////////\nPresetJtAccelJump__FP2JT                    = 0x17D248; // type:func\nUpdateJtActiveJump__FP2JTP3JOY              = 0x17D5D8; // type:func\nFCheckJtSingleEdge__FP2JTP2SOP4EDGEP6VECTOR = 0x17DCE0; // type:func\nFCheckJtEdgeNormal__FP2JTP6VECTORT1         = 0x17DE88; // type:func\nFCheckJtEdgeGrab__FP2JTP2SOP6VECTOR3XPKPvT2 = 0x17E088; // type:func\nPxpFindJtBestEdge__FP2JTPiP6VECTOR          = 0x17E3C8; // type:func\nJtsResetJt__FP2JT                           = 0x17E6D0; // type:func\nHandleJtDiveEffect__FP2JT                   = 0x17E710; // type:func\nFUN_0017ece8                                = 0x17ECE8; // type:func\nUpdateJtJump__FP2JT                         = 0x17F018; // type:func\nFTimeJtJumpToTarget__FP2JTP6VECTORN31Pf     = 0x17FAC0; // type:func\nGetJtJumpVelocity__FP2JTP6VECTOR            = 0x17FB78; // type:func\nGetJtJumpToTargetVelocity__FP2JTP6VECTOR    = 0x17FC48; // type:func\nGetJtJumpBoostVelocity__FP2JTP6VECTOR       = 0x17FCC8; // type:func\nStartupJmt__Fv                              = 0x17FD48; // type:func\nResetJmtList__Fv                            = 0x17FD70; // type:func\nOnJmtAdd__FP3JMT                            = 0x17FD90; // type:func\nOnJmtRemove__FP3JMT                         = 0x17FDC8; // type:func\nCloneJmt__FP3JMTT0                          = 0x17FE00; // type:func\nPostJmtLoad__FP3JMT                         = 0x17FE48; // type:func\n\ng_dlJmt = 0x264088; // size:0xc\n\n\n////////////////////////////////////////////////////////////////\n// P2/keyhole.c\n////////////////////////////////////////////////////////////////\nInitKeyhole__FP7KEYHOLE                             = 0x17FE90; // type:func\nLoadKeyholeFromBrx__FP7KEYHOLEP18CBinaryInputStream = 0x17FEC0; // type:func\nDrawKeyholeMask__FP7KEYHOLEffff                     = 0x180108; // type:func\nDrawKeyhole__FP7KEYHOLEf                            = 0x180398; // type:func\nkeyhole__static_initialization_and_destruction_0    = 0x180E38; // type:func\n_GLOBAL_$I$InitKeyhole__FP7KEYHOLE                  = 0x180E90; // type:func\n\ng_pkeyhole = 0x2640A4; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/landing.c\n////////////////////////////////////////////////////////////////\nOnLandingAdd__FP7LANDING    = 0x180EB0; // type:func\nOnLandingRemove__FP7LANDING = 0x180EE8; // type:func\nCloneLanding__FP7LANDINGT0  = 0x180F20; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/lgn.c\n////////////////////////////////////////////////////////////////\nInitLgn__FP3LGN                  = 0x180F68; // type:func\nPostLgnLoad__FP3LGN              = 0x180F98; // type:func\nUpdateLgnActive__FP3LGNP3JOYf    = 0x181078; // type:func\nUpdateLgn__FP3LGNf               = 0x181448; // type:func\nFUN_00181658                     = 0x181658; // type:func\nOnLgnActive__FP3LGNiP2PO         = 0x181780; // type:func\nRenderLgnAll__FP3LGNP2CMP2RO     = 0x181818; // type:func\nGetLgnCpdefi__FP3LGNfP6CPDEFI    = 0x181A58; // type:func\nFInvulnerableLgn__FP3LGN3ZPK     = 0x181A98; // type:func\nJthsCurrentLgn__FP3LGN           = 0x181AE0; // type:func\nUseLgnCharm__FP3LGN              = 0x181AF0; // type:func\nApplyLgnThrow__FP3LGNP2PO        = 0x181B20; // type:func\nFTakeLgnDamage__FP3LGNP3ZPR      = 0x181BC8; // type:func\nHandleLgnMessage__FP3LGN5MSGIDPv = 0x181D28; // type:func\nFUN_00181d88                     = 0x181D88; // type:func\nSetLgnLgns__FP3LGN4LGNS          = 0x181DA8; // type:func\nUpdateLgnrAim__FP4LGNRP3JOY      = 0x181ED0; // type:func\nDrawLgnr__FP4LGNR                = 0x1821B0; // type:func\nInitSwp__FP3SWP                  = 0x182470; // type:func\nPostSwpLoad__FP3SWP              = 0x1824D8; // type:func\nUpdateSwp__FP3SWPf               = 0x182548; // type:func\nProjectSwpTransform__FP3SWPfi    = 0x182748; // type:func\nSetSwpShape__FP3SWPP5SHAPEf      = 0x182948; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/lo.c\n////////////////////////////////////////////////////////////////\nInitLo__FP2LO = 0x182c18; // type:func\nPostLoLoad__FP2LO = 0x182c58; // type:func\nAddLo__FP2LO = 0x182c80; // type:func\nAddLoHierarchy__FP2LO = 0x182d00; // type:func\nOnLoAdd__FP2LO = 0x182d48; // type:func\nRemoveLo__FP2LO = 0x182d50; // type:func\nDeferLoRemove__FP2LO = 0x182dd8; // type:func\nSetLoSuckHideLimits__FP2LOP2LM = 0x182e40; // type:func\nRemoveLoHierarchy__FP2LO = 0x182e88; // type:func\nOnLoRemove__FP2LO = 0x182ed0; // type:func\nSnipLo__FP2LO = 0x182ed8; // type:func\nFFindLoParent__FP2LOP3ALO = 0x182f40; // type:func\nSetLoParent__FP2LOP3ALO = 0x182f78; // type:func\nFIsLoInWorld__FP2LO = 0x182fc8; // type:func\nGetLoInWorld__FP2LOPi = 0x183028; // type:func\njunk_00183050 = 0x183050; // type:func\nPloCloneLo__FP2LOP2SWP3ALO = 0x183058; // type:func\nCloneLoHierarchy__FP2LOT0 = 0x1830b0; // type:func\nCloneLo__FP2LOT0 = 0x1830d8; // type:func\nSubscribeSwPpmqStruct__FP2SWPP2MQPFPv5MSGIDPv_vPv = 0x1831e8; // type:func\nUnsubscribeSwPpmqStruct__FP2SWPP2MQPFPv5MSGIDPv_vPv = 0x183238; // type:func\nSubscribeLoStruct__FP2LOPFPv5MSGIDPv_vPv = 0x183290; // type:func\nUnsubscribeLoStruct__FP2LOPFPv5MSGIDPv_vPv = 0x1832c0; // type:func\nSubscribeLoObject__FP2LOT0 = 0x1832f0; // type:func\nUnsubscribeLoObject__FP2LOT0 = 0x183320; // type:func\nSendLoMessage__FP2LO5MSGIDPv = 0x183350; // type:func\nLoadLoFromBrx__FP2LOP18CBinaryInputStream = 0x1833d0; // type:func\nFMatchesLoName__FP2LO3OID = 0x1833f0; // type:func\nOidProxyLo__FP2LO = 0x183438; // type:func\nOidProxyLoPreferred__FP2LO = 0x183458; // type:func\nGetLoOidProxy__FP2LOP3OID = 0x183478; // type:func\nPostSpliceEventCallback__FP2LOUiPv = 0x1834a0; // type:func\nFFilterSpliceEvent__FP2LO7SYMEVIDiPPv = 0x183668; // type:func\nHandleLoSpliceEvent__FP2LOUiiPPv = 0x1837e0; // type:func\nEnsureLoSidebagBool__FP2LO5OPTIDi = 0x183910; // type:func\nEnsureLoSidebagInt__FP2LO5OPTIDi = 0x183990; // type:func\nEnsureLoSidebagFloat__FP2LO5OPTIDf = 0x183a10; // type:func\nEnsureLoSidebagClq__FP2LO5OPTIDP3CLQ = 0x183a90; // type:func\nEnsureLoSidebagLm__FP2LO5OPTIDP2LM = 0x183b20; // type:func\nEnsureLoSidebagOid__FP2LO5OPTID3OID = 0x183bb8; // type:func\nEnsureLoSidebagVector__FP2LO5OPTIDP6VECTOR = 0x183c38; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/light.c\n////////////////////////////////////////////////////////////////\nInitLight__FP5LIGHT                            = 0x183CC8; // type:func\nUpdateLightXfWorldHierarchy__FP5LIGHT          = 0x183D88; // type:func\nRemoveLightFromSw__FP5LIGHT                    = 0x183DC0; // type:func\nAddLightToSw__FP5LIGHT                         = 0x183DF8; // type:func\nOnLightAdd__FP5LIGHT                           = 0x183E40; // type:func\nOnLightRemove__FP5LIGHT                        = 0x183E70; // type:func\nCloneLight__FP5LIGHTT0                         = 0x183EA0; // type:func\nFitLinearFunction__FffffPfT4                   = 0x183F40; // type:func\nFitRecipFunction__FffffPfT4                    = 0x183FE0; // type:func\nConvertFallOff__FP2LMPfT1                      = 0x1840B8; // type:func\nConvertAngleStrength__FffffPfT4                = 0x1840F0; // type:func\nInvalidateLight__FP5LIGHT                      = 0x1841B0; // type:func\nRebuildLightVifs__FP5LIGHT                     = 0x1841D0; // type:func\nSetLightKind__FP5LIGHT6LIGHTK                  = 0x184768; // type:func\nSetLightHighlightColor__FP5LIGHTP6VECTOR       = 0x1847F0; // type:func\nSetLightMidtoneStrength__FP5LIGHTf             = 0x184818; // type:func\nSetLightShadowStrength__FP5LIGHTf              = 0x184838; // type:func\nSetLightHighlightAngle__FP5LIGHTf              = 0x184858; // type:func\nSetLightMidtoneAngle__FP5LIGHTf                = 0x184878; // type:func\nSetLightShadowAngle__FP5LIGHTf                 = 0x184898; // type:func\nSetLightDirection__FP5LIGHTP6VECTOR            = 0x1848B8; // type:func\nSetLightDynamic__FP5LIGHTi                     = 0x184968; // type:func\nSetLightFallOff__FP5LIGHTP2LM                  = 0x184990; // type:func\nSetLightConeAngle__FP5LIGHTf                   = 0x1849D0; // type:func\nSetLightHotSpotAngle__FP5LIGHTf                = 0x184A08; // type:func\nSetLightFrustrumUp__FP5LIGHTP6VECTOR           = 0x184A38; // type:func\nRebuildLightFrustrum__FP5LIGHT                 = 0x184A70; // type:func\nUpdateLightBeamGrfzon__FP5LIGHT                = 0x184B58; // type:func\nSetLightDiffuse_Old__FP5LIGHTf                 = 0x184CD0; // type:func\nGetLightDiffuse_Old__FP5LIGHTPf                = 0x184D10; // type:func\nSetLightSaturate_Old__FP5LIGHTP6VECTOR         = 0x184D20; // type:func\nGetLightSaturate_Old__FP5LIGHTP6VECTOR         = 0x184D58; // type:func\nNCmpFindLight__FPP5LIGHTT0                     = 0x184D78; // type:func\nPrepareSwLightsForDraw__FP2SW                  = 0x184DE8; // type:func\nTwpsFindSwLights__FP2SWP6VECTORfiiPiT5PP5LIGHT = 0x185150; // type:func\n\ng_cframeStaticLightsInvalid = 0x264260; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/lookat.c\n////////////////////////////////////////////////////////////////\nInitActla__FP5ACTLAP3ALO                         = 0x185358; // type:func\nSetActlaTarget__FP5ACTLAP3ALOP6VECTOR            = 0x1853F0; // type:func\nPaloGetActlaTarget__FP5ACTLA                     = 0x185468; // type:func\nUpdateActla__FP5ACTLAf                           = 0x185498; // type:func\nGetActlaRotationGoal__FP5ACTLAfP7MATRIX3P6VECTOR = 0x185538; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/main.c\n////////////////////////////////////////////////////////////////\nmain           = 0x185758; // type:func\nStartupSif__Fv = 0x1858f8; // type:func\nStartupVU0__Fv = 0x185A58; // type:func\nStartupVU1__Fv = 0x185AC8; // type:func\nStartup__Fv    = 0x185B38; // type:func\n\ns_apchzSifModules = 0x2647A8; // size:0x18\ns_asfn            = 0x2647C0; // size:0x74\ng_cpchzArgs       = 0x264834; // size:0x4\ng_apchzArgs       = 0x264838; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/mark.c\n////////////////////////////////////////////////////////////////\nMuFromAmtlk__FP4MTLK                                   = 0x185C18; // type:func\nElasFromAmtlk__FP4MTLK                                 = 0x185CA0; // type:func\nPxpAdd__FP2SOT0P6VECTORT2f3XPKPvT6PP2XP                = 0x185D20; // type:func\nRecalcSwXpPos__FP2SWiPP2XP                             = 0x185F48; // type:func\nRecalcSwXpMovement__FP2SWiPP2XP                        = 0x1860A8; // type:func\nFreeSwXpList__FP2SWP2XP                                = 0x1861E8; // type:func\nFindClosestPointOnLine__FP6VECTORN20PfT3               = 0x186230; // type:func\nFindClosestPointOnLineSegment__FP6VECTORN20PfT3        = 0x186320; // type:func\nClsgClipSoAllEdges__FP2SOT0P3BSPiP3LSG                 = 0x186450; // type:func\nClsgClipSoBspEdges__FP2SOT0iP3BSPiP3LSG                = 0x186568; // type:func\nCategorizeAlsg__FiP3LSGPiT2PP3LSGT4                    = 0x1867C8; // type:func\nCplsgFindEdgePath__FP4SURFiiP3LSGPP3LSG                = 0x186A70; // type:func\nMarkSoContactsBspBsp__FP2SOT0iP3BSPT3PP2XP             = 0x186BA8; // type:func\nCsbiIntersectSphereBsp__FP6VECTORfiP3BSPT3P4GEOMiP3SBI = 0x187260; // type:func\nMarkSoContactsSphereBsp__FP2SOP6VECTORfT0iP3BSPT5PP2XP = 0x1879C0; // type:func\nMarkSoContactsSphereSphere__FP2SOT0PP2XP               = 0x187A88; // type:func\nCalculateCenterContact__FP2SOP6VECTORfT1Pf             = 0x187B60; // type:func\nFMarkSoContactsCenterBsp__FP2SOT0iP3BSPT3PP2XP         = 0x187C28; // type:func\nFClipEdgeToSphere__FP6VECTORfT0T0PfT0T0T4              = 0x187D08; // type:func\nFMarkSoContactsCenterSphere__FP2SOT0PP2XP              = 0x187E88; // type:func\nAddSoXps__FP2SOT0iiP3BSPT4PP2XP                        = 0x187F40; // type:func\nPxpMarkSwContactsRoot__FP2SWPP2SOi                     = 0x188270; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/mat.c\n////////////////////////////////////////////////////////////////\nPostCopyMatrix3__7MATRIX4                                = 0x1884C0; // type:func\n__as__7MATRIX4RC7MATRIX3                                 = 0x1884E0; // type:func\nMatMulMatTransMat__FRC7MATRIX3T0                         = 0x188520; // type:func\nLoadIdentityMatrix4__FP7MATRIX4                          = 0x1885E0; // type:func\n__ml__FRC7MATRIX4G8VU_FLOAT                              = 0x188628; // type:func\n__ml__FRC7MATRIX4T0                                      = 0x188668; // type:func\njunk_001886F8                                            = 0x1886F8; // type:func\nMultiplyMatrix4Vector__FP7MATRIX4P6VECTORfT1             = 0x188700; // type:func\n__ml__FRC7MATRIX4G10VU_VECTOR4                           = 0x188740; // type:func\nTransposeMatrix4__FP7MATRIX4T0                           = 0x188770; // type:func\nAddMatrix4Matrix4__FP7MATRIX4N20                         = 0x188810; // type:func\njunk_00188848                                            = 0x188848; // type:func\nLoadRotateMatrixRad__FfP6VECTORP7MATRIX3                 = 0x188850; // type:func\nLoadRotateMatrix__FP6VECTORP7MATRIX3                     = 0x188978; // type:func\nLoadRotateMatrixEuler__FP6VECTORP7MATRIX3                = 0x188A20; // type:func\nLoadMatrixFromPosRot__FP6VECTORP7MATRIX3P7MATRIX4        = 0x188B08; // type:func\nLoadMatrixFromPosRotInverse__FP6VECTORP7MATRIX3P7MATRIX4 = 0x188B48; // type:func\nLoadMatrixFromPosRotScale__FP6VECTORP7MATRIX3T0P7MATRIX4 = 0x188C10; // type:func\njunk_00188CC8                                            = 0x188CC8; // type:func\nCosRotateMatrixMagnitude__FP7MATRIX3                     = 0x188CE0; // type:func\nDecomposeRotateMatrixRad__FP7MATRIX3PfP6VECTOR           = 0x188D28; // type:func\njunk_00188FD0                                            = 0x188FD0; // type:func\nDecomposeRotateMatrixEuler__FP7MATRIX3P6VECTOR           = 0x188FD8; // type:func\nNormalizeRotateMatrix3__FP7MATRIX3                       = 0x1890A0; // type:func\nCalculateDmat__FP7MATRIX3N20                             = 0x189150; // type:func\nCalculateDmat4__FP7MATRIX4N20                            = 0x1891C0; // type:func\nDecomposeRotateMatrixPanTilt__FP7MATRIX3PfT1             = 0x189230; // type:func\nLoadRotateMatrixPanTilt__FffP7MATRIX3                    = 0x1892A0; // type:func\nLoadLookAtMatrix__FP6VECTORP7MATRIX3                     = 0x189350; // type:func\nTiltMatUpright__FP7MATRIX3N20                            = 0x189378; // type:func\njunk_00189430                                            = 0x189430; // type:func\nFInvertMatrix__FiPfT1                                    = 0x189438; // type:func\nFInvertMatrix3__FP7MATRIX3T0                             = 0x1897F0; // type:func\nFInvertMatrix4__FP7MATRIX4T0                             = 0x189AF0; // type:func\nBuildOrthonormalMatrixY__FP6VECTORT0P7MATRIX3            = 0x189B18; // type:func\nBuildOrthonormalMatrixZ__FP6VECTORT0P7MATRIX3            = 0x189C28; // type:func\nBuildRotateVectorsMatrix__FP6VECTORT0P7MATRIX3           = 0x189D38; // type:func\nBuildSimpleProjectionMatrix__FffffffP7MATRIX4            = 0x189F58; // type:func\nLoadScaleMatrixScalar__FP6VECTORfP7MATRIX4               = 0x18A008; // type:func\nLoadScaleMatrixVector__FP6VECTORP7MATRIX3T0P7MATRIX4     = 0x18A040; // type:func\nLoadRotateVectorMatrix__FP6VECTORT0P7MATRIX3             = 0x18A160; // type:func\n\n// TODO: Do these belong here?\ng_normalX = 0x248D00; // size:0xc\ng_normalY = 0x248D10; // size:0xc\ng_normalZ = 0x248D20; // size:0xc\n\n\n////////////////////////////////////////////////////////////////\n// P2/mb.c\n////////////////////////////////////////////////////////////////\nInitMbg__FP3MBG                                     = 0x18A388; // type:func\nLoadMbgFromBrx__FP3MBGP18CBinaryInputStream         = 0x18A3B8; // type:func\nPostMbgLoad__FP3MBG                                 = 0x18A3F0; // type:func\nFUN_0018a510                                        = 0x18A510; // type:func\nFUN_0018a628                                        = 0x18A628; // type:func\nPsoHitTestCylinderObjects__FiP6VECTORT1fiPP2SOP3LSG = 0x18A6C0; // type:func\nFFilterMbgAttackObjects__FP3MBGP2SO                 = 0x18A830; // type:func\nFObstructedMbg__FP3MBGP6VECTORT1                    = 0x18A910; // type:func\nFCanMbgAttack__FP3MBG                               = 0x18A9A8; // type:func\nFDetectMbg__FP3MBG                                  = 0x18AAE0; // type:func\nFUN_0018ab88__Fi                                    = 0x18AB88; // type:func\nFUN_0018abf0__Fi                                    = 0x18ABF0; // type:func\nFUN_0018ac58__Fi                                    = 0x18AC58; // type:func\nUpdateMbg__FP3MBGf                                  = 0x18ACD0; // type:func\nFUN_0018acf0                                        = 0x18ACF0; // type:func\nUpdateMbgGoal__FP3MBGi                              = 0x18AD88; // type:func\nUpdateMbgSgs__FP3MBG                                = 0x18AE38; // type:func\nOnMgExitingSgs__FP3MBG3SGS                          = 0x18B2E8; // type:func\nHandleMbgMessage__FP3MBG5MSGIDPv                    = 0x18B340; // type:func\nFUN_0018b460                                        = 0x18B460; // type:func\n\ns_asnipLoadMbg = 0x264910;\n\n\n////////////////////////////////////////////////////////////////\n// P2/memcard.c\n// TODO: Mangle function names.\n// NOTE: These can be incorrect as they are not found in the may prototype.\n////////////////////////////////////////////////////////////////\nStartupMemcard__Fv                   = 0x18B580; // type:func\nInitMemcard__FP7MEMCARD              = 0x18B5C0; // type:func\nFUN_0018b600__Fv                     = 0x18B600; // type:func\nCreateMemcardThread__FP7MEMCARDii    = 0x18B670; // type:func\nSetMemcardThreadHighPrio__FP7MEMCARD = 0x18B720; // type:func\nFCheckMemcardThread__FP7MEMCARD      = 0x18B770; // type:func\nFUN_0018b780                         = 0x18B780; // type:func\nFUN_0018b910__Fi                     = 0x18B910; // type:func\nFUN_0018b930__Fi                     = 0x18B930; // type:func\nFUN_0018b988                         = 0x18B988; // type:func\nFUN_0018bc90                         = 0x18BC90; // type:func\nFUN_0018bd00                         = 0x18BD00; // type:func\nInitSave__FP4SAVEii                  = 0x18BD58; // type:func\nUpdateSave__FP4SAVE                  = 0x18BDC8; // type:func\nCompareSaves__FP4SAVET0              = 0x18BFA8; // type:func\nFUN_0018c028                         = 0x18C028; // type:func\nFUN_0018c178_FP4SAVEi                = 0x18C178; // type:func\nFUN_0018c1a8                         = 0x18C1A8; // type:func\nFUN_0018c1e8                         = 0x18C1E8; // type:func\nFUN_0018c250                         = 0x18C250; // type:func\nFUN_0018c420                         = 0x18C420; // type:func\nFUN_0018c568                         = 0x18C568; // type:func\nFUN_0018c638                         = 0x18C638; // type:func\nFUN_0018c770                         = 0x18C770; // type:func\nFUN_0018c7f8__FP4SAVE                = 0x18C7F8; // type:func\nFUN_0018c888                         = 0x18C888; // type:func\nFUN_0018c9c0                         = 0x18C9C0; // type:func\nFUN_0018ca10                         = 0x18CA10; // type:func\nload_sly_icon_from_disc              = 0x18CDF8; // type:func\nload_file_from_disc                  = 0x18CC20; // type:func\nFUN_0018cdd8                         = 0x18CDD8; // type:func\nFUN_0018cfc0                         = 0x18CFC0; // type:func\nFUN_0018d028                         = 0x18D028; // type:func\nFUN_0018d0a0                         = 0x18D0A0; // type:func\nFUN_0018d168                         = 0x18D168; // type:func\nFUN_0018d1f8                         = 0x18D1F8; // type:func\nFUN_0018d228                         = 0x18D228; // type:func\nFUN_0018d268                         = 0x18D268; // type:func\nFUN_0018d2b0                         = 0x18D2B0; // type:func\nFUN_0018d2e8                         = 0x18D2E8; // type:func\nFUN_0018d328                         = 0x18D328; // type:func\nFUN_0018d368                         = 0x18D368; // type:func\nClear__13CFileLocation               = 0x18D410; // type:func\n\ns_savePath = 0x24b3b0;\n\ng_memcard = 0x269990; // size:0x14\ng_save = 0x264A40;\n\n\n////////////////////////////////////////////////////////////////\n// P2/memory.c\n////////////////////////////////////////////////////////////////\nStartupMemMgr__Fv = 0x18D430; // type:func\nPvAllocGlobalImpl__Fi = 0x18D4B0; // type:func\njunk_0018D4F0 = 0x18D4F0; // type:label\nCheckForOutOfMemory__Fv = 0x18D4F8; // type:func\nPvAllocSwImpl__Fi = 0x18D500; // type:func\nFreeSw__Fv = 0x18D550; // type:func\nPvAllocSwCopyImpl__FiPv = 0x18D568; // type:func\nPvAllocSwClearImpl__Fi = 0x18D5C0; // type:func\nInitStackImpl__Fv = 0x18D608; // type:func\nPvAllocStackImpl__Fi = 0x18D658; // type:func\nPvAllocStackClearImpl__Fi = 0x18D6A8; // type:func\nFreeStackImpl__Fv = 0x18D6F0; // type:func\nmalloc = 0x18D740; // type:func\n_malloc_r = 0x18D748; // type:func\nfree = 0x18D750; // type:func\n__builtin_new = 0x18D758; // type:func\n__builtin_delete = 0x18D778; // type:func\nCopyAqw__FPvT0i = 0x18D780; // type:func\nCopyAb__FPvT0Ui = 0x18D800; // type:func\n\ns_pvGlobalMin = 0x2C2A10; // size:0x4\ns_pvGlobalMac = 0x2C2A14; // size:0x4\ns_pvWorldMin = 0x2C2A18; // size:0x4\ns_pvWorldMac = 0x2C2A1C; // size:0x4\ns_pvStackMin = 0x2C2A20; // size:0x4\ns_pvStackMac = 0x2C2A24; // size:0x4\ns_critsectStack = 0x2C2A28; // size:0xc\ns_ipvStackCur = 0x2C2A34; // size:0x4\ns_apvStackMin = 0x2C2A38; // size:0x4\n\n// TODO: Move elsewhere?\ng_pvHeapMin = 0x2699A4; // size:0x4\ng_pvHeapMax = 0x2699A8; // size:0x4\nD_0064C70F = 0x64C70F; // size:0x04\n\n\n////////////////////////////////////////////////////////////////\n// P2/missile.c\n////////////////////////////////////////////////////////////////\nInitMissile__FP7MISSILE                             = 0x18D8E0; // type:func\nLoadMissileFromBrx__FP7MISSILEP18CBinaryInputStream = 0x18D910; // type:func\nOnMissileRemove__FP7MISSILE                         = 0x18D978; // type:func\nProjectMissileTransform__FP7MISSILEfi               = 0x18D9B8; // type:func\nFireMissile__FP7MISSILEP3ALOP6VECTOR                = 0x18DA40; // type:func\nRenderMissileAll__FP7MISSILEP2CMP2RO                = 0x18DB20; // type:func\nFUN_0018dc88                                        = 0x18DC88; // type:func\nFUN_0018dd50                                        = 0x18DD50; // type:func\nFUN_0018dd78                                        = 0x18DD78; // type:func\nInitAccmiss__FP7ACCMISS                             = 0x18DDA0; // type:func\nFireAccmiss__FP7ACCMISSP3ALOP6VECTOR                = 0x18DDD8; // type:func\nPresetAccmissAccel__FP7ACCMISSf                     = 0x18DE70; // type:func\nFireSplmiss__FP7SPLMISSP3ALOP6VECTOR                = 0x18DEE8; // type:func\nProjectSplmissTransform__FP7SPLMISSfi               = 0x18E040; // type:func\n\ns_asnipMissile = 0x2699b0;\n\n\n////////////////////////////////////////////////////////////////\n// P2/mpeg.c\n////////////////////////////////////////////////////////////////\nFUN_0018e410                                           = 0x18E410; // type:func\nFUN_0018e480                                           = 0x18E480; // type:func\nFUN_0018e4c0                                           = 0x18E4C0; // type:func\nFUN_0018e4f0                                           = 0x18E4F0; // type:func\nFUN_0018e558                                           = 0x18E558; // type:func\nStartupMpeg__Fv                                        = 0x18E5E8; // type:func\nInit__15CQueueOutputIopii                              = 0x18E678; // type:func\nReset__15CQueueOutputIop                               = 0x18E6A0; // type:func\nCbWrite__15CQueueOutputIopiPv                          = 0x18E6C0; // type:func\nCbSend__15CQueueOutputIopiPv                           = 0x18E7C0; // type:func\nUpdate__15CQueueOutputIop                              = 0x18E838; // type:func\nFAsyncDrain__15CQueueOutputIop                         = 0x18E8C0; // type:func\nCbWrite__15CQueueOutputIpuiPv                          = 0x18E8C8; // type:func\nFAsyncDrain__15CQueueOutputIpu                         = 0x18E938; // type:func\nInit__10CMpegAudio                                     = 0x18E940; // type:func\nReset__10CMpegAudio                                    = 0x18EA48; // type:func\nClose__10CMpegAudio                                    = 0x18EAA0; // type:func\nFAccept__10CMpegAudioiPUc                              = 0x18EAF8; // type:func\nUpdate__10CMpegAudio                                   = 0x18EB98; // type:func\nFMpegAcceptVideo__FP7sceMpegP16sceMpegCbDataStrP5CMpeg = 0x18EC40; // type:func\nFMpegAcceptAudio__FP7sceMpegP16sceMpegCbDataStrP5CMpeg = 0x18EC80; // type:func\nFMpegDecodeVideo__FP7sceMpegP13sceMpegCbDataP5CMpeg    = 0x18ECA8; // type:func\nFMpegDecoderIdle__FP7sceMpegP13sceMpegCbDataP5CMpeg    = 0x18ED78; // type:func\nFMpegDecoderError__FP7sceMpegP13sceMpegCbDataP5CMpeg   = 0x18EDA0; // type:func\nBuildMpegGifs__FP2QWP11sceIpuRGB32iiiii                = 0x18EDA8; // type:func\nFUN_0018ef78                                           = 0x18EF78; // type:func\nFUN_0018f0e8                                           = 0x18F0E8; // type:func\nExecuteOids__5CMpeg                                    = 0x18F148; // type:func\nExecute__5CMpeg                                        = 0x18F198; // type:func\nStart__5CMpegP18CBinaryAsyncStream                     = 0x18F448; // type:func\nFUN_0018f610__5CMpeg                                   = 0x18F610; // type:func\nUpdate__5CMpeg                                         = 0x18F6E8; // type:func\nFinish__5CMpeg                                         = 0x18F7D0; // type:func\nCbDemuxed__5CMpegi                                     = 0x18F890; // type:func\njunk_0018F938                                          = 0x18F938; // type:func\nmpeg__static_initialization_and_destruction_0          = 0x18F940; // type:func\n_GLOBAL_$I$g_mpeg                                      = 0x18F968; // type:func\n\ng_mpeg = 0x269A00;\n\n\n////////////////////////////////////////////////////////////////\n// P2/mrkv.c\n////////////////////////////////////////////////////////////////\nInitMrkv__FP4MRKV = 0x18F988; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/ms.c\n////////////////////////////////////////////////////////////////\nRenderMsGlobset__FP2MSP2CMP2RO = 0x18F9D8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/murray.c\n////////////////////////////////////////////////////////////////\nInitMurray__FP6MURRAY                  = 0x18FEF8; // type:func\nPostMurrayLoad__FP6MURRAY              = 0x18FF28; // type:func\nFUN_0018ffb0                           = 0x18FFB0; // type:func\nOnMurrayExitingSgs__FP6MURRAY3SGS      = 0x1900A0; // type:func\nUpdateMurrayGoal__FP6MURRAYi           = 0x190128; // type:func\nUpdateMurraySgs__FP6MURRAY             = 0x190258; // type:func\nFUN_001903f0                           = 0x1903F0; // type:func\nFUN_00190450                           = 0x190450; // type:func\nFAbsorbMurrayWkr__FP6MURRAYP3WKR       = 0x1904E0; // type:func\nFDetectMurray__FP6MURRAY               = 0x190570; // type:func\nFCanMurrayAttack__FP6MURRAY            = 0x190658; // type:func\nFUN_00190660                           = 0x190660; // type:func\nSetMurrayPursueXfm__FP6MURRAYP3XFM     = 0x1906E8; // type:func\nSetMurrayPatrolXfm__FP6MURRAYP3XFM     = 0x1906F0; // type:func\nCollectMurrayPrize__FP6MURRAY3PCKP3ALO = 0x1906F8; // type:func\nFUN_00190740                           = 0x190740; // type:func\nHandleMurrayMessage                    = 0x190770; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/path.c\n////////////////////////////////////////////////////////////////\nPcbspExtract__FP4CBSP                                 = 0x1907E0; // type:func\nPcgtExtract__FP3CGT                                   = 0x1907F0; // type:func\nPcgtPointInCbspQuick__FP4CBSPP6VECTOR                 = 0x190810; // type:func\nPcgtPointInCbspSafe__FP4CBSPP6VECTOR                  = 0x1908C0; // type:func\nCbskFromG__Ff                                         = 0x1909B0; // type:func\nClsgClipEdgeToCbsp__FP4CBSPP6VECTORT1iP3LSG           = 0x1909F0; // type:func\nFClipEdgeToCbsp__FP4CBSPP6VECTORT1                    = 0x190E30; // type:func\nIcgvFromPcgv__FP2CGP3CGV                              = 0x190EA8; // type:func\nFindPathAStar__FP2CGP3CGVT1iPiPP3CGV                  = 0x190EB8; // type:func\nSimplifyApcgvNeighbor__FP4CBSPPiPP3CGV                = 0x191128; // type:func\nCposFindPath__FP2CGP6VECTORT1iT1                      = 0x191290; // type:func\nFindClosestPointInCg__FP2CGP6VECTORT1                 = 0x191570; // type:func\nLoadPathzoneFromBrx__FP8PATHZONEP18CBinaryInputStream = 0x1916D0; // type:func\nHookupCg__FP2CG                                       = 0x1919F8; // type:func\nCposFindPathzonePath__FP8PATHZONEP6VECTORT1iT1        = 0x191A68; // type:func\nFindPathzoneClosestPoint__FP8PATHZONEP6VECTORT1       = 0x191A88; // type:func\nFUN_00191aa8                                          = 0x191AA8; // type:func\nFUN_00191ac8                                          = 0x191AC8; // type:func\nChoosePathzoneRandomPoint__FP8PATHZONEP6VECTOR        = 0x191C78; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/phasemem.c\n////////////////////////////////////////////////////////////////\nSetPhase__F5PHASE = 0x191E70; // type:func\nClearPhase__F5PHASE = 0x191EB0; // type:func\n\ng_phase = 0x269ba4; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/pipe.c\n////////////////////////////////////////////////////////////////\nStartupPipe__Fv       = 0x191EC0; // type:func\nResetPipeList__Fv     = 0x191EE8; // type:func\nInitPipe__FP4PIPE     = 0x191F08; // type:func\nOnPipeAdd__FP4PIPE    = 0x191F68; // type:func\nOnPipeRemove__FP4PIPE = 0x191FA0; // type:func\nPostPipeLoad__FP4PIPE = 0x191FD8; // type:func\nClonePipe__FP4PIPET0  = 0x192020; // type:func\n\ng_dlPipe = 0x269BA8;\n\n\n////////////////////////////////////////////////////////////////\n// P2/pnt.c\n////////////////////////////////////////////////////////////////\nLoadPntFromBrx__FP3PNTP18CBinaryInputStream = 0x192068; // type:func\nGetPntPos__FP3PNTP6VECTOR                   = 0x1920B0; // type:func\nSetPntParent__FP3PNTP3ALO                   = 0x1920E0; // type:func\nApplyPntProxy__FP3PNTP5PROXY                = 0x192128; // type:func\nFUN_00192150__FP3PNTP18CBinaryInputStream   = 0x192150; // type:func\nFUN_00192190__FP3PNT                        = 0x192190; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/po.c\n////////////////////////////////////////////////////////////////\nInitPo__FP2PO = 0x1921A8; // type:func\nClonePo__FP2POT0 = 0x1921E8; // type:func\nHandlePoMessage__FP2PO5MSGIDPv = 0x192230; // type:func\nOnPoActive__FP2POiT0 = 0x1922E8; // type:func\nGetPoCpdefi__FP2POfP6CPDEFI = 0x192380; // type:func\nFIsPoSoundBase__FP2PO = 0x192410; // type:func\nMakePoActive__FP2PO = 0x192418; // type:func\nFInvulnerablePo__FP2PO3ZPK = 0x192450; // type:func\nFTakePoDamage__FP2POP3ZPR = 0x192488; // type:func\nJthsCurrentPo__FP2PO = 0x192490; // type:func\nFUN_00192498 = 0x192498; // type:func\nCollectPoPrize__FP2PO3PCKP3ALO = 0x1924C8; // type:func\nFUN_001925C0 = 0x1925C0; // type:func\nPpoCur__Fv = 0x1925F0; // type:func\nPpoStart__Fv = 0x192620; // type:func\n_IppoFindPo__FP2PO = 0x192688; // type:func\nAddPoToList__FP2PO = 0x1926D0; // type:func\nRemovePoFromList__FP2PO = 0x192780; // type:func\nOnPoAdd__FP2PO = 0x192820; // type:func\nOnPoRemove__FP2PO = 0x192850; // type:func\nSwitchToIppo__Fi = 0x192880; // type:func\njunk_00192988 = 0x192988; // type:func\nSetPoPlayable__FP2POi = 0x192990; // type:func\nSwitchToPo__FP2PO = 0x1929D0; // type:func\nPpziCur__Fv = 0x1929F8; // type:func\nGetPoDiapi__FP2POP6DIALOGP5DIAPI = 0x192A28; // type:func\nPlayPoDialog__FP2POP6DIALOG = 0x192A38; // type:func\nFUN_00192a70 = 0x192A70; // type:func\nUpdatePo__FP2POf = 0x192B58; // type:func\nUsePoCharm__FP2PO = 0x192C58; // type:func\nFUN_00192dd0 = 0x192DD0; // type:func\nFUN_001930B0 = 0x1930B0; // type:func\npo__static_initialization_and_destruction_04 = 0x1930B8; // type:func\n_GLOBAL_$I$InitPo__FP2PO = 0x1931F0; // type:func\n\ng_ippoCur = 0x269BCC; // size:0x4\ng_appo = 0x269C98; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/prog.c\n////////////////////////////////////////////////////////////////\n__5CProgP4RGBAN31 = 0x193210; // type:func\nBegin__5CProg = 0x193270; // type:func\nSetRemain__5CProgi = 0x193288; // type:func\nEnd__5CProg = 0x193300; // type:func\nDraw__5CProg = 0x193318; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/proxy.c\n////////////////////////////////////////////////////////////////\nInitProxy__FP5PROXY                             = 0x1963D8; // type:func\nLoadProxyFromBrx__FP5PROXYP18CBinaryInputStream = 0x196410; // type:func\nCloneProxy__FP5PROXYT0                          = 0x196810; // type:func\nPostProxyLoad__FP5PROXY                         = 0x196900; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/puffer.c\n////////////////////////////////////////////////////////////////\nInitPuffer__FP6PUFFER                             = 0x196938; // type:func\nLoadPufferFromBrx__FP6PUFFERP18CBinaryInputStream = 0x1969C0; // type:func\nPostPufferLoad__FP6PUFFER                         = 0x1969F8; // type:func\nPresetPufferAccel__FP6PUFFERf                     = 0x196B78; // type:func\nFFilterPuffer__FP6PUFFERP2SO                      = 0x196E48; // type:func\nUpdatePuffer__FP6PUFFERf                          = 0x196EB0; // type:func\nPpufftChoosePuffer__FP6PUFFER                     = 0x1971B8; // type:func\nFUN_001973d8                                      = 0x1973D8; // type:func\nFUN_00197458                                      = 0x197458; // type:func\nOnPufferActive__FP6PUFFERiP2PO                    = 0x1974D8; // type:func\nUpdatePufferActive__FP6PUFFERP3JOYf               = 0x1974F8; // type:func\nFUN_00197788                                      = 0x197788; // type:func\nFUN_00197848                                      = 0x197848; // type:func\nFUN_00197a08                                      = 0x197A08; // type:func\nFUN_00197a68                                      = 0x197A68; // type:func\nAddPufferWaterAcceleration__FP6PUFFERP5WATERf     = 0x197A88; // type:func\nHandlePufferMessage__FP6PUFFER5MSGIDPv            = 0x197F10; // type:func\nPostPuffcLoad__FP5PUFFC                           = 0x198090; // type:func\nPresetPuffcAccel__FP5PUFFCf                       = 0x1980B0; // type:func\nFUN_001982a0                                      = 0x1982A0; // type:func\nUpdatePuffcGoal__FP5PUFFCi                        = 0x198318; // type:func\nOnPuffcExitingSgs__FP5PUFFC3SGS                   = 0x1984B8; // type:func\nOnPuffcEnteringSgs__FP5PUFFC3SGSP4ASEG            = 0x198530; // type:func\nUpdatePuffcSgs__FP5PUFFC                          = 0x198570; // type:func\nHandlePuffcMessage__FP5PUFFC5MSGIDPv              = 0x1986E8; // type:func\nUpdatePuffc__FP5PUFFCf                            = 0x198760; // type:func\nFCanPuffcAttack__FP5PUFFC                         = 0x198858; // type:func\nFUN_00198860                                      = 0x198860; // type:func\nPostPuffbLoad__FP5PUFFB                           = 0x198920; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/pzo.c\n////////////////////////////////////////////////////////////////\nInitSprize__FP6SPRIZE                             = 0x198980; // type:func\nLoadSprizeFromBrx__FP6SPRIZEP18CBinaryInputStream = 0x1989B0; // type:func\nBindSprize__FP6SPRIZE                             = 0x198A88; // type:func\nPostSprizeLoad__FP6SPRIZE                         = 0x198B28; // type:func\nUpdateSprize__FP6SPRIZEf                          = 0x198BD8; // type:func\nCollectSprize__FP6SPRIZE                          = 0x198DA8; // type:func\nEmitSprizeExplosion__FP6SPRIZE                    = 0x198E58; // type:func\nPcsFromSprize__FP6SPRIZE                          = 0x198E98; // type:func\nAddSprizeAseg__FP6SPRIZE3OID                      = 0x198ED8; // type:func\nHandleSprizeMessage__FP6SPRIZE5MSGIDPv            = 0x198EF8; // type:func\nFIgnoreSprizeIntersection__FP6SPRIZEP2SO          = 0x198FB0; // type:func\nFUN_00199000                                      = 0x199000; // type:func\nInitScprize__FP7SCPRIZE                           = 0x199070; // type:func\nCloneScprize__FP7SCPRIZET0                        = 0x1990A8; // type:func\nPcsFromScprize__FP7SCPRIZE                        = 0x1990E0; // type:func\nCollectScprize__FP7SCPRIZE                        = 0x199138; // type:func\nLoadLockFromBrx__FP4LOCKP18CBinaryInputStream     = 0x199170; // type:func\nPostLockLoad__FP4LOCK                             = 0x1991A8; // type:func\nLoadLockgFromBrx__FP5LOCKGP18CBinaryInputStream   = 0x1991E0; // type:func\nPostLockgLoad__FP5LOCKG                           = 0x199218; // type:func\nSetLockgIndex__FP5LOCKGi                          = 0x199380; // type:func\nAddLockgLock__FP5LOCKG3OID                        = 0x199398; // type:func\nTriggerLockg__FP5LOCKG                            = 0x1993C0; // type:func\nInitClue__FP4CLUE                                 = 0x1993F0; // type:func\nLoadClueFromBrx__FP4CLUEP18CBinaryInputStream     = 0x199428; // type:func\nCloneClue__FP4CLUET0                              = 0x1994C8; // type:func\nPostClueLoad__FP4CLUE                             = 0x199500; // type:func\nUpdateClue                                        = 0x199698; // type:func\nOnClueSmack__FP4CLUE                              = 0x199850; // type:func\nCollectClue__FP4CLUE                              = 0x1999D0; // type:func\nBreakClue__FP4CLUE                                = 0x199AF0; // type:func\nCollectClueSilent__FP4CLUE                        = 0x199B18; // type:func\nFUN_00199c10                                      = 0x199C10; // type:func\nImpactClue__FP4CLUEi                              = 0x199C58; // type:func\nFAbsorbClueWkr__FP4CLUEP3WKR                      = 0x199C78; // type:func\nRenderClueAll__FP4CLUEP2CMP2RO                    = 0x199D08; // type:func\nCollectAllClues__Fi                               = 0x199F38; // type:func\nSetGrfvault__Fi                                   = 0x199FF0; // type:func\nFUN_0019a000                                      = 0x19A000; // type:func\nFUN_0019a088                                      = 0x19A088; // type:func\nFUN_0019a0f0                                      = 0x19A0F0; // type:func\nInitVault__FP5VAULT                               = 0x19A148; // type:func\nPostTmblLoad__FP4TMBL3OID                         = 0x19A178; // type:func\nPostVaultLoad__FP5VAULT                           = 0x19A1E0; // type:func\nOnVaultActive__FP5VAULTiP2PO                      = 0x19A520; // type:func\nUpdateVaultActive__FP5VAULTP3JOYf                 = 0x19A6A8; // type:func\nHandleVaultMessage__FP5VAULT5MSGIDPv              = 0x19AB78; // type:func\nAddVaultGoadDialog__FP5VAULT5GOADK3OID            = 0x19AD30; // type:func\nOpenVault__FP5VAULT                               = 0x19AD68; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/rail.c\n////////////////////////////////////////////////////////////////\nInitRail__FP4RAIL     = 0x19AF00; // type:func\nOnRailAdd__FP4RAIL    = 0x19AF38; // type:func\nOnRailRemove__FP4RAIL = 0x19AF70; // type:func\nPostLoadRail__FP4RAIL = 0x19AFA8; // type:func\nCloneRail__FP4RAILT0  = 0x19AFF0; // type:func\n\nD_0024C8C4 = 0x24C8C4; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/rat.c\n////////////////////////////////////////////////////////////////\nInitRat__FP3RAT                             = 0x19B038; // type:func\nLoadRatFromBrx__FP3RATP18CBinaryInputStream = 0x19B0A0; // type:func\nPostRatLoad__FP3RAT                         = 0x19B188; // type:func\nOnRatAdd__FP3RAT                            = 0x19B1E0; // type:func\nOnRatRemove__FP3RAT                         = 0x19B218; // type:func\nCloneRat__FP3RATT0                          = 0x19B250; // type:func\nPresetRatAccel__FP3RATf                     = 0x19B298; // type:func\nUpdateRat__FP3RATf                          = 0x19B378; // type:func\nAdjustRatNewXp__FP3RATP2XPi                 = 0x19BB10; // type:func\nAdjustRatXpVelocity__FP3RATP2XPi            = 0x19BB90; // type:func\nRenderRatAll__FP3RATP2CMP2RO                = 0x19BC40; // type:func\nFAbsorbRatWkr__FP3RATP3WKR                  = 0x19BE08; // type:func\nChooseRatFleeTarget__FP3RAT                 = 0x19BE80; // type:func\nHideRat__FP3RATi                            = 0x19C068; // type:func\nSetRatRats__FP3RAT4RATS                     = 0x19C1C0; // type:func\nOnRatholeAdd__FP7RATHOLE                    = 0x19C3D0; // type:func\nOnRatholeRemove__FP7RATHOLE                 = 0x19C408; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/rchm.c\n////////////////////////////////////////////////////////////////\nInitRchm__FP4RCHM                                   = 0x19C440; // type:func\nLoadRchmFromBrx__FP4RCHMP18CBinaryInputStream       = 0x19C470; // type:func\nPostRchmLoad__FP4RCHM                               = 0x19C728; // type:func\nReblendRchm__FP4RCHMP3TWRP6VECTOR                   = 0x19C9C8; // type:func\nBuildRchmCoefficients__FP4RCHMfffPf                 = 0x19CC10; // type:func\nConvertRchmIposToRclIoLhub__FP4RCHMiPfN22           = 0x19CD90; // type:func\nSetRchmNaturalCoefficients__FP4RCHMfff              = 0x19CE28; // type:func\nSetRchmCenterCoefficients__FP4RCHMfff               = 0x19CE38; // type:func\nPredictRchmTargetPos__FP4RCHMP6TARGETfP6VECTOR      = 0x19CE50; // type:func\nPredictRchmTargetLocalPos__FP4RCHMP6TARGETfP6VECTOR = 0x19CEC0; // type:func\nPtwrMapRchmSafe__FP4RCHMP3BSPP6VECTOR               = 0x19CF68; // type:func\nFindRchmClosestPoint__FP4RCHMP6VECTORT1PP3TWRPf     = 0x19D0E0; // type:func\nTrackJtTarget__FP2JTP4RCHMP6TARGET                  = 0x19D2A8; // type:func\nTrackJtPipe__FP2JTP4RCHMP4PIPEPf                    = 0x19D338; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/render.c\n////////////////////////////////////////////////////////////////\nSubmitRpl__FP3RPL                 = 0x19D410; // type:func\nNCmpPrplReverseZ__FPP3RPLT0       = 0x19D468; // type:func\nCprplPartitionArpl__FiP3RPLPP3RPL = 0x19D4B0; // type:func\nRenderSw__FP2SWP2CM               = 0x19D6C0; // type:func\nEnsureRenderGlobals__Fv           = 0x19D860; // type:func\nEnsureCameraGlobals__Fv           = 0x19D930; // type:func\nEnsureScreenCleared__Fv           = 0x19D968; // type:func\nSetupRpDynamicTexture__FP3RPL     = 0x19DA30; // type:func\nSetupRpBackground__FP3RPL         = 0x19DA60; // type:func\nSetupRpBlotContext__FP3RPL        = 0x19DAD8; // type:func\nSetupRpGlob__FP3RPL               = 0x19DB20; // type:func\nSetupRpBlip__FP3RPL               = 0x19DB68; // type:func\nSetupRpWorldMap__FP3RPL           = 0x19DBB0; // type:func\nDrawSw__FP2SWP2CM                 = 0x19DC98; // type:func\nFillScreenRect__FiiiiffffP4GIFS   = 0x19DDA0; // type:func\nStartupRender__Fv                 = 0x19DF48; // type:func\n\ns_fFBCleared     = 0x604780; // size:0x4\ns_fZBCleared     = 0x604784; // size:0x4\ns_fCameraGlobals = 0x604788; // size:0x4\ns_fRenderGlobals = 0x60478c; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/rip.c\n////////////////////////////////////////////////////////////////\nPripgNew__FP2SW5RIPGT                          = 0x19E040; // type:func\nInitRipg__FP4RIPG                              = 0x19E0B8; // type:func\nSetRipgEmitb__FP4RIPGP5EMITB                   = 0x19E158; // type:func\nOnRipgRemove__FP4RIPG                          = 0x19E168; // type:func\nProjectRipgTransform__FP4RIPGfi                = 0x19E220; // type:func\nUpdateRipgBounds__FP4RIPG                      = 0x19E418; // type:func\nFUN_0019e420                                   = 0x19E420; // type:func\nBounceRipgRips__FP4RIPG                        = 0x19E558; // type:func\nRenderRipgSelf__FP4RIPGP2CMP2RO                = 0x19E848; // type:func\nPvtripFromRipt__F4RIPT                         = 0x19E908; // type:func\nPripNewRipg__F4RIPTP4RIPG                      = 0x19EA78; // type:func\nInitRip__FP3RIPP6VECTORfP2SO                   = 0x19EB28; // type:func\nRemoveRip__FP3RIP                              = 0x19EBE8; // type:func\nAddRipRef__FP3RIP                              = 0x19EC20; // type:func\nReleaseRip__FP3RIP                             = 0x19EC30; // type:func\nTouchRip__FP3RIPi                              = 0x19ECE0; // type:func\nForceRipFade__FP3RIPf                          = 0x19ED00; // type:func\nFBounceRip__FP3RIPP2SOP6VECTORT2               = 0x19ED58; // type:func\nProjectRipTransform__FP3RIPf                   = 0x19F390; // type:func\nUpdateRip__FP3RIPf                             = 0x19F560; // type:func\nFRenderRipPosMat__FP3RIPP2CMP6VECTORP7MATRIX3  = 0x19F620; // type:func\nRenderRip__FP3RIPP2CM                          = 0x19F858; // type:func\nSubscribeRipObject__FP3RIPP2LO                 = 0x19F8E8; // type:func\nSubscribeRipStruct__FP3RIPPFPv5MSGIDPv_vPv     = 0x19F918; // type:func\nUnsubscribeRipStruct__FP3RIPPFPv5MSGIDPv_vPv   = 0x19F950; // type:func\nInitDroplet__FP7DROPLETP6VECTORfP2SO           = 0x19F988; // type:func\nTouchDroplet__FP7DROPLETi                      = 0x19F9D0; // type:func\nInitBublet__FP6BUBLETP6VECTORfP2SO             = 0x19FA98; // type:func\nProjectBubletTransform__FP6BUBLETf             = 0x19FB08; // type:func\nTouchBublet__FP6BUBLETi                        = 0x19FCE8; // type:func\nInitRipple__FP6RIPPLEP6VECTORfP2SO             = 0x19FD08; // type:func\nInitPuff__FP4PUFFP6VECTORfP2SO                 = 0x19FD70; // type:func\nInitDablet__FP6DABLETP6VECTORfP2SO             = 0x19FDC0; // type:func\nInitFlake__FP5FLAKEP6VECTORfP2SO               = 0x19FE10; // type:func\nUpdateFlake__FP5FLAKEf                         = 0x19FE50; // type:func\nRenderFlake__FP5FLAKEP2CM                      = 0x19FF20; // type:func\nTouchFlake__FP5FLAKEi                          = 0x1A0020; // type:func\nInitSpark__FP5SPARKP6VECTORfP2SO               = 0x1A0040; // type:func\nRenderSpark__FP5SPARKP2CM                      = 0x1A00A0; // type:func\nInitBurst__FP5BURSTP6VECTORfP2SO               = 0x1A01B8; // type:func\nInitTrail__FP5TRAILP6VECTORfP2SO               = 0x1A0258; // type:func\nOnTrailRemove__FP5TRAIL                        = 0x1A0318; // type:func\nSetTrailTrls__FP5TRAIL4TRLSPv                  = 0x1A0338; // type:func\nDetachTrail__FP5TRAIL                          = 0x1A04A0; // type:func\nProjectTrailTransform__FP5TRAILf               = 0x1A05D8; // type:func\nRenderTrail__FP5TRAILP2CM                      = 0x1A0758; // type:func\nHandleTrailMessage__FP5TRAIL5MSGIDPv           = 0x1A0950; // type:func\nInitFireball__FP8FIREBALLP6VECTORfP2SO         = 0x1A09C0; // type:func\nUpdateFireball__FP8FIREBALLf                   = 0x1A0A78; // type:func\nInitSmokecloud__FP10SMOKECLOUDP6VECTORfP2SO    = 0x1A0B20; // type:func\nInitSmoketrail__FP10SMOKETRAILP6VECTORfP2SO    = 0x1A0BA0; // type:func\nInitDebris__FP6DEBRISP6VECTORfP2SO             = 0x1A0C50; // type:func\nInitSmack__FP5SMACKP6VECTORfP2SO               = 0x1A0C98; // type:func\nProjectSmackTransform__FP5SMACKf               = 0x1A0D60; // type:func\nRenderSmack__FP5SMACKP2CM                      = 0x1A0DF0; // type:func\nUpdateSmack__FP5SMACKf                         = 0x1A0F88; // type:func\nInitOrbit__FP5ORBITP6VECTORfP2SO               = 0x1A0FE8; // type:func\njunk_001A1028                                  = 0x1A1028; // type:func\nProjectOrbitTransform__FP5ORBITf               = 0x1A1030; // type:func\nUpdateOrbit__FP5ORBITf                         = 0x1A11C0; // type:func\nRenderOrbit__FP5ORBITP2CM                      = 0x1A1398; // type:func\nInitRay__FP3RAYP6VECTORfP2SO                   = 0x1A1410; // type:func\nInitRose__FP4ROSEP6VECTORfP2SO                 = 0x1A1458; // type:func\nProjectRoseTransform__FP4ROSEf                 = 0x1A1498; // type:func\nUpdateRose__FP4ROSEf                           = 0x1A14A0; // type:func\nRenderRose__FP4ROSEP2CM                        = 0x1A15D8; // type:func\nSetRoseRoses__FP4ROSE5ROSES                    = 0x1A1DF0; // type:func\nSgnCmpHp__FPCvT0                               = 0x1A1F18; // type:func\nChpBuildConvexHullScreen__FP6VECTORiP2HP       = 0x1A1F40; // type:func\nChpBuildConvexHullXY__FP7MATRIX4iP2HP          = 0x1A2070; // type:func\nPostFlyingEmit__FP6FLYINGP5EMITB               = 0x1A22C8; // type:func\nRenderFlying__FP6FLYINGP2CM                    = 0x1A22E0; // type:func\nCreateStuck__FP3RIPP3ALOP2SOP6VECTORT3PP5STUCK = 0x1A2380; // type:func\nFBounceFlying__FP6FLYINGP2SOP6VECTORT2         = 0x1A25F0; // type:func\nUpdateStuck__FP5STUCKf                         = 0x1A26B0; // type:func\nRenderStuck__FP5STUCKP2CM                      = 0x1A26F8; // type:func\nPostLeafEmit__FP4LEAFP5EMITB                   = 0x1A2770; // type:func\nProjectLeafTransform__FP4LEAFf                 = 0x1A2830; // type:func\nFBounceLeaf__FP4LEAFP2SOP6VECTORT2             = 0x1A2A68; // type:func\nFFilterFlameObjects__FPvP2SO                   = 0x1A2B18; // type:func\nPostFlameEmit__FP5FLAMEP5EMITB                 = 0x1A2B48; // type:func\nPostBulletEmit__FP6BULLETP5EMITB               = 0x1A2D30; // type:func\nRenderBullet__FP6BULLETP2CM                    = 0x1A2D88; // type:func\nFBounceBullet__FP6BULLETP2SOP6VECTORT2         = 0x1A2E68; // type:func\nPostShrapnelEmit__FP8SHRAPNELP5EMITB           = 0x1A3008; // type:func\nFBounceShrapnel__FP8SHRAPNELP2SOP6VECTORT2     = 0x1A3128; // type:func\nRenderShrapnel__FP8SHRAPNELP2CM                = 0x1A31A0; // type:func\nInitGlint__FP5GLINTP6VECTORfP2SO               = 0x1A31F0; // type:func\nRenderGlint__FP5GLINTP2CM                      = 0x1A3250; // type:func\nInitMatch__FP5MATCHP6VECTORfP2SO               = 0x1A3598; // type:func\nLaunchMatch__FP5MATCH                          = 0x1A35F0; // type:func\nProjectMatchTransform__FP5MATCHf               = 0x1A3730; // type:func\nUpdateMatch__FP5MATCHf                         = 0x1A38F0; // type:func\nRenderMatch__FP5MATCHP2CM                      = 0x1A3990; // type:func\nPostRemitEmit__FP5REMITP5EMITB                 = 0x1A39C8; // type:func\nUpdateRemit__FP5REMITf                         = 0x1A3A18; // type:func\njunk_001A3AC8                                  = 0x1A3AC8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/rog.c\n////////////////////////////////////////////////////////////////\nInitRov__FP3ROV                               = 0x1A3AE0; // type:func\nLoadRovFromBrx__FP3ROVP18CBinaryInputStream   = 0x1A3B20; // type:func\nPostRovLoad__FP3ROV                           = 0x1A3B58; // type:func\nUpdateRovActive__FP3ROVP3JOYf                 = 0x1A3C40; // type:func\nUpdateRov__FP3ROVf                            = 0x1A3D40; // type:func\nReadRovJoystick__FP3ROVP3JOY                  = 0x1A3F40; // type:func\nRovsNextRov__FP3ROV                           = 0x1A3FE0; // type:func\nSetRovRovs__FP3ROV4ROVS                       = 0x1A4070; // type:func\nRovtsNextRov__FP3ROV                          = 0x1A4258; // type:func\nSetRovRovts__FP3ROV5ROVTS                     = 0x1A42C8; // type:func\nHandleRovMessage__FP3ROV5MSGIDPv              = 0x1A43C8; // type:func\nPresetRovAccel__FP3ROVf                       = 0x1A44E8; // type:func\nAdjustRovXpVelocity__FP3ROVP2XPi              = 0x1A4538; // type:func\nAdjustRovNewXp__FP3ROVP2XPi                   = 0x1A45B8; // type:func\nPropagateRovForce__FP3ROViP2XPiP2DZP2FX       = 0x1A4610; // type:func\nFIsRovSoundBase__FP3ROV                       = 0x1A4710; // type:func\nInitRob__FP3ROB                               = 0x1A4718; // type:func\nSetRobCollectible__FP3ROB3OID                 = 0x1A4858; // type:func\nSetRobHarvester__FP3ROB3OID                   = 0x1A4860; // type:func\nSetRobVehicle__FP3ROB3OID                     = 0x1A4868; // type:func\nSetRobPrize__FP3ROB3OID                       = 0x1A4870; // type:func\nAddRobSpawnTunnel__FP3ROB3OID                 = 0x1A4878; // type:func\nRobkCur__Fv                                   = 0x1A4898; // type:func\nBindRob__FP3ROB                               = 0x1A48C0; // type:func\nPostRobLoad__FP3ROB                           = 0x1A4B30; // type:func\nUpdateRob__FP3ROBf                            = 0x1A4C48; // type:func\nFUN_001a4d60                                  = 0x1A4D60; // type:func\nRobsNextRob__FP3ROB                           = 0x1A4DC0; // type:func\nSetRobRobs__FP3ROB4ROBS                       = 0x1A4EF0; // type:func\nAddRobRoc__FP3ROB                             = 0x1A5120; // type:func\nAddRobRoh__FP3ROB                             = 0x1A54F8; // type:func\nAdjustRobDifficulty__FP3ROBf                  = 0x1A5760; // type:func\nDestroyedRobRoc__FP3ROBP3ROC                  = 0x1A5B28; // type:func\nSpawnedRobRoh__FP3ROBP3ROH                    = 0x1A5C38; // type:func\nGrabbedRobRoh__FP3ROBP3ROH                    = 0x1A5C90; // type:func\nDroppedRobRoh__FP3ROBP3ROH                    = 0x1A5D50; // type:func\nReturnedRobRoh__FP3ROBP3ROH                   = 0x1A5DD8; // type:func\nExitedRobRoh__FP3ROBP3ROH                     = 0x1A5DF8; // type:func\nKilledRobRoh__FP3ROBP3ROH                     = 0x1A5F78; // type:func\nFChooseRobRoc__FP3ROBP3ROH                    = 0x1A6090; // type:func\nTakeRobRoc__FP3ROBP3ROHP3ROC                  = 0x1A6168; // type:func\nFChooseRobRoh__FP3ROBP3ROC                    = 0x1A6238; // type:func\nFChooseRobReturnPoint__FP3ROBP3ROH            = 0x1A6328; // type:func\nChooseRobWanderLocation__FP3ROBP3ROH          = 0x1A63F8; // type:func\nProddCurRob__FP3ROB4ENSK                      = 0x1A6480; // type:func\nInitRoh__FP3ROH                               = 0x1A6498; // type:func\nLoadRohFromBrx__FP3ROHP18CBinaryInputStream   = 0x1A64F8; // type:func\nCloneRoh__FP3ROHT0                            = 0x1A6540; // type:func\nPostRohLoad__FP3ROH                           = 0x1A6588; // type:func\nUpdateRoh__FP3ROHf                            = 0x1A65C8; // type:func\nMoveRohToTarget__FP3ROHP6VECTORi              = 0x1A6788; // type:func\nRohsNextRoh__FP3ROH                           = 0x1A69F8; // type:func\nSetRohRohs__FP3ROH4ROHS                       = 0x1A6BE0; // type:func\nFAbsorbRohWkr__FP3ROHP3WKR                    = 0x1A6DE0; // type:func\nProcContactRoh__FP3ROH                        = 0x1A6F28; // type:func\nInitRoc__FP3ROC                               = 0x1A6F88; // type:func\nLoadRocFromBrx__FP3ROCP18CBinaryInputStream   = 0x1A7008; // type:func\nCloneRoc__FP3ROCT0                            = 0x1A7050; // type:func\nPostRocLoad__FP3ROC                           = 0x1A7098; // type:func\nUpdateRoc__FP3ROCf                            = 0x1A7128; // type:func\nPresetRocAccel__FP3ROCf                       = 0x1A7230; // type:func\nAdjustRocNewXp__FP3ROCP2XPi                   = 0x1A7290; // type:func\nFAbsorbRocWkr__FP3ROCP3WKR                    = 0x1A72B0; // type:func\nRocsNextRoc__FP3ROC                           = 0x1A7420; // type:func\nSetRocRocs__FP3ROC4ROCS                       = 0x1A7480; // type:func\nInitRost__FP4ROST                             = 0x1A7520; // type:func\nLoadRostFromBrx__FP4ROSTP18CBinaryInputStream = 0x1A7550; // type:func\nCloneRost__FP4ROSTT0                          = 0x1A7588; // type:func\nPostRostLoad__FP4ROST                         = 0x1A75D0; // type:func\nUpdateRost__FP4ROSTf                          = 0x1A7648; // type:func\nRostsNextRost__FP4ROST                        = 0x1A7698; // type:func\nSetRostRosts__FP4ROST5ROSTS                   = 0x1A76A0; // type:func\nInitRop__FP3ROP                               = 0x1A7708; // type:func\nLoadRopFromBrx__FP3ROPP18CBinaryInputStream   = 0x1A7750; // type:func\nPostRopLoad__FP3ROP                           = 0x1A7798; // type:func\nUpdateRop__FP3ROPf                            = 0x1A7800; // type:func\nSetRopRops__FP3ROP4ROPS                       = 0x1A7998; // type:func\nRopsNextRop__FP3ROP                           = 0x1A7AA0; // type:func\n\ns_asnipLoadRov = 0x26B778;\n\n\n////////////////////////////////////////////////////////////////\n// P2/rumble.c\n////////////////////////////////////////////////////////////////\nInitRumble__FP6RUMBLEii                 = 0x1A7B20; // type:func\nUpdateRumble__FP6RUMBLE                 = 0x1A7B88; // type:func\nTriggerRumbleRumk__FP6RUMBLE4RUMKf      = 0x1A7CE8; // type:func\nTriggerRumbleRumpat__FP6RUMBLEP6RUMPATf = 0x1A7D18; // type:func\nSetRumbleRums__FP6RUMBLE4RUMS           = 0x1A7D98; // type:func\nStopRumbleActuators__FP6RUMBLE          = 0x1A7E40; // type:func\nFUN_001A7E70__Fv                        = 0x1A7E70; // type:func\nFUN_001A7E90                            = 0x1A7E90; // type:func\nFUN_001A7EE8                            = 0x1A7EE8; // type:func\nFUN_001A7F50                            = 0x1A7F50; // type:func\n\nDAT_0026c3dc = 0x26C3DC;\n\n\n////////////////////////////////////////////////////////////////\n// P2/rwm.c\n////////////////////////////////////////////////////////////////\nInitRwm__FP3RWM                         = 0x1A7FE8; // type:func\nOnRwmRemove                             = 0x1A80E0; // type:func\nFUN_001a8110                            = 0x1A8110; // type:func\nFUN_001a8150                            = 0x1A8150; // type:func\nInitRwmCallback__FP3RWM5MSGIDPv         = 0x1A8208; // type:func\nFUN_001a84c8                            = 0x1A84C8; // type:func\nPostRwmLoad__FP3RWM                     = 0x1A8590; // type:func\nFUN_001a86f8                            = 0x1A86F8; // type:func\nPrwcFindRwm__FP3RWM3OID                 = 0x1A8718; // type:func\nEnableRwmRwc__FP3RWM3OID                = 0x1A8778; // type:func\nDisableRwmRwc__FP3RWM3OID               = 0x1A87A8; // type:func\nResizeRwmRwc__FP3RWM3OIDi               = 0x1A87E0; // type:func\nFIsRwmAmmo__FP3RWMP2SO                  = 0x1A8820; // type:func\nFAvailableRwmAmmo__FP3RWMP2SO           = 0x1A88A0; // type:func\nCycleRwmCache__FP3RWM                   = 0x1A89E8; // type:func\nReloadRwm__FP3RWM                       = 0x1A8AF8; // type:func\nFEnsureRwmLoaded__FP3RWM                = 0x1A8C50; // type:func\nFFireRwm__FP3RWMi                       = 0x1A8C90; // type:func\nFUN_001a93c8                            = 0x1A93C8; // type:func\nClearRwmFireInfo__FP3RWM                = 0x1A93E8; // type:func\nClearRwmTargetInfo__FP3RWM              = 0x1A9438; // type:func\nClearRwmAimConstraints__FP3RWM          = 0x1A9498; // type:func\nGetRwfiPosMat__FP4RWFIP6VECTORP7MATRIX3 = 0x1A94C0; // type:func\nGetRwtiPos__FP4RWTIP6VECTORT1           = 0x1A95D0; // type:func\nGetRwacPan__FP4RWACPf                   = 0x1A97C8; // type:func\nGetRwacTilt__FP4RWACPf                  = 0x1A9868; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/sb.c\n////////////////////////////////////////////////////////////////\nPostSbgLoad__FP3SBG                = 0x1A98F8; // type:func\nFUN_001a9928__FP3SBG               = 0x1A9928; // type:func\nUpdateSbgGoal__FP3SBGi             = 0x1A9960; // type:func\nUpdateSbgSgs__FP3SBG               = 0x1A99B8; // type:func\nOnSbgEnteringSgs__FP3SBG3SGSP4ASEG = 0x1A99F8; // type:func\nUpdateSbg__FP3SBGf                 = 0x1A9A40; // type:func\nFUN_001a9a98                       = 0x1A9A98; // type:func\nFAbsorbSbgWkr__FP3SBGP3WKR         = 0x1A9AE8; // type:func\nFUN_001a9c58                       = 0x1A9C58; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/screen.c\n////////////////////////////////////////////////////////////////\nStartupScreen__Fv = 0x1A9C68; // type:func\nPostBlotsLoad__Fv = 0x1A9F78; // type:func\nUpdateBlots__Fv = 0x1A9FD0; // type:func\nForceHideBlots__Fv = 0x1AA060; // type:func\nResetBlots__Fv = 0x1AA0C0; // type:func\nRenderBlots__Fv = 0x1AA110; // type:func\nDrawBlots__Fv = 0x1AA178; // type:func\nInitBlot__FP4BLOT5BLOTK = 0x1AA1F0; // type:func\nPostBlotLoad__FP4BLOT = 0x1AA268; // type:func\nUpdateBlot__FP4BLOT = 0x1AA298; // type:func\nSetBlotAchzDraw__FP4BLOTPc = 0x1AA4F0; // type:func\nSetBlotRgba__FP4BLOTUi = 0x1AA5A0; // type:func\nSetBlotFontScale__FfP4BLOT = 0x1AA788; // type:func\nDrawBlot__FP4BLOT = 0x1AA790; // type:func\njunk_001AA890 = 0x1AA890; // type:func\nDtAppearBlot__FP4BLOT = 0x1AA898; // type:func\nDtVisibleBlot__FP4BLOT = 0x1AA8A0; // type:func\nDtDisappearBlot__FP4BLOT = 0x1AA8A8; // type:func\nSetBlotDtAppear__FP4BLOTf = 0x1AA8B0; // type:func\nSetBlotDtVisible__FP4BLOTf = 0x1AA8B8; // type:func\nSetBlotDtDisappear__FP4BLOTf = 0x1AA8C0; // type:func\nOnBlotReset__FP4BLOT = 0x1AA8C8; // type:func\nShowBlot__FP4BLOT = 0x1AA8F0; // type:func\nHideBlot__FP4BLOT = 0x1AA958; // type:func\nSetBlotBlots__FP4BLOT5BLOTS = 0x1AA998; // type:func\nFIncludeBlotForPeg__FP4BLOTT0 = 0x1AAAC8; // type:func\nResizeBlot__FP4BLOTff = 0x1AAB20; // type:func\nRepositionBlot__FP4BLOT = 0x1AAB60; // type:func\nRepositionBlotDependents__FP4BLOT = 0x1AAEC0; // type:func\nSetBlotClock__FP4BLOTPf = 0x1AAF58; // type:func\nPostCtrLoad__FP3CTR = 0x1AAF88; // type:func\nUpdateCtr__FP3CTR = 0x1AB058; // type:func\nDrawCtr__FP3CTR = 0x1AB198; // type:func\nRebuildCtrAchzDraw__FP3CTR = 0x1AB2B8; // type:func\nDtVisibleCtr__FP3CTR = 0x1AB5D8; // type:func\nFUN_001ab600 = 0x1AB600; // type:func\nUpdateTimer__FP5TIMER = 0x1AB660; // type:func\nDrawTimer__FP5TIMER = 0x1AB710; // type:func\nSetTimer__FP5TIMERf = 0x1AB890; // type:func\nSetTimerSpeed__FP5TIMERf = 0x1AB920; // type:func\nSetTimerExpire__FP5TIMERfPv = 0x1AB928; // type:func\nStartTimer__FP5TIMER = 0x1AB938; // type:func\nStopTimer__FP5TIMER = 0x1AB958; // type:func\nRebuildTimerAchzDraw__FP5TIMERf = 0x1AB980; // type:func\nSetTimerTimers__FP5TIMER6TIMERS = 0x1ABE20; // type:func\nDtVisibleTrunkctr__FP8TRUNKCTR = 0x1ABE40; // type:func\nDtVisibleCrusherctr__FP10CRUSHERCTR = 0x1ABE50; // type:func\nFUN_001ABE60__Fv = 0x1ABE60; // type:func\nFUN_001abe70 = 0x1ABE70; // type:func\nFUN_001ac060 = 0x1AC060; // type:func\nFUN_001ac0e8 = 0x1AC0E8; // type:func\nPostNoteLoad__FP4NOTE = 0x1AC5C0; // type:func\nSetNoteAchzDraw__FP4NOTEPc = 0x1AC638; // type:func\nDrawNote__FP4NOTE = 0x1AC700; // type:func\nFUN_001ac888 = 0x1AC888; // type:func\nFUN_001ac910 = 0x1AC910; // type:func\nFUN_001ac990 = 0x1AC990; // type:func\nFUN_001ac9e0 = 0x1AC9E0; // type:func\nFUN_001aca30 = 0x1ACA30; // type:func\nFUN_001aca68 = 0x1ACA68; // type:func\nDrawTitle__FP5TITLE = 0x1ACAA8; // type:func\nPostTotalsLoad__FP6TOTALS = 0x1ACDA0; // type:func\nFUN_001ace38 = 0x1ACE38; // type:func\nFUN_001acee0 = 0x1ACEE0; // type:func\nrender_level_info_from_id = 0x1AD088; // type:func\nrender_level_info = 0x1AD0D0; // type:func\nrender_hideout_world_info = 0x1AD1E8; // type:func\nSetTotalsBlots__FP6TOTALS5BLOTS = 0x1AD320; // type:func\nShowTotalsQMARK = 0x1AD378; // type:func\nHideTotalsQMARK = 0x1AD3B0; // type:func\nDrawTotals__FP6TOTALS = 0x1AD3F0; // type:func\nFUN_001ad6a8 = 0x1AD6A8; // type:func\nFUN_001ad718 = 0x1AD718; // type:func\nFUN_001ad7b0 = 0x1AD7B0; // type:func\nFUN_001ad940 = 0x1AD940; // type:func\nFUN_001ad970 = 0x1AD970; // type:func\nDrawLetterbox__FP9LETTERBOX = 0x1ADB00; // type:func\nFUN_001adc60 = 0x1ADC60; // type:func\nDrawLogo__FP4LOGO = 0x1ADD28; // type:func\nFUN_001adf28 = 0x1ADF28; // type:func\nFUN_001adff0 = 0x1ADFF0; // type:func\nFUN_001ae130 = 0x1AE130; // type:func\nUpdateAttract__FP7ATTRACT = 0x1AE178; // type:func\nDrawAttract__FP7ATTRACT = 0x1AE220; // type:func\nDrawLineScreen__FUiUiUiUiUiUiG4RGBAi = 0x1AE3B8; // type:func\nFUN_001ae510 = 0x1AE510; // type:func\nFUN_001ae5e0 = 0x1AE5E0; // type:func\nFUN_001ae758 = 0x1AE758; // type:func\nFUN_001ae7f8 = 0x1AE7F8; // type:func\nFUN_001ae820 = 0x1AE820; // type:func\nFUN_001aea08 = 0x1AEA08; // type:func\nFUN_001aea70 = 0x1AEA70; // type:func\njunk_001aec80 = 0x1AEC80; // type:func\nFUN_001aec90 = 0x1AEC90; // type:func\n\n// Global blots\ng_lifectr = 0x26c6c8; // size:0x280\ng_cluectr = 0x26c948; // size:0x280\ng_keyctr = 0x26cbc8; // size:0x280\ng_coinctr = 0x26ce48; // size:0x280\ng_unkblot0 = 0x26d0c8; // size:0x280\ng_unkblot1 = 0x26d348; // size:0x280\ng_unkblot2 = 0x26d5c8; // size:0x280\ng_unkblot3 = 0x26d848; // size:0x280\ng_unkblot4 = 0x26dac8; // size:0x280\ng_unkblot5 = 0x26dd48; // size:0x280\ng_unkblot6 = 0x26dfc8; // size:0x280\ng_unkblot7 = 0x26e248; // size:0x280\ng_unkblot8 = 0x26e4e0; // size:0x280\ng_unkblot9 = 0x26e760; // size:0x280\ng_note = 0x26e9f8; // size:0x280\ng_unkblot11 = 0x26eed0; // size:0x268\ng_totals = 0x26f138; // size:0x18\n\n// Maybe doesn't belong here?\ng_binoc = 0x2701F8; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/sensor.c\n////////////////////////////////////////////////////////////////\nInitSensor__FP6SENSOR                           = 0x1AECB0; // type:func\nSetSensorAlarm__FP6SENSORP5ALARM                = 0x1AECE0; // type:func\nSetSensorSensors__FP6SENSOR7SENSORS             = 0x1AECE8; // type:func\nFCheckSensorObject__FP6SENSORP2SO               = 0x1AED78; // type:func\nFIgnoreSensorObject__FP6SENSORP2SO              = 0x1AEE50; // type:func\nFOnlySensorTriggerObject__FP6SENSORP2SO         = 0x1AEF00; // type:func\nPauseSensor__FP6SENSOR                          = 0x1AEF68; // type:func\nUpdateSensor__FP6SENSORf                        = 0x1AEFA0; // type:func\nAddSensorTriggerObject__FP6SENSOR3OID           = 0x1AF000; // type:func\nAddSensorNoTriggerObject__FP6SENSOR3OID         = 0x1AF028; // type:func\nAddSensorTriggerClass__FP6SENSOR3CID            = 0x1AF050; // type:func\nAddSensorNoTriggerClass__FP6SENSOR3CID          = 0x1AF078; // type:func\nInitLasen__FP5LASEN                             = 0x1AF0A0; // type:func\nLoadLasenFromBrx__FP5LASENP18CBinaryInputStream = 0x1AF0D0; // type:func\nBindLasen__FP5LASEN                             = 0x1AF108; // type:func\nPostLasenLoad__FP5LASEN                         = 0x1AF3B8; // type:func\nUpdateBusyLasenSenseTimes__Fv                   = 0x1AF508; // type:func\nUpdateLasen__FP5LASENf                          = 0x1AF5C8; // type:func\nFreezeLasen__FP5LASENi                          = 0x1AF7A8; // type:func\nRenderLasenSelf__FP5LASENP2CMP2RO               = 0x1AF820; // type:func\nFUN_001afaf8__FP6SENSORP2SO                     = 0x1AFAF8; // type:func\nSenseLasen__FP5LASENP7SENSORS                   = 0x1AFBB0; // type:func\nEnableLasen__FP5LASEN5SENSM                     = 0x1B00E8; // type:func\nDisableLasen__FP5LASEN                          = 0x1B0120; // type:func\nOnLasenAlarmTriggered__FP5LASEN                 = 0x1B0160; // type:func\nSetLasenSensors__FP5LASEN7SENSORS               = 0x1B01B0; // type:func\nSCalcLasenShapeExtent__FP5LASENP5LBEAM          = 0x1B0360; // type:func\nRetractLasen__FP5LASENf                         = 0x1B0470; // type:func\nExtendLasen__FP5LASENf                          = 0x1B0488; // type:func\nInitCamsen__FP6CAMSEN                           = 0x1B04A0; // type:func\nPostCamsenLoad__FP6CAMSEN                       = 0x1B04D0; // type:func\nUpdateCamsen__FP6CAMSENf                        = 0x1B0578; // type:func\nRenderCamsenSelf__FP6CAMSENP2CMP2RO             = 0x1B0838; // type:func\nFIgnoreCamsenIntersection__FP6CAMSENP2SO        = 0x1B0BD8; // type:func\nFFilterCamsen__FPvP2SO                          = 0x1B0BE0; // type:func\nSenseCamsen__FP6CAMSENP7SENSORS                 = 0x1B0C68; // type:func\nEnableCamsen__FP6CAMSEN5SENSM                   = 0x1B0EA8; // type:func\nDisableCamsen__FP6CAMSEN                        = 0x1B0EE0; // type:func\nOnCamsenAlarmTriggered__FP6CAMSEN               = 0x1B0F70; // type:func\nSetCamsenSensors__FP6CAMSEN7SENSORS             = 0x1B0FC0; // type:func\nSetCamsenCsdts__FP6CAMSEN5CSDTS                 = 0x1B1070; // type:func\nInitPrsen__FP5PRSEN                             = 0x1B1158; // type:func\nPostPrsenLoad__FP5PRSEN                         = 0x1B11A0; // type:func\nUpdatePrsen__FP5PRSENf                          = 0x1B1238; // type:func\nSensePrsen__FP5PRSENP7SENSORS                   = 0x1B1438; // type:func\nEnablePrsen__FP5PRSEN5SENSM                     = 0x1B15D0; // type:func\nDisablePrsen__FP5PRSEN                          = 0x1B1608; // type:func\nOnPrsenAlarmTriggered__FP5PRSEN                 = 0x1B1698; // type:func\nSetPrsenSensors__FP5PRSEN7SENSORS               = 0x1B1710; // type:func\nUpdatePrsenLoopShader__FP5PRSEN                 = 0x1B1898; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/shadow.c\n////////////////////////////////////////////////////////////////\nInitShadow__FP6SHADOW                       = 0x1B1AC8; // type:func\nPostShadowLoad__FP6SHADOW                   = 0x1B1B38; // type:func\nInvalidateShadowVifs__FP6SHADOW             = 0x1B1BF0; // type:func\nRebuildShadowRegion__FP6SHADOW              = 0x1B1BF8; // type:func\nSetShadowShader__FP6SHADOW3OID              = 0x1B1CF8; // type:func\nFShadowRadiusSet__FP6SHADOW                 = 0x1B1D38; // type:func\nSetShadowNearRadius__FP6SHADOWf             = 0x1B1D70; // type:func\nSetShadowFarRadius__FP6SHADOWf              = 0x1B1DA8; // type:func\nSetShadowCastPosition__FP6SHADOWP6VECTOR    = 0x1B1DE0; // type:func\nSetShadowCastNormal__FP6SHADOWP6VECTOR      = 0x1B1EC8; // type:func\nSetShadowNearCast__FP6SHADOWf               = 0x1B1FB0; // type:func\nSetShadowFarCast__FP6SHADOWf                = 0x1B1FE0; // type:func\nSetShadowConeAngle__FP6SHADOWf              = 0x1B2010; // type:func\nSetShadowFrustrumUp__FP6SHADOWP6VECTOR      = 0x1B2068; // type:func\nFShadowValid__FP6SHADOWi                    = 0x1B2090; // type:func\nFFilterFastShadows__FPvP2SO                 = 0x1B2118; // type:func\nUpdateShadow__FP6SHADOWf                    = 0x1B2140; // type:func\nRebuildShadowVifs__FP6SHADOW                = 0x1B2358; // type:func\nDrawShadow__FP6SHADOW                       = 0x1B2640; // type:func\nFShadowIntersectsSphere__FP6SHADOWP6VECTORf = 0x1B26F8; // type:func\nFindSwShadows__FP2SWP6VECTORfiPiPP6SHADOW   = 0x1B2790; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/shape.c\n////////////////////////////////////////////////////////////////\nLoadShapeFromBrx__FP5SHAPEP18CBinaryInputStream = 0x1B2840; // type:func\nSetShapeParent__FP5SHAPEP3ALO                   = 0x1B28A8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/shd.c\n////////////////////////////////////////////////////////////////\nTex0FromTexIframeCtk__FP3TEXi3CTK              = 0x1B2988; // type:func\nPackTexGifs__FP3TEXi3CTK4SHDKP4GIFS            = 0x1B29E0; // type:func\nLoadClutFromBrx__FP18CBinaryInputStreamP4CLUT  = 0x1B2B50; // type:func\nLoadColorTablesFromBrx__FP18CBinaryInputStream = 0x1B2BA8; // type:func\nLoadBmpFromBrx__FP18CBinaryInputStreamP3BMP    = 0x1B2CA8; // type:func\nLoadBitmapsFromBrx__FP18CBinaryInputStream     = 0x1B2CF8; // type:func\nLoadFontsFromBrx__FP18CBinaryInputStream       = 0x1B2DF8; // type:func\nLoadTexFromBrx__FP18CBinaryInputStreamP3TEX    = 0x1B2F00; // type:func\nLoadShadersFromBrx__FP18CBinaryInputStream     = 0x1B3040; // type:func\nUploadPermShaders__Fv                          = 0x1B3450; // type:func\nPropagateShaders__Fi                           = 0x1B3488; // type:func\nFillShaders__Fi                                = 0x1B3510; // type:func\nUnloadShaders__Fv                              = 0x1B40C8; // type:func\njunk_001B4180                                  = 0x1B4180; // type:func\nConvertRgbToHsv__FP6VECTORT0                   = 0x1B4188; // type:func\nConvertHsvToRgb__FP6VECTORT0                   = 0x1B4330; // type:func\nConvertUserHsvToUserRgb__FP6VECTORT0           = 0x1B4580; // type:func\nConvertUserRgbToUserHsv__FP6VECTORT0           = 0x1B4600; // type:func\njunk_001B4670                                  = 0x1B4670; // type:func\nPshdFindShader__F3OID                          = 0x1B4688; // type:func\nSetSaiIframe__FP3SAIi                          = 0x1B46E0; // type:func\nSetSaiDuDv__FP3SAIff                           = 0x1B4750; // type:func\nPropagateSais__Fv                              = 0x1B47C0; // type:func\nUpdateShaders__Ff                              = 0x1B4878; // type:func\n\ng_grfzonShaders = 0x274518; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/shdanim.c\n////////////////////////////////////////////////////////////////\nCbFromSaak__F4SAAK                                     = 0x1B4920; // type:func\nPvtsaaFromSaak__F4SAAK                                 = 0x1B4980; // type:func\nPsaaLoadFromBrx__FP18CBinaryInputStream                = 0x1B4A10; // type:func\nInitSaa__FP3SAAP4SAAF                                  = 0x1B4AA0; // type:func\nPostSaaLoad__FP3SAA                                    = 0x1B4AD0; // type:func\nFUpdatableSaa__FP3SAA                                  = 0x1B4B08; // type:func\nUCompleteSaa__FP3SAA                                   = 0x1B4B38; // type:func\nPsaiFromSaaShd__FP3SAAP3SHD                            = 0x1B4B48; // type:func\nInitLoop__FP4LOOPP4SAAF                                = 0x1B4B68; // type:func\nPostLoopLoad__FP4LOOP                                  = 0x1B4BC8; // type:func\nUpdateLoop__FP4LOOPf                                   = 0x1B4C30; // type:func\nUCompleteLoop__FP4LOOP                                 = 0x1B4D18; // type:func\nInitPingpong__FP8PINGPONGP4SAAF                        = 0x1B4D48; // type:func\nPostPingpongLoad__FP8PINGPONG                          = 0x1B4DA8; // type:func\nUpdatePingpong__FP8PINGPONGf                           = 0x1B4E18; // type:func\nUCompletePingpong__FP8PINGPONG                         = 0x1B4F18; // type:func\nInitShuffle__FP7SHUFFLEP4SAAF                          = 0x1B4F80; // type:func\nUpdateShuffle__FP7SHUFFLEf                             = 0x1B4FC0; // type:func\nInitHologram__FP8HOLOGRAMP4SAAF                        = 0x1B5060; // type:func\nPostHologramLoad__FP8HOLOGRAM                          = 0x1B5108; // type:func\nNotifyHologramRender__FP8HOLOGRAMP3ALOP3RPL            = 0x1B5160; // type:func\nInitScroller__FP8SCROLLERP4SAAF                        = 0x1B5200; // type:func\nUpdateScroller__FP8SCROLLERf                           = 0x1B5278; // type:func\nUCompleteScroller__FP8SCROLLER                         = 0x1B5308; // type:func\nSetScrollerMasterSpeeds__FP8SCROLLERff                 = 0x1B5388; // type:func\nInitCircler__FP7CIRCLERP4SAAF                          = 0x1B5398; // type:func\nUpdateCircler__FP7CIRCLERf                             = 0x1B5400; // type:func\nUCompleteCircler__FP7CIRCLER                           = 0x1B5488; // type:func\nInitLooker__FP6LOOKERP4SAAF                            = 0x1B54D0; // type:func\nSetLookerSgvr__FP6LOOKERP4SGVRP7GLOBSETP4GLOBP7SUBGLOB = 0x1B5568; // type:func\nSetVecPosad__FP6VECTORP5POSAD                          = 0x1B5588; // type:func\nSetUvPuvqd__FP3UVFP3UVQ                                = 0x1B55A8; // type:func\nNotifyLookerRender__FP6LOOKERP3ALOP3RPL                = 0x1B55C0; // type:func\njunk_001B5B48                                          = 0x1B5B48; // type:func\nFUN_001b5b58                                           = 0x1B5B58; // type:func\nFUN_001b5c40                                           = 0x1B5C40; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/sky.c\n////////////////////////////////////////////////////////////////\nPostSkyLoad__FP3SKY = 0x1B5CD8; // type:func\nUpdateSky__FP3SKYf  = 0x1B5D28; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/slotheap.c\n////////////////////////////////////////////////////////////////\n_InitSlotheap__FP8SLOTHEAPii           = 0x1B5D80; // type:func\nCreateSlotheapSw__FP8SLOTHEAPii        = 0x1B5DD0; // type:func\nCreateSlotheapSwAlign64__FP8SLOTHEAPii = 0x1B5E30; // type:func\njunk_001B5E98                          = 0x1B5E98; // type:func\nPvAllocSlotheapUnsafe__FP8SLOTHEAP     = 0x1B5EA0; // type:func\nPvAllocSlotheapImpl__FP8SLOTHEAP       = 0x1B5EC0; // type:func\nPvAllocSlotheapClearImpl__FP8SLOTHEAP  = 0x1B5EE0; // type:func\nFreeSlotheapPv__FP8SLOTHEAPPv          = 0x1B5F28; // type:func\njunk_001B5F48                          = 0x1B5F48; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/sm.c\n////////////////////////////////////////////////////////////////\nLoadSmFromBrx__FP2SMP18CBinaryInputStream = 0x1B5F50; // type:func\nPostSmLoad__FP2SM                         = 0x1B61A8; // type:func\nPostSmLoadCallback__FP2SM5MSGIDPv         = 0x1B61F0; // type:func\nPsmaApplySm__FP2SMP3ALO3OIDi              = 0x1B6290; // type:func\nPsmaFindSm__FP2SMP3ALO                    = 0x1B6388; // type:func\nIsmsFindSmOptional__FP2SM3OID             = 0x1B63C0; // type:func\nIsmsFindSmRequired__FP2SM3OID             = 0x1B63F8; // type:func\nOidFromSmIsms__FP2SMi                     = 0x1B6420; // type:func\nRetractSma__FP3SMA                        = 0x1B6438; // type:func\nSetSmaGoal__FP3SMA3OID                    = 0x1B64D8; // type:func\nGetSmaGoal__FP3SMAP3OID                   = 0x1B6568; // type:func\nGetSmaCur__FP3SMAP3OID                    = 0x1B6598; // type:func\nGetSmaNext__FP3SMAP3OID                   = 0x1B65C8; // type:func\nSetSmaSvt__FP3SMAf                        = 0x1B65F8; // type:func\nSeekSma__FP3SMA3OID                       = 0x1B6628; // type:func\nChooseSmaTransition__FP3SMA               = 0x1B66A0; // type:func\nEndSmaTransition__FP3SMA                  = 0x1B6C68; // type:func\nHandleSmaMessage__FP3SMA5MSGIDPv          = 0x1B6CA8; // type:func\nSkipSma__FP3SMAf                          = 0x1B6CF0; // type:func\nSendSmaMessage__FP3SMA5MSGIDPv            = 0x1B6D78; // type:func\nFUN_001b6df8                              = 0x1B6DF8; // type:func\nNotifySmaSpliceOnEnterState__FP3SMAii     = 0x1B6E28; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/smartguard.c\n////////////////////////////////////////////////////////////////\nInitSmartguard__FP10SMARTGUARD                        = 0x1B6EC8; // type:func\nPostSmartguardLoadFlashlight__FP10SMARTGUARD          = 0x1B6F50; // type:func\nUseSmartguardFlashlightTarget__FP10SMARTGUARD3SGS3OID = 0x1B70B0; // type:func\nFUN_001B7100__FP10SMARTGUARDi                         = 0x1B7100; // type:func\nPostSmartguardLoad__FP10SMARTGUARD                    = 0x1B7128; // type:func\nFFilterSmartguardDetect__FP10SMARTGUARDP2SO           = 0x1B71C8; // type:func\nFDetectSmartguard__FP10SMARTGUARD                     = 0x1B7280; // type:func\nUpdateSmartguard__FP10SMARTGUARDf                     = 0x1B7608; // type:func\nUpdateSmartguardFlashlight__FP10SMARTGUARD            = 0x1B7638; // type:func\nOnSmartguardEnteringSgs__FP10SMARTGUARD3SGSP4ASEG     = 0x1B7790; // type:func\nFCanSmartguardAttack__FP10SMARTGUARD                  = 0x1B7818; // type:func\nSgasGetSmartguard__FP10SMARTGUARD                     = 0x1B7860; // type:func\nHandleSmartguardMessage__FP10SMARTGUARD5MSGIDPv       = 0x1B78C0; // type:func\nFreezeSmartguard__FP10SMARTGUARDi                     = 0x1B7920; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/so.c\n////////////////////////////////////////////////////////////////\nInitSo__FP2SO                                          = 0x1B7968; // type:func\nOnSoAdd__FP2SO                                         = 0x1B7A98; // type:func\nOnSoRemove__FP2SO                                      = 0x1B7B78; // type:func\nEnableSoPhys__FP2SOi                                   = 0x1B7C40; // type:func\nDisplaceSo__FP2SOi                                     = 0x1B7D00; // type:func\nImpactSo__FP2SOi                                       = 0x1B7F78; // type:func\nPivotSo__FP2SOi                                        = 0x1B8148; // type:func\nExtendSoBounds__FP2SOP6VECTORf                         = 0x1B8420; // type:func\nUpdateSoBounds__FP2SO                                  = 0x1B8540; // type:func\nUpdateGeomWorld__FP4GEOMT0G9VU_VECTORP7MATRIX3         = 0x1B8820; // type:func\nUpdateSoXfWorldHierarchy__FP2SO                        = 0x1B8960; // type:func\nUpdateSoXfWorld__FP2SO                                 = 0x1B89B8; // type:func\nFIgnoreSoIntersection__FP2SOT0                         = 0x1B8A08; // type:func\nUpdateSoImpacts__FP2SO                                 = 0x1B8A48; // type:func\nUProjectVector__FP6VECTORN20                           = 0x1B8B30; // type:func\nAdjustSoXpLocal__FP2SOP2XPi                            = 0x1B8B90; // type:func\njunk_001B8FE0                                          = 0x1B8FE0; // type:func\nCalculateSoAngularEffectWorld__FP2SOP6VECTORT1         = 0x1B8FE8; // type:func\nAccelSoTowardPosSpring__FP2SOP6VECTORP3CLQT1T2f        = 0x1B9058; // type:func\nAccelSoTowardMatSpring__FP2SOP7MATRIX3P3CLQP6VECTORT2f = 0x1B91A8; // type:func\nPresetSoAccel__FP2SOf                                  = 0x1B9338; // type:func\nRenderSoSelf__FP2SOP2CMP2RO                            = 0x1B93D8; // type:func\nUpdateSo__FP2SOf                                       = 0x1B93F8; // type:func\nSetSoMass__FP2SOf                                      = 0x1B9418; // type:func\nAdjustSoMomint__FP2SOf                                 = 0x1B9448; // type:func\nDiscardSoXps__FP2SO                                    = 0x1B94F0; // type:func\nUpdateSoPosWorldPrev__FP2SO                            = 0x1B9680; // type:func\nTranslateSoToPos__FP2SOP6VECTOR                        = 0x1B9690; // type:func\nRotateSoToMat__FP2SOP7MATRIX3                          = 0x1B97E0; // type:func\nTranslateSoToPosSafe__FP2SOP6VECTORT1                  = 0x1B9860; // type:func\njunk_001B9938                                          = 0x1B9938; // type:func\nSetSoVelocityVec__FP2SOP6VECTOR                        = 0x1B9940; // type:func\nSetSoAngularVelocityVec__FP2SOP6VECTOR                 = 0x1B99F0; // type:func\njunk_001B9AA8                                          = 0x1B9AA8; // type:func\nAddSoAcceleration__FP2SOP6VECTOR                       = 0x1B9AB0; // type:func\nAddSoAngularAcceleration__FP2SOP6VECTOR                = 0x1B9AC8; // type:func\nSetSoConstraints__FP2SO2CTP6VECTORT1T2                 = 0x1B9AE0; // type:func\nSetSoParent__FP2SOP3ALO                                = 0x1B9B50; // type:func\nApplySoProxy__FP2SOP5PROXY                             = 0x1B9C80; // type:func\njunk_001B9D08                                          = 0x1B9D08; // type:func\nAccelSoTowardMatSmooth__FP2SOfP7MATRIX3P3SMP           = 0x1B9D10; // type:func\njunk_001B9F28                                          = 0x1B9F28; // type:func\nGetSoCpdefi__FP2SOfP6CPDEFI                            = 0x1B9F30; // type:func\nFIsSoTouching__FP2SOT0                                 = 0x1B9FB0; // type:func\nPsoFirstSoTouching__FP2SO                              = 0x1BA068; // type:func\nCloneSo__FP2SOT0                                       = 0x1BA130; // type:func\nApplySoConstraintWorld__FP2SOP6CONSTRP6VECTORN22       = 0x1BA2E8; // type:func\nApplyConstr__FP6CONSTRP6VECTORN21                      = 0x1BA430; // type:func\nApplySoConstraintLocal__FP2SOP6CONSTRP6VECTORN22       = 0x1BA500; // type:func\nAddSoXa__FP2SOP2XA                                     = 0x1BA528; // type:func\nRemoveSoXa__FP2SOP2XA                                  = 0x1BA550; // type:func\nAddSoWaterAcceleration__FP2SOP5WATERf                  = 0x1BA5B0; // type:func\nAddSoExternalAccelerations__FP2SOP2XAf                 = 0x1BAC28; // type:func\nLoadSoFromBrx__FP2SOP18CBinaryInputStream              = 0x1BAC30; // type:func\nSetSoSphere__FP2SOf                                    = 0x1BAFE0; // type:func\nSetSoNoInteract__FP2SOi                                = 0x1BB000; // type:func\nConstrFromCnstr__F5CNSTRP2CTP6VECTOR                   = 0x1BB028; // type:func\nSetSoCnstrForce__FP2SO5CNSTR                           = 0x1BB058; // type:func\nSetSoCnstrTorque__FP2SO5CNSTR                          = 0x1BB0C8; // type:func\nSetSoCameraStyle__FP2SO3CMK                            = 0x1BB138; // type:func\nSetSoIgnoreLocked__FP2SOi                              = 0x1BB168; // type:func\nSetSoIceable__FP2SOi                                   = 0x1BB1A0; // type:func\nSetSoMtlk__FP2SO4MTLK                                  = 0x1BB1D8; // type:func\nSetSoEdgeGrab__FP2SO3EGK                               = 0x1BB1E0; // type:func\nSendSoMessage__FP2SO5MSGIDPv                           = 0x1BB210; // type:func\nPxpFindSoGround__FP2SOT0Pi                             = 0x1BB290; // type:func\nSetSoNoGravity__FP2SOi                                 = 0x1BB378; // type:func\nSetSoNoXpsAll__FP2SOi                                  = 0x1BB3B0; // type:func\nSetSoNoXpsSelf__FP2SOi                                 = 0x1BB400; // type:func\nSetSoNoXpsCenter__FP2SOi                               = 0x1BB450; // type:func\nRebuildSoPhysHook__FP2SO                               = 0x1BB4A0; // type:func\nPsoFindSoPhysHook__FP2SOi                              = 0x1BB540; // type:func\nRecalcSoLocked__FP2SO                                  = 0x1BB580; // type:func\nFGetSoContactList__FP2SOPv                             = 0x1BB710; // type:func\nGetSoContacts__FP2SOPiPPP2SO                           = 0x1BB800; // type:func\nFSoInStsoList__FP4STSOP2SO                             = 0x1BB9A0; // type:func\nGenerateSoSpliceTouchingEvents__FP2SO                  = 0x1BB9D0; // type:func\nFInflictSoZap__FP2SOP2XPP3ZPR                          = 0x1BBC30; // type:func\nEnsureSoLvo__FP2SO                                     = 0x1BBC38; // type:func\nProjectSoLvo__FP2SOf                                   = 0x1BBEB8; // type:func\nProjectSoTransform__FP2SOfi                            = 0x1BC088; // type:func\nApplySoImpulse__FP2SOP6VECTORT1f                       = 0x1BC0E0; // type:func\nCalculateSoTrajectoryApex__FP2SOP6VECTORfT1            = 0x1BC260; // type:func\nFAbsorbSoWkr__FP2SOP3WKR                               = 0x1BC320; // type:func\nCloneSoPhys__FP2SOT0i                                  = 0x1BC368; // type:func\nFUN_001bc4d8                                           = 0x1BC4D8; // type:func\nFUN_001bc670                                           = 0x1BC670; // type:func\nFUN_001bc710                                           = 0x1BC710; // type:func\nFUN_001bc748                                           = 0x1BC748; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/solve.c\n////////////////////////////////////////////////////////////////\nRenumberSo__FP2SOPiPP2SO               = 0x1BC760; // type:func\nCalculateSoEffect__FP2SOP6VECTORP2FXT1 = 0x1BC7f8; // type:func\nPropagateSoForce__FP2SOiP2XPiP2DZP2FX  = 0x1BC828; // type:func\nDistributeSoEffects__FP2SOiiPP2SOP2FX  = 0x1BC978; // type:func\nSolveSwGroup__FP2SWiPP2SOiPP2XPfi      = 0x1BCD00; // type:func\nCpxpBuildXpArray__FiPP2SOiPP2XP        = 0x1BD558; // type:func\nBuildContactGroup__FP2SOPiPP2SOT1T2    = 0x1BD678; // type:func\nSplitSoFreeze__FP2SOi                  = 0x1BD790; // type:func\nSortSwGroup__FiPP2SO                   = 0x1BD888; // type:func\nSplitSwGroup__FP2SWiPP2SOfi            = 0x1BDA50; // type:func\nSolveSw__FP2SWfi                       = 0x1BDD00; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/sort.c\n////////////////////////////////////////////////////////////////\nSwapEntries__FPviii     = 0x1BE068; // type:func\nHeapSort__FPviiPFPvPv_i = 0x1BE0A8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/sound.c\n////////////////////////////////////////////////////////////////\nUnloadMusic__Fv = 0x1BE1E8; // type:func\nSbpEnsureBank__Fi = 0x1BE268; // type:func\nSbpEnsureBank__F5SFXID = 0x1BE4A8; // type:func\nNewSfx__FPP3SFX = 0x1BE4D8; // type:func\nFContinuousSound__F5SFXID = 0x1BE568; // type:func\nFUN_001BE5D8 = 0x1BE5D8; // type:func\nSetVagUnpaused__Fv = 0x1BE5E8; // type:func\nPreloadVag__FPc2FK = 0x1BE5F8; // type:func\n\nFUN_001be708 = 0x1BE708; // type:func\nPreloadVag1 = 0x1BE728; // type:func\n\nFPauseForVag__Fv = 0x1BE810; // type:func\nRefreshPambVolPan__FP3AMB = 0x1BE860; // type:func\n\nFUN_001be8f8 = 0x1BE8F8; // type:func\n\nFVagPlaying__Fv = 0x1BE980; // type:func\njunk_001BE990 = 0x1BE990; // type:func\nStopVag__Fv = 0x1BE998; // type:func\nPauseVag__Fv = 0x1BEA28; // type:func\nContinueVag__Fv = 0x1BEA50; // type:func\nKillMusic__Fv = 0x1BEA78; // type:func\nPreloadMusidSongComplete__FUiUl = 0x1BEAC8; // type:func\nPreloadMusidSong__F5MUSID = 0x1BEB10; // type:func\nStartMusidSong__F5MUSID = 0x1BEC58; // type:func\nPauseMusic__Fv = 0x1BECF8; // type:func\nContinueMusic__Fv = 0x1BED20; // type:func\n\nSfxhMusicUnknown1 = 0x1BED48; // type:func\nSfxhMusicUnknown2 = 0x1BED70; // type:func\n\nPexcAlloc__Fv = 0x1BED98; // type:func\nRemoveExc__FP3EXC = 0x1BEDF8; // type:func\nKillExcitement__Fv = 0x1BEE48; // type:func\nPexcSetExcitement__Fi = 0x1BEEF8; // type:func\nSetIexcCurHigh__FP3EXC = 0x1BEF88; // type:func\nUnsetExcitement__FP3EXC = 0x1BF048; // type:func\nUnsetExcitementHyst__FP3EXC = 0x1BF0D8; // type:func\nStartupSound__Fv = 0x1BF130; // type:func\njunk_001BF1E8 = 0x1BF1E8; // type:func\nFAmbientsPaused__Fv = 0x1BF1F0; // type:func\nCalculateVolPan__FfP6VECTORPfT2fff = 0x1BF200; // type:func\nFUN_001BF2E0 = 0x1BF2E0; // type:func\nFUN_001BF398 = 0x1BF398; // type:func\nPposEar__Fv = 0x1BF3D0; // type:func\nSetDoppler__FP3AMB = 0x1BF428; // type:func\nPfneardistGet__Fv = 0x1BF578; // type:func\nSDistEar__FP6VECTOR = 0x1BF5E0; // type:func\nCalculateDistVolPan__FP6VECTORPfT1fff = 0x1BF620; // type:func\nPambAlloc__Fv = 0x1BF6B8; // type:func\nDropPamb__FPP3AMB = 0x1BF718; // type:func\nRemoveAmb__FP3AMB = 0x1BF728; // type:func\nStopSound__FP3AMBi = 0x1BF788; // type:func\nSetPambFrq__FP3AMBf = 0x1BF7F8; // type:func\nSetPambVol__FP3AMBf = 0x1BF8E8; // type:func\nFillPamb__FP3AMBPP3AMBiP3ALOP6VECTORfffffP2LMT10_ = 0x1BF920; // type:func\nActivatePamb__FP3AMB5SFXID = 0x1BFAF8; // type:func\nScheduleNextIntermittentSound__FP3AMB = 0x1BFBF8; // type:func\nStartSound__F5SFXIDPP3AMBP3ALOP6VECTORfffffP2LMT9 = 0x1BFCD8; // type:func\nFUN_001BFFC8 = 0x1BFFC8; // type:func\nHandleWipeHandleWipeVolumes__FifVolumes = 0x1C0000; // type:func\nUpdateSounds__Fv = 0x1C0070; // type:func\nSetMvgkUvol__Ff = 0x1c05d0; // type:func\nMvgkUnknown1__F4MVGK = 0x1C0600; // type:func\nSetMvgkRvol__Fi4MVGKf = 0x1C06A0; // type:func\nMvgkUnknown2__Fv = 0x1C06D8; // type:func\nMvgkUnknown3 = 0x1C0760; // type:func\nMvgkUnknown4 = 0x1C0790; // type:func\nKillSoundSystem__Fv = 0x1C07B0; // type:func\nKillSounds__Fi = 0x1C0808; // type:func\nPushSwReverb__FP2SW7REVERBKi = 0x1C08B0; // type:func\nPopSwReverb__FP2SW = 0x1C0950; // type:func\nSetSwDefaultReverb__FP2SW7REVERBKi = 0x1C09D8; // type:func\nFUN_001C0A50 = 0x1C0A50; // type:func\nFUN_001C0AB8 = 0x1C0AB8; // type:func\nFUN_001C0B08 = 0x1C0B08; // type:func\nStartSwIntermittentSounds__FP2SW = 0x1C0B38; // type:func\nSetAMRegister__FiUc = 0x1C0C08; // type:func\nFUN_001c0c50 = 0x1C0C50; // type:func\nFUN_001c0c68 = 0x1C0C68; // type:func\nFUN_001c0cb0__Fv = 0x1C0CB0; // type:func\nHsNextFootFall__Fv = 0x1C0CF0; // type:func\nNextSneakyFootstep__Fv = 0x1C0EC0; // type:func\n\nD_00604790 = 0x00604790; // size:0x1c\n\ng_iexcHyst = 0x274738; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/speaker.c\n////////////////////////////////////////////////////////////////\nInitSpeaker__FP7SPEAKER          = 0x1C0F30; // type:func\nPostSpeakerLoad__FP7SPEAKER      = 0x1C0FF0; // type:func\nSetSpeakerSmIdle__FP7SPEAKER3OID = 0x1C1030; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/spire.c\n////////////////////////////////////////////////////////////////\nInitSpire__FP5SPIRE     = 0x1C10A8; // type:func\nOnSpireAdd__FP5SPIRE    = 0x1C10D8; // type:func\nOnSpireRemove__FP5SPIRE = 0x1C1110; // type:func\nCloneSpire__FP5SPIRET0  = 0x1C1148; // type:func\n\nDAT_0024d3b4 = 0x24D3B4; // size:0x4\n\n\n////////////////////////////////////////////////////////////////\n// P2/splicemap.c\n////////////////////////////////////////////////////////////////\nLoadSwSpliceFromBrx__FP2SWP18CBinaryInputStream = 0x1C1190; // type:func\nPframeFromIsplice__FiP2SW                       = 0x1C1390; // type:func\nRefEvalModule__FiP2SW                           = 0x1C13E8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/spliceobj.c\n////////////////////////////////////////////////////////////////\nPeopidFind__FP5BASICi                  = 0x1C14C0; // type:func\nRefGetObjectList__FP5BASIC4OTYPPFPv_v  = 0x1C1530; // type:func\nRefGetPeopid__FP5BASICP5EOPID          = 0x1C15D8; // type:func\nFAppendSpliceListElement__FPvT0        = 0x1C1A28; // type:func\nFSpliceListElementExists__FPvT0        = 0x1C1AD8; // type:func\nRefSetPvsFromSplice__FiP4CRefP4OTYPPPv = 0x1C1BF8; // type:func\nRefSetArgListFromPvs__FiP4OTYPPPv      = 0x1C1E48; // type:func\nRefSetPeopid__FP5BASICP5EOPIDP4CRef    = 0x1C1F20; // type:func\nRefGetOption__FP5BASICi                = 0x1C21A0; // type:func\nRefSetOption__FP5BASICiP4CRef          = 0x1C2238; // type:func\nRefAddOption__FP5BASICiP4CRef          = 0x1C22B8; // type:func\nRefEnsureOption__FP5BASICiP4CRef       = 0x1C2320; // type:func\nRefSetArgsFromSplice__FiP4CRefP4OTYPe  = 0x1C23B0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/sprbuf.c\n////////////////////////////////////////////////////////////////\nLoadSprBuf__Fie                                 = 0x1C2430; // type:func\nSaveSprBuf__FPve                                = 0x1C25B0; // type:func\njunk_001C27A8                                   = 0x1C27A8; // type:func\nsprbuf__static_initialization_and_destruction_0 = 0x1C27B0; // type:func\n_GLOBAL_$I$g_asprbuf                            = 0x1C29C8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/sqtr.c\n////////////////////////////////////////////////////////////////\nFUN_001c29e8                             = 0x1C29E8; // type:func\nUpdateSqtrm__FP5SQTRMP6VECTORP7MATRIX3ff = 0x1C29F8; // type:func\nRenderSqtrm__FP5SQTRMP2CM                = 0x1C3028; // type:func\nDrawSqtrm__FP3RPL                        = 0x1C30E8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/step.c\n////////////////////////////////////////////////////////////////\nInitStep__FP4STEP                              = 0x1C4458; // type:func\nPostStepLoad__FP4STEP                          = 0x1C44F0; // type:func\nLimitStepHands__FP4STEPi                       = 0x1C4578; // type:func\nFUN_001c4618                                   = 0x1C4618; // type:func\nFUN_001c4790                                   = 0x1C4790; // type:func\nFUN_001c4848                                   = 0x1C4848; // type:func\nRenderStepSelf__FP4STEPP2CMP2RO                = 0x1C49C8; // type:func\nReadStepJoystick__FP4STEPP3JOY                 = 0x1C49E8; // type:func\nUpdateStepFootfall__FP4STEPfP3SFF              = 0x1C4A80; // type:func\nUpdateStepPhys__FP4STEP                        = 0x1C4C20; // type:func\nSetStepPhys__FP4STEPP2SOi                      = 0x1C4D60; // type:func\nUpdateStep__FP4STEPf                           = 0x1C4ED0; // type:func\nCtTorqueStep__FP4STEP                          = 0x1C4F00; // type:func\nPropagateStepForce__FP4STEPiP2XPiP2DZP2FX      = 0x1C4F08; // type:func\nRotateStepToMat__FP4STEPP7MATRIX3              = 0x1C4FA0; // type:func\nCloneStepPhys__FP4STEPP2SOi                    = 0x1C4FF8; // type:func\nPresetStepAccel__FP4STEPf                      = 0x1C5118; // type:func\nPresetStepAccelBase__FP4STEP                   = 0x1C5148; // type:func\nFCheckStepXpBase__FP4STEPP2XPi                 = 0x1C5248; // type:func\nAdjustStepNewXp__FP4STEPP2XPi                  = 0x1C5338; // type:func\nAdjustStepDz__FP4STEPiP2DZif                   = 0x1C5388; // type:func\nAdjustStepDzBase__FP4STEPiP2DZi                = 0x1C53A8; // type:func\nUpdateStepMatTarget__FP4STEP                   = 0x1C53B0; // type:func\nAdjustStepXpVelocity__FP4STEPP2XPi             = 0x1C53E0; // type:func\nUpdateStepXfWorld__FP4STEP                     = 0x1C5438; // type:func\nAdjustStepXpVelocityBase__FP4STEPP2XPi         = 0x1C54D0; // type:func\nAdjustStepXps__FP4STEP                         = 0x1C57C8; // type:func\nAddStepCustomXps__FP4STEPP2SOiP3BSPT3PP2XP     = 0x1C5BF0; // type:func\nAddStepCustomXpsBase__FP4STEPP2SOP3BSPPP2XP    = 0x1C5C10; // type:func\nFixStepAngularVelocity__FP4STEP                = 0x1C5D58; // type:func\nPredictStepRotation__FP4STEPfP7MATRIX3P6VECTOR = 0x1C5DB8; // type:func\nSetStepSpinRatio__FP4STEPf                     = 0x1C5E50; // type:func\nSetStepGravityRatio__FP4STEPf                  = 0x1C5EA8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/stepact.c\n////////////////////////////////////////////////////////////////\nGetActaddPositionGoal__FP6ACTADDfP6VECTORT2        = 0x1C5F18; // type:func\nGetActaddRotationGoal__FP6ACTADDfP7MATRIX3P6VECTOR = 0x1C6028; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/stepcane.c\n////////////////////////////////////////////////////////////////\nSetJtJtcs__FP2JT4JTCS                             = 0x1C61E0; // type:func\nUpdateJtCane__FP2JT                               = 0x1C6890; // type:func\nUpdateJtActiveCane__FP2JTP3JOY                    = 0x1C6928; // type:func\nChooseJtAttackTarget__FP2JTiP6VECTORffPP6TARGETT2 = 0x1C6AA8; // type:func\nChooseJtSweepTarget__FP2JTP2BLP6ASEGBL            = 0x1C6D00; // type:func\nChooseJtRushTarget__FP2JT                         = 0x1C6E58; // type:func\nChooseJtSmashTarget__FP2JT                        = 0x1C6ED0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/stepguard.c\n////////////////////////////////////////////////////////////////\nInitStepguard__FP9STEPGUARD                             = 0x1C6F48; // type:func\nLoadStepguardFromBrx__FP9STEPGUARDP18CBinaryInputStream = 0x1C7140; // type:func\nCloneStepguard__FP9STEPGUARDT0                          = 0x1C7188; // type:func\nBindStepguard__FP9STEPGUARD                             = 0x1C71E0; // type:func\nPostStepguardLoadCallback__FP9STEPGUARD5MSGIDPv         = 0x1C7278; // type:func\nPostStepguardLoad__FP9STEPGUARD                         = 0x1C72A0; // type:func\nFIgnoreStepguardIntersection__FP9STEPGUARDP2SO          = 0x1C7468; // type:func\nOnStepguardAdd__FP9STEPGUARD                            = 0x1C74E8; // type:func\nOnStepguardRemove__FP9STEPGUARD                         = 0x1C7520; // type:func\nPresetStepguardAccel__FP9STEPGUARDf                     = 0x1C75B0; // type:func\nDradEnemyStepguard__FP9STEPGUARD                        = 0x1C7A60; // type:func\nSetStepguardTargetHeading__FP9STEPGUARDff               = 0x1C7AE0; // type:func\nFUN_001c7b60                                            = 0x1C7B60; // type:func\nUpdateStepguardDrive__FP9STEPGUARD                      = 0x1C7BE8; // type:func\nUpdateStepguard__FP9STEPGUARDf                          = 0x1C7CB8; // type:func\nSgsNextStepguardAI__FP9STEPGUARD                        = 0x1C8010; // type:func\nSetStepguardGoal__FP9STEPGUARDP6VECTOR                  = 0x1C8418; // type:func\nFReachedStepguardGoal__FP9STEPGUARD                     = 0x1C84C0; // type:func\nFFilterStepguardJump__FP9STEPGUARDP2SO                  = 0x1C84E8; // type:func\nMoveStepguardToGoal__FP9STEPGUARD                       = 0x1C8590; // type:func\nFUN_001c8920                                            = 0x1C8920; // type:func\nLookStepguardAtGoal__FP9STEPGUARD                       = 0x1C8BC0; // type:func\nUpdateStepguardGoal__FP9STEPGUARDi                      = 0x1C8C08; // type:func\nFUN_001c8d40                                            = 0x1C8D40; // type:func\nOnStepguardWaypointActive__FP9STEPGUARD                 = 0x1C8D78; // type:func\nUpdateStepguardSgs__FP9STEPGUARD                        = 0x1C8E28; // type:func\nSetStepguardSgs__FP9STEPGUARD3SGSP4ASEG                 = 0x1C8F20; // type:func\nSetStepguardSgsExternal__FP9STEPGUARD3SGSP4ASEG         = 0x1C8FD0; // type:func\nOnStepguardExitingSgs__FP9STEPGUARD3SGS                 = 0x1C9008; // type:func\nOnStepguardEnteringSgs__FP9STEPGUARD3SGSP4ASEG          = 0x1C91C8; // type:func\nSggsGetStepguard__FP9STEPGUARD                          = 0x1C96B8; // type:func\nFAbsorbStepguardWkr__FP9STEPGUARDP3WKR                  = 0x1C96D8; // type:func\nFTakeStepguardDamage__FP9STEPGUARDP3ZPR                 = 0x1C9990; // type:func\nFUN_001c9a48                                            = 0x1C9A48; // type:func\nHandleStepguardGrfsgsc__FP9STEPGUARD                    = 0x1C9A58; // type:func\nDoStepguardFreefallJump__FP9STEPGUARD                   = 0x1C9AF8; // type:func\nDoStepguardFreefallLanding__FP9STEPGUARD                = 0x1C9CF8; // type:func\nFUN_001c9d50                                            = 0x1C9D50; // type:func\nHandleStepguardMessage__FP9STEPGUARD5MSGIDPv            = 0x1C9DE0; // type:func\nSgasGetStepguard__FP9STEPGUARD                          = 0x1CA460; // type:func\nFCanStepguardAttack__FP9STEPGUARD                       = 0x1CA468; // type:func\nRenderStepguardSelf__FP9STEPGUARDP2CMP2RO               = 0x1CA5E0; // type:func\nFValidSgs__F3SGS                                        = 0x1CA600; // type:func\nUseStepguardAnimation__FP9STEPGUARD3SGS3OID             = 0x1CA608; // type:func\nUseStepguardAnimationImmediate__FP9STEPGUARD3SGS3OID    = 0x1CA658; // type:func\nFUN_001ca6d0                                            = 0x1CA6D0; // type:func\nUseStepguardDeathAnimation__FP9STEPGUARDi3OID           = 0x1CA720; // type:func\nPasegFindStepguard__FP9STEPGUARD3OID                    = 0x1CA758; // type:func\nLoadStepguardAnimations__FP9STEPGUARD                   = 0x1CA7C0; // type:func\nUseStepguardExpl__FP9STEPGUARD3OID                      = 0x1CA878; // type:func\nUseStepguardRwm__FP9STEPGUARD3OID                       = 0x1CA888; // type:func\nUseStepguardPhys__FP9STEPGUARD3SGS3OID                  = 0x1CA898; // type:func\nLoadStepguardPhys__FP9STEPGUARD                         = 0x1CA8E8; // type:func\nAddStepguardEffect__FP9STEPGUARD3OID3ZPK                = 0x1CA960; // type:func\nSetStepguardPathzone__FP9STEPGUARD3OID                  = 0x1CA998; // type:func\nPsoEnemyStepguard__FP9STEPGUARD                         = 0x1CAA08; // type:func\nFUN_001caad0                                            = 0x1CAAD0; // type:func\nSetStepguardEnemyObject__FP9STEPGUARDP2SO               = 0x1CAB00; // type:func\nRebindStepguardEnemy__FP9STEPGUARD                      = 0x1CAB10; // type:func\nFUN_001cac28__FP9STEPGUARD                              = 0x1CAC28; // type:func\nFUN_001cac30                                            = 0x1CAC30; // type:func\nAdjustStepguardDz__FP9STEPGUARDiP2DZif                  = 0x1CACB0; // type:func\nSetStepguardAttackAngleMax__FP9STEPGUARDf               = 0x1CAD28; // type:func\nAddStepguardAlarm__FP9STEPGUARDP5ALARM                  = 0x1CAD40; // type:func\nMatchStepguardAnimationPhase__FP9STEPGUARD3OIDN31       = 0x1CAD60; // type:func\nAddStepguardCustomXps__FP9STEPGUARDP2SOiP3BSPT3PP2XP    = 0x1CAD98; // type:func\nFUN_001caee0                                            = 0x1CAEE0; // type:func\nUpdateStepguardEffect__FP9STEPGUARD                     = 0x1CAF38; // type:func\nSetStepguardPatrolAnimation__FP9STEPGUARDP4ASEG         = 0x1CB328; // type:func\nFInflictStepguardZap__FP9STEPGUARDP2XPP3ZPR             = 0x1CB3C0; // type:func\nFDetectStepguard__FP9STEPGUARD                          = 0x1CB3C8; // type:func\nFCheckStepguardEnemyHidden__FP9STEPGUARD                = 0x1CB3D0; // type:func\nFUN_001cb578                                            = 0x1CB578; // type:func\nPsggNew__FP2SW                                          = 0x1CB5B8; // type:func\nInitSgg__FP3SGG                                         = 0x1CB618; // type:func\nAddSggGuard__FP3SGGP9STEPGUARD                          = 0x1CB648; // type:func\nAddSggGuardName__FP3SGG3OID                             = 0x1CB6A8; // type:func\nAddSggSearchXfmName__FP3SGG3OID                         = 0x1CB6D0; // type:func\nRemoveSggGuard__FP3SGGP9STEPGUARD                       = 0x1CB6F8; // type:func\nBindSgg__FP3SGG                                         = 0x1CB7A0; // type:func\nPostSggLoadCallback__FP3SGG5MSGIDPv                     = 0x1CB8B8; // type:func\nEnsureSggCallback__FP3SGG                               = 0x1CBAA0; // type:func\nPsoEnemySgg__FP3SGG                                     = 0x1CBAF8; // type:func\nUpdateSggCallback__FP3SGG5MSGIDPv                       = 0x1CBB20; // type:func\nSggsNextSgg__FP3SGG                                     = 0x1CBB88; // type:func\nFDetectSgg__FP3SGG                                      = 0x1CBCB8; // type:func\nFAbandonSggSearch__FP3SGG                               = 0x1CBD58; // type:func\nEnsureSggAlarm__FP3SGGP5ALARM                           = 0x1CBE20; // type:func\nTriggerSggAlarms__FP3SGG4ALTK                           = 0x1CBE70; // type:func\nSetSggSggs__FP3SGG4SGGS                                 = 0x1CBEE8; // type:func\nAssignSggSearchPoints__FP3SGG                           = 0x1CC120; // type:func\n\ns_asnipStepguardLoad = 0x274C20;\nD_0024D654 = 0x24D654;\n\n\n////////////////////////////////////////////////////////////////\n// P2/stephang.c\n////////////////////////////////////////////////////////////////\nPostJtLoadSwing__FP2JTP2BLPP6ASEGBL        = 0x1CC410; // type:func\nAnticipateJtForce__FP2JTP2SOP6VECTORT2P2FX = 0x1CC490; // type:func\nCalculateJtHangAccel__FP2JT                = 0x1CC818; // type:func\nPresetJtAccelHang__FP2JT                   = 0x1CCF98; // type:func\nAddJtExternalAccelerations__FP2JTP2XAf     = 0x1CD088; // type:func\nUpdateJtActiveHang__FP2JTP3JOY             = 0x1CD0C8; // type:func\nCheckJtUnhook__FP2JT                       = 0x1CD6C0; // type:func\nUpdateJtHookOx__FP2JTP2LOi                 = 0x1CD7E0; // type:func\nAddJtHookXps__FP2JTiP2LOP6VECTORN23        = 0x1CD870; // type:func\nGetJtHangHeading__FP2JTPf                  = 0x1CDB28; // type:func\nUpdateJtIkHang__FP2JT                      = 0x1CDB70; // type:func\nFUN_001cdd98                               = 0x1CDD98; // type:func\nFUN_001cdf78                               = 0x1CDF78; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/stephide.c\n////////////////////////////////////////////////////////////////\nJtbsChooseJtHide__FP2JTP2LOP4JTHK                     = 0x1CDFB8; // type:func\nMeasureJtJumpToTarget__FP2JTP6VECTORP3ALOT1T1PfT5T1T1 = 0x1CE590; // type:func\nGetJtRailLanding__FP2JTP4RAILfP6VECTORT3              = 0x1CE800; // type:func\nGMeasureJumpRail__FP3MJRf                             = 0x1CE9E8; // type:func\nFUN_001cea58                                          = 0x1CEA58; // type:func\nGMeasureJumpHshape__FP3MJHf                           = 0x1CEAB8; // type:func\nFUN_001ceb18                                          = 0x1CEB18; // type:func\nFUN_001cedf8                                          = 0x1CEDF8; // type:func\nFUN_001cee30                                          = 0x1CEE30; // type:func\nFUN_001ceec8                                          = 0x1CEEC8; // type:func\nFUN_001cf138                                          = 0x1CF138; // type:func\nFUN_001cf158                                          = 0x1CF158; // type:func\nUpdateJtActiveHide__FP2JTP3JOY                        = 0x1CFFD0; // type:func\nMatchJtXmgRail__FP2JTP3XMGP6ACTADJ                    = 0x1D0B20; // type:func\nUpdateJtHide__FP2JT                                   = 0x1D0C78; // type:func\nUpdateJtInternalXpsHide__FP2JT                        = 0x1D0F20; // type:func\nSetJtHfdk__FP2JT4HFDK                                 = 0x1D1200; // type:func\nResetJtDynamicTunnel__FP2JT                           = 0x1D1260; // type:func\nPresetJtAccelHide__FP2JT                              = 0x1D12F0; // type:func\nFUN_001d1478                                          = 0x1D1478; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/steppipe.c\n////////////////////////////////////////////////////////////////\nPostJtLoadPipe__FP2JT                   = 0x1D14F0; // type:func\nGetJtPipeGoalMat__FP2JTP4PIPEfP7MATRIX3 = 0x1D1630; // type:func\nPresetJtAccelPipe__FP2JT                = 0x1D1A80; // type:func\nUpdateJtActivePipe__FP2JTP3JOY          = 0x1D1BB0; // type:func\nUpdateJtInternalXpsPipe__FP2JT          = 0x1D2518; // type:func\nSetJtJtpdk__FP2JT5JTPDK                 = 0x1D27C0; // type:func\nPlaceJtOnPipe__FP2JTP4PIPE              = 0x1D2830; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/steppower.c\n////////////////////////////////////////////////////////////////\nSetFsp__F3FSP = 0x1D29C8; // type:func\nUpdateJtActivePowerUp__FP2JTP3JOY = 0x1d2bb8; // type:func\nIRotatePowerUp__FP3JOYiiPi = 0x1d3100; // type:func\n\ns_mpfspachz = 0x274f58; //size:0x1c\ng_fsp = 0x274f74; //size:0x4\n// float[3] @ 0x274f78\nRT_JtSpeedUpClock = 0x274f84; // size:0x4\nRT_JtSlowDownClock = 0x274f88; // size:0x4\n\ns_mpfspgrfvault = 0x274F38; // size:0x1c\n\n\n////////////////////////////////////////////////////////////////\n// P2/steprail.c\n// TODO: Mangle the function names.\n////////////////////////////////////////////////////////////////\nfunc_001D31D0__FP2LOi   = 0x1D31D0; // type:func\npost_load_steprail      = 0x1D3290; // type:func\nfunc_001D32D8__FiP2JTl  = 0x1D32D8; // type:func\nupdate_steprail         = 0x1D3398; // type:func\npreset_steprail_accel   = 0x1D3470; // type:func\nFUN_001d34e0            = 0x1D34E0; // type:func\nFUN_001d3500            = 0x1D3500; // type:func\nFUN_001d35a8            = 0x1D35A8; // type:func\nupdate_steprail_message = 0x1D3678; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/steprun.c\n////////////////////////////////////////////////////////////////\nPostStepLoadRun__FP4STEPP5BLRUNPP6ASEGBL        = 0x1D36F0; // type:func\nCalculateBlrunV__FiP5BLRUNP4MRSGP6VECTOR        = 0x1D39E0; // type:func\nProjectStepRunPlant__FP4STEPP5BLRUNffiiP6VECTOR = 0x1D3A38; // type:func\nFIntersectStepRunPlant__FP4STEPP6VECTORT1Pf     = 0x1D3B58; // type:func\nFReblendAbl2D__FiiiP2BLe                        = 0x1D3C68; // type:func\nAdjustStepRun__FP4STEPP5BLRUNP6ASEGBLP5ASEGA    = 0x1D3E00; // type:func\nSetStepRunTarget__FP4STEPffP5BLRUNP6ASEGBL      = 0x1D40A0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/stepside.c\n////////////////////////////////////////////////////////////////\nPostJtLoadSidestep__FP2JTP4BLSSPP6ASEGBL   = 0x1D4148; // type:func\nAdjustJtSidestep__FP2JTP4BLSSP6ASEGBL      = 0x1D4348; // type:func\nSetJtSidestepTarget__FP2JTP4BLSSP6ASEGBLff = 0x1D4698; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/stepzap.c\n////////////////////////////////////////////////////////////////\nPostJtLoadZap__FP2JT                      = 0x1D4848; // type:func\nPresetJtAccelZap__FP2JT                   = 0x1D48E8; // type:func\nUpdateJtZap__FP2JT                        = 0x1D4A98; // type:func\nFUN_001d4c90                              = 0x1D4C90; // type:func\nFUN_001d4c98                              = 0x1D4C98; // type:func\nFTakeJtDamage__FP2JTP3ZPR                 = 0x1D4D08; // type:func\nFUN_001d51a0                              = 0x1D51A0; // type:func\nFUN_001d5398                              = 0x1D5398; // type:func\nFUN_001d5418                              = 0x1D5418; // type:func\nFUN_001d5468                              = 0x1D5468; // type:func\nFUN_001d54e0                              = 0x1D54E0; // type:func\nFUN_001d5620                              = 0x1D5620; // type:func\nSgnCmpSpkn__FPCvT0                        = 0x1D5650; // type:func\nDrawHaloSpks__FP6VECTORiP4SPKSP4SPKDP3RPL = 0x1D5678; // type:func\nDrawJtHaloElectric__FP3RPL                = 0x1D5FA8; // type:func\nDrawJtHaloFire__FP3RPL                    = 0x1D60B0; // type:func\nFUN_001d61c8                              = 0x1D61C8; // type:func\nRenderJtSelfZap__FP2JTP2CMP2RO            = 0x1D62E0; // type:func\nJthsCurrentJt__FP2JT                      = 0x1D65D8; // type:func\nUseJtCharm__FP2JT                         = 0x1D6608; // type:func\nUpdateJtWater__FP2JT                      = 0x1D66A8; // type:func\nFFindJtWaterSurface__FP2JTP5WATERP6VECTOR = 0x1D6A18; // type:func\nAddJtWaterAcceleration__FP2JTP5WATERf     = 0x1D6B18; // type:func\nFUN_001d6cb0                              = 0x1D6CB0; // type:func\nFUN_001d6da0                              = 0x1D6DA0; // type:func\nFUN_001d6dd8                              = 0x1D6DD8; // type:func\nFUN_001d7018                              = 0x1D7018; // type:func\nFUN_001d7040                              = 0x1D7040; // type:func\nInitZpr__FP3ZPR3ZPKP2LO                   = 0x1D7098; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/stream.c\n////////////////////////////////////////////////////////////////\n__5OSTRMi          = 0x1D7100; // type:func\n__5OSTRMPvi        = 0x1D7120; // type:func\n_$_5OSTRM          = 0x1D7148; // type:func\nCbWrite__5OSTRMPvi = 0x1D7190; // type:func\nFlush__5OSTRM      = 0x1D72C8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/suv.c\n////////////////////////////////////////////////////////////////\nInitSuv__FP3SUV = 0x1D73A8; // type:func\nPostSuvLoad__FP3SUV = 0x1D7440; // type:func\nPresetSuvAccel__FP3SUVf = 0x1D7778; // type:func\nGExcludeAlm__FiP2LMf = 0x1D8470; // type:func\nUpdateSuvBalance__FP3SUV = 0x1D8578; // type:func\nDsGetTrackRelative__Ffff = 0x1D86F8; // type:func\nFIsSuvAheadOf__FP3SUVT0 = 0x1D8740; // type:func\nUpdateSuvLine__FP3SUVPi = 0x1D87C8; // type:func\nUpdateSuvHeading__FP3SUV = 0x1D8BD0; // type:func\nUpdateSuvWheels__FP3SUV = 0x1D8D90; // type:func\nUpdateSuvExpls__FP3SUV = 0x1D8E40; // type:func\nBoostSuv__FP3SUV = 0x1D92F0; // type:func\nFUN_001d9338 = 0x1D9338; // type:func\nUpdateSuvVolumes__FP3SUVi = 0x1D9488; // type:func\nUpdateSuvSounds__FP3SUVf = 0x1D9678; // type:func\nUpdateSuvPuncher__FP3SUV = 0x1D9AC8; // type:func\nUpdateSuv__FP3SUVf = 0x1D9C98; // type:func\nUpdateSuvActive__FP3SUVP3JOYf = 0x1D9D78; // type:func\nFUN_001da170 = 0x1DA170; // type:func\nUpdateSuvInternalXps__FP3SUV = 0x1DA310; // type:func\nAddSuvCustomXps__FP3SUVP2SOiP3BSPT3PP2XP = 0x1DA320; // type:func\nAdjustSuvNewXp__FP3SUVP2XPi = 0x1DA6E0; // type:func\nUpdateSuvInfluences__FP3SUVP2RO = 0x1DA7E0; // type:func\nRenderSuvSelf__FP3SUVP2CMP2RO = 0x1DAA18; // type:func\nUpdateSuvBounds__FP3SUV = 0x1DAC20; // type:func\nCollectSuvPrize__FP3SUV3PCKP3ALO = 0x1DACB0; // type:func\nUpdateSuvShapes__FP3SUV = 0x1DAD28; // type:func\nUpdateSuvXfWorld__FP3SUV = 0x1DAE18; // type:func\nGetSuvCpdefi__FP3SUVfP6CPDEFI = 0x1DAE48; // type:func\nOnSuvActive__FP3SUViP2PO = 0x1DAE68; // type:func\nHandleSuvMessage__FP3SUV5MSGIDPv = 0x1DAF08; // type:func\nSetSuvTrack__FP3SUVP5SHAPE = 0x1DAFB8; // type:func\nSetSuvLine__FP3SUVP5SHAPE = 0x1DB0C8; // type:func\nAddSuvCheckPoint__FP3SUVP3VOL = 0x1DB110; // type:func\nAddSuvFeature__FP3SUVP3VOLffP4EXPLT4 = 0x1DB1E8; // type:func\nSetSuvSuvs__FP3SUV4SUVS = 0x1DB238; // type:func\nResetSuv__FP3SUV = 0x1DB290; // type:func\njunk_001DB448 = 0x1DB448; // type:func\nVecCombo__FG8VU_FLOATG9VU_VECTORT0T1 = 0x1DB460; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/sw.c\n////////////////////////////////////////////////////////////////\nInitSwDlHash__FP2SW                                               = 0x1DB480; // type:func\nInitSw__FP2SW                                                     = 0x1DB4C8; // type:func\nDeleteSw__FP2SW                                                   = 0x1DB838; // type:func\nSetupBulkDataFromBrx__FiP18CBinaryInputStream                     = 0x1DB928; // type:func\nLoadBulkDataFromBrx__FP18CBinaryInputStream                       = 0x1DBA38; // type:func\nSetSwGravity__FP2SWf                                              = 0x1DBA90; // type:func\nFUN_001dbac0                                                      = 0x1DBAC0; // type:func\nFUN_001dbae0                                                      = 0x1DBAE0; // type:func\nFUN_001dbb00                                                      = 0x1DBB00; // type:func\nFOverflowSwLo__FP2SWP2LOi                                         = 0x1DBB20; // type:func\nPxaAllocSw__FP2SW                                                 = 0x1DBB50; // type:func\nFreeSwXaList__FP2SWP2XA                                           = 0x1DBB90; // type:func\nPmqAllocSw__FP2SW                                                 = 0x1DBBD8; // type:func\nFreeSwMqList__FP2SWP2MQ                                           = 0x1DBC18; // type:func\nEnsureSwCallback__FP2SWPFPv5MSGIDPv_vPv5MSGIDT2                   = 0x1DBC60; // type:func\nPostSwCallback__FP2SWPFPv5MSGIDPv_vPv5MSGIDT2                     = 0x1DBCC8; // type:func\nClearSwCallbacks__FP2SWiPFPv5MSGIDPv_vPv5MSGIDT3                  = 0x1DBD40; // type:func\nProcessSwCallbacks__FP2SW                                         = 0x1DBE48; // type:func\nProcessSwSpliceScheduledCallbacks__FP2SWf                         = 0x1DBEC8; // type:func\nPstsoAllocSw__FP2SW                                               = 0x1DC0C8; // type:func\nFreeSwStsoList__FP2SWP4STSO                                       = 0x1DC108; // type:func\nAddSwProxySource__FP2SWP2LOi                                      = 0x1DC150; // type:func\nPloGetSwProxySource__FP2SWi                                       = 0x1DC208; // type:func\nIntersectSwBoundingBox__FP2SWP2SOP6VECTORT2PFPvP2SO_iPvPiPPP2SO   = 0x1DC238; // type:func\nIntersectSwBoundingSphere__FP2SWP2SOP6VECTORfPFPvP2SO_iPvPiPPP2SO = 0x1DC4D0; // type:func\nRemoveOxa__FP3OXAPP3OXA                                           = 0x1DC710; // type:func\nInitSwAoxa__FP2SW                                                 = 0x1DC740; // type:func\nAddOxa__FP3OXAPP3OXA                                              = 0x1DC7B0; // type:func\nPoxaAllocSw__FP2SWP2SO                                            = 0x1DC7D0; // type:func\nFreeSwPoxa__FP2SWP3OXA                                            = 0x1DC828; // type:func\nCreateSwDefaultLights__FP2SW                                      = 0x1DC9A0; // type:func\nFUN_001dccc0__FP18CBinaryInputStream                              = 0x1DCCC0; // type:func\nCreateSwPrizes__FP2SW                                             = 0x1DCD28; // type:func\nLoadSwFromBrx__FP2SWP18CBinaryInputStream                         = 0x1DCEA0; // type:func\nFClipLineHomogeneous__FP7VECTOR4                                  = 0x1DD218; // type:func\nDrawLineWorld__FP6VECTORT0G4RGBAP2CMi                             = 0x1DD3E0; // type:func\nDrawAxesWorld__FP6VECTORP7MATRIX3fP2CMi                           = 0x1DD548; // type:func\nSetSwIllum__FP2SWf                                                = 0x1DD5F8; // type:func\nSetSwIllumShadow__FP2SWf                                          = 0x1DD610; // type:func\nSetSwExcitement__FP2SWf                                           = 0x1DD628; // type:func\nFLevelSwVisited__FP2SW3WID                                        = 0x1DD690; // type:func\nFLevelSwPrimary__FP2SW3WID                                        = 0x1DD6B0; // type:func\nFLevelSwSecondary__FP2SW3WID                                      = 0x1DD6D0; // type:func\nFLevelSwTertiary__FP2SW3WID                                       = 0x1DD6F0; // type:func\nFUN_001dd710                                                      = 0x1DD710; // type:func\nFUN_001dd758                                                      = 0x1DD758; // type:func\nFUN_001dd7a0                                                      = 0x1DD7A0; // type:func\nFUN_001dd7e8                                                      = 0x1DD7E8; // type:func\nFUN_001dd888                                                      = 0x1DD888; // type:func\nFUN_001dd8e8                                                      = 0x1DD8E8; // type:func\nFUN_001dd908                                                      = 0x1DD908; // type:func\nFUN_001dd928                                                      = 0x1DD928; // type:func\nFUN_001dd950                                                      = 0x1DD950; // type:func\nFUN_001dd9a0                                                      = 0x1DD9A0; // type:func\nFUN_001dd9c0                                                      = 0x1DD9C0; // type:func\nSetSwPlayerSuck__FP2SWf                                           = 0x1DD9D8; // type:func\nGetSwPlayerSuck__FP2SWPf                                          = 0x1DDA08; // type:func\nIncrementSwHandsOff__FP2SW                                        = 0x1DDA20; // type:func\nDecrementSwHandsOff__FP2SW                                        = 0x1DDA50; // type:func\nIsSwHandsOff__FP2SW                                               = 0x1DDA80; // type:func\nIsSwVagPlaying__FP2SWPi                                           = 0x1DDA90; // type:func\nSetSwDarken__FP2SWf                                               = 0x1DDAB8; // type:func\nSetSwDarkenSmooth__FP2SWf                                         = 0x1DDAC8; // type:func\nCancelSwDialogPlaying__FP2SW                                      = 0x1DDAD0; // type:func\nFUN_001ddb20                                                      = 0x1DDB20; // type:func\nFUN_001ddb58                                                      = 0x1DDB58; // type:func\nFUN_001ddbb8                                                      = 0x1DDBB8; // type:func\nFUN_001ddbf8                                                      = 0x1DDBF8; // type:func\nFUN_001ddc18                                                      = 0x1DDC18; // type:func\nFUN_001ddc38                                                      = 0x1DDC38; // type:func\nFUN_001ddc40                                                      = 0x1DDC40; // type:func\nFUN_001ddc78                                                      = 0x1DDC78; // type:func\nFUN_001ddc90                                                      = 0x1DDC90; // type:func\nFUN_001ddcb0                                                      = 0x1DDCB0; // type:func\nFUN_001ddcc8                                                      = 0x1DDCC8; // type:func\n\ng_grfdfl       = 0x275630; // size:0x10\ng_vecHighlight = 0x275640; // size:0x10\ng_degHighlight = 0x275650; // size:0x4\ng_gMidtone     = 0x275654; // size:0x4\ng_degMidtone   = 0x275658; // size:0x4\ng_gShadow      = 0x27565C; // size:0x4\ng_degShadow    = 0x275660; // size:0x10\n\ng_psw                      = 0x275710; // size:0x4\ng_fLoadDebugInfo           = 0x275714; // size:0x4\ng_pbBulkData               = 0x275718; // size:0x4\ng_fLoadBulkData            = 0x27571C; // size:0x4\ng_cbBulkData               = 0x275720; // size:0x4\ng_nBulkDataSig             = 0x275724; // size:0x4\ng_cbBulkDataReadAdjustment = 0x275728; // size:0x8\n\n\n////////////////////////////////////////////////////////////////\n// P2/tail.c\n////////////////////////////////////////////////////////////////\nInitTail__FP4TAIL = 0x1DDCE0; // type:func\nPostTailLoad__FP4TAIL = 0x1DDD18; // type:func\nUpdateTailConstraints__FP4TAIL = 0x1DDE90; // type:func\nMatchTailOtherObject__FP4TAILP3ALO = 0x1DE768; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/tank.c\n////////////////////////////////////////////////////////////////\nInitTank__FP4TANK                  = 0x1DE798; // type:func\nPostTankLoad__FP4TANK              = 0x1DE808; // type:func\nUpdateTank__FP4TANKf               = 0x1DE910; // type:func\nFUN_001deb30                       = 0x1DEB30; // type:func\nUseTankCharm__FP4TANK              = 0x1DEBB8; // type:func\nUpdateTankActive__FP4TANKP3JOYf    = 0x1DEBE8; // type:func\nOnTankActive__FP4TANKiP2PO         = 0x1DF290; // type:func\nRenderTankAll__FP4TANKP2CMP2RO     = 0x1DF2C8; // type:func\nImpactTank__FP4TANKi               = 0x1DF520; // type:func\nFInvulnerableTank__FP4TANK3ZPK     = 0x1DF5A0; // type:func\nApplyTankThrow__FP4TANKP2PO        = 0x1DF600; // type:func\nFTakeTankDamage__FP4TANKP3ZPR      = 0x1DF700; // type:func\nFUN_001dfa10                       = 0x1DFA10; // type:func\nAdjustTankNewXp__FP4TANKP2XPi      = 0x1DFA40; // type:func\nHandleTankMessage__FP4TANK5MSGIDPv = 0x1DFB08; // type:func\nJthsCurrentTank__FP4TANK           = 0x1DFBD0; // type:func\nSetTankTanks__FP4TANK5TANKS        = 0x1DFBE0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/target.c\n////////////////////////////////////////////////////////////////\nStartupTarget__Fv         = 0x1DFD48; // type:func\nResetTargetList__Fv       = 0x1DFD70; // type:func\nInitTarget__FP6TARGET     = 0x1DFD90; // type:func\nOnTargetAdd__FP6TARGET    = 0x1DFDC8; // type:func\nOnTargetRemove__FP6TARGET = 0x1DFE00; // type:func\nCloneTarget__FP6TARGETT0  = 0x1DFE38; // type:func\n\ng_dlTarget = 0x2758D0; // size:0xc\n\n\n////////////////////////////////////////////////////////////////\n// P2/text.c\n////////////////////////////////////////////////////////////////\nCchParsePchzInt__FPcPi = 0x1E08F8; // type:func\nCchParsePchzTft__FPcP3TFTPPc = 0x1E0978; // type:func\nWriteTftPchz__FP3TFTP5OSTRMPc = 0x1E0CD0; // type:func\nFNegTftUl__FP3TFTP2UL = 0x1E0E18; // type:func\nUnRadixFromChConversion__Fc = 0x1E0EF8; // type:func\nCchAchFromUl__FPciUlUi = 0x1E0F58; // type:func\nWriteTftUl__FP3TFTP5OSTRMUl = 0x1E1028; // type:func\nExpFirstFromG__Fd = 0x1E1330; // type:func\nChDigitFromG__Fdii = 0x1E13D0; // type:func\nCchAchFromDouble__FPciP3TFTd = 0x1E1498; // type:func\nWriteTftDouble__FP3TFTP5OSTRMd = 0x1E17A8; // type:func\nWriteTft__FP3TFTP5OSTRMPPcPci = 0x1E1A08; // type:func\nCchOstrmPrintf__FP5OSTRMPcT1 = 0x1E1DB8; // type:func\n\nvprintf = 0x1E1EB0; // type:func\nprintf = 0x1E1F10; // type:func\nvsprintf = 0x1E1F58; // type:func\nsprintf = 0x1E1FD0; // type:func\n_vsnprintf = 0x1E2018; // type:func\njunk_001E20B0 = 0x1E20B0; // type:func\n_snprintf = 0x1E20B8; // type:func\njunk_001E20F8 = 0x1E20F8; // type:func\nstrlen = 0x1E2100; // type:func\nstrcpy = 0x1E2138; // type:func\nstrcpy1 = 0x1E2180; // type:func\nstrchr = 0x1E21D8; // type:func\n\njunk_001E2210 = 0x1E2210; // type:func\nUpperizePchz__FPc = 0x1E2218; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/thread.c\n////////////////////////////////////////////////////////////////\nSemaCreate__Fii = 0x1e2268; // type:func\njunk_001E22B8 = 0x1E22B8; // type:func\nInitCritSect__FP8CRITSECT = 0x1e22c0; // type:func\nEnterCritSect__FP8CRITSECT = 0x1e22f8; // type:func\nLeaveCritSect__FP8CRITSECT = 0x1e2358; // type:func\njunk_001E2390 = 0x1E2390; // type:func\nStartupThread__Fv = 0x1e2398; // type:func\n\ng_athread = 0x275958; // size:0xC\n\ng_abRenderLoopStack = 0x6056d0; // size:0x20000\n\n\n////////////////////////////////////////////////////////////////\n// P2/tn.c\n////////////////////////////////////////////////////////////////\nPtnfnFromTn__FP2TN                                         = 0x1E2420; // type:func\nGetTnfnNose__FP4TNFNP6CPDEFIP6VECTORP2TN                   = 0x1E2438; // type:func\nInitTn__FP2TN                                              = 0x1E2520; // type:func\nOnTnRemove__FP2TN                                          = 0x1E25F8; // type:func\nLoadTnFromBrx__FP2TNP18CBinaryInputStream                  = 0x1E2648; // type:func\nPostTnLoad__FP2TN                                          = 0x1E2758; // type:func\nSetTnTns__FP2TN3TNS                                        = 0x1E2778; // type:func\nFUN_001e2840__FP2TN3TNS                                    = 0x1E2840; // type:func\nUpdateTnCallback__FP2TN5MSGIDPv                            = 0x1E2870; // type:func\nUpdateTn__FP2TNf                                           = 0x1E2940; // type:func\nRenderTnSelf__FP2TNP2CMP2RO                                = 0x1E2988; // type:func\nFreezeTn__FP2TNi                                           = 0x1E29A8; // type:func\nFUN_001e29e8                                               = 0x1E29E8; // type:func\nCalculateTnCrv__FP2TNP6VECTORN21                           = 0x1E2A00; // type:func\nCalculateTnPos__FP2TNP6VECTORffP3CLQP2LM4FTNDT1            = 0x1E2BF0; // type:func\nActivateCptn__FP4CPTNPv                                    = 0x1E2E68; // type:func\nDeactivateCptn__FP4CPTNPv                                  = 0x1E30A0; // type:func\nSetCptn__FP4CPTNPv                                         = 0x1E30D8; // type:func\nRevokeCptn__FP4CPTNPv                                      = 0x1E30E0; // type:func\nFUN_001e30e8                                               = 0x1E30E8; // type:func\nUpdateCptn__FP4CPTNP6CPDEFIP3JOYf                          = 0x1E31F0; // type:func\nFUN_001e4578                                               = 0x1E4578; // type:func\nFUN_001e4880                                               = 0x1E4880; // type:func\nFUN_001e4888                                               = 0x1E4888; // type:func\nLoadTbspFromBrx__FP18CBinaryInputStreamPiPP5TSURFT1PP4TBSP = 0x1E4C48; // type:func\nFCheckTbspPoint__FP4TBSPP6VECTOR                           = 0x1E4DC0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/transition.c\n////////////////////////////////////////////////////////////////\n__11CTransition = 0x1E4E38; // type:func\nSet__11CTransitionPc3OIDT2i = 0x1E4E80; // type:func\nExecute__11CTransition = 0x1e4ea8; // type:func\nResetWorld__F6FTRANS = 0x1E5278; // type:func\ntransition__static_initialization_and_destruction_0 = 0x1E5328; // type:func\n_GLOBAL_$I$g_transition = 0x1E5358; // type:func\n\ng_transition = 0x275af0; // size:0x38\n\n\n////////////////////////////////////////////////////////////////\n// P2/turret.c\n////////////////////////////////////////////////////////////////\nInitTurret__FP6TURRET                    = 0x1E5378; // type:func\nFUN_001e53f8                             = 0x1E53F8; // type:func\nPostTurretLoad__FP6TURRET                = 0x1E5428; // type:func\nUpdateTurret__FP6TURRETf                 = 0x1E55D0; // type:func\nUpdateTurretActive__FP6TURRETP3JOYf      = 0x1E56A0; // type:func\nOnTurretActive__FP6TURRETiP2PO           = 0x1E5750; // type:func\nFFilterTurret__FP6TURRETP2SO             = 0x1E5888; // type:func\nUpdateTurretAim__FP6TURRET               = 0x1E5938; // type:func\nFireTurret__FP6TURRET                    = 0x1E5C78; // type:func\nHandleTurretMessage__FP6TURRET5MSGIDPv   = 0x1E5CE8; // type:func\nFIgnoreTurretIntersection__FP6TURRETP2SO = 0x1E5DA8; // type:func\nCollectTurretPrize__FP6TURRET3PCKP3ALO   = 0x1E5E08; // type:func\nGetTurretDiapi__FP6TURRETP6DIALOGP5DIAPI = 0x1E5E50; // type:func\nFUN_001e5e60                             = 0x1E5E60; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/tv.c\n////////////////////////////////////////////////////////////////\nInitTv__FP2TV5BLOTK                         = 0x1E5E70; // type:func\nPostTvLoad__FP2TV                           = 0x1E6188; // type:func\nGetTvItvbMinMax__FP2TVPiT1                  = 0x1E6268; // type:func\nDrawTvArea__FP2TVR4GIFSi                    = 0x1E62A8; // type:func\nDrawTvBands__FP2TVR4GIFS                    = 0x1E6600; // type:func\nDrawTvOutline__FP2TVR4GIFS                  = 0x1E6C20; // type:func\nDrawTv__FP2TV                               = 0x1E73B8; // type:func\nSetTvTvs__FP2TV3TVS                         = 0x1E7440; // type:func\nAcceptTvSpeaker__FP2TV                      = 0x1E7460; // type:func\nSetTvTvgs__FP2TV4TVGS                       = 0x1E7518; // type:func\nSetTvBlots__FP2TV5BLOTS                     = 0x1E76E0; // type:func\nUpdateTv__FP2TV                             = 0x1E77C0; // type:func\nRenderTv__FP2TV                             = 0x1E7C60; // type:func\nPreTvContext__FP3RPL                        = 0x1E80D8; // type:func\nPostTvContext__FP3RPL                       = 0x1E83E0; // type:func\nSetTvSpeaker__FP2TVP7SPEAKER                = 0x1E86E0; // type:func\nSetTvReplace__FP2TVP3ALO                    = 0x1E87F0; // type:func\nOnTvReset__FP2TV                            = 0x1E8840; // type:func\ntv__static_initialization_and_destruction_0 = 0x1E8878; // type:func\n_GLOBAL_$I$RGBA_Distortion                  = 0x1E88B0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/ub.c\n////////////////////////////////////////////////////////////////\nInitUbg__FP3UBG                    = 0x1E88D0; // type:func\nPostUbgLoad__FP3UBG                = 0x1E8948; // type:func\nPsoPadUbgClosest__FP3UBGP6VECTOR   = 0x1E89F0; // type:func\nOnUbgEnteringSgs__FP3UBG3SGSP4ASEG = 0x1E8A50; // type:func\nSgsNextUbgAI__FP3UBG               = 0x1E8D58; // type:func\nFDetectUbg__FP3UBG                 = 0x1E8DB0; // type:func\nFCanUbgAttack__FP3UBG              = 0x1E8DD0; // type:func\nDoUbgFreefallJump__FP3UBG          = 0x1E8E08; // type:func\nDoUbgFreefallLanding__FP3UBG       = 0x1E8E48; // type:func\nUpdateUbgGoal__FP3UBGi             = 0x1E8EF8; // type:func\nUpdateUbgSgs__FP3UBG               = 0x1E8FA8; // type:func\nFUN_001e8fe8                       = 0x1E8FE8; // type:func\nFIgnoreUbgIntersection__FP3UBGP2SO = 0x1E9038; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/ui.c\n////////////////////////////////////////////////////////////////\nStartupUi__Fv = 0x1E9088; // type:func\nInitUi__FP2UI = 0x1E90A8; // type:func\nPostUiLoad__FP2UI = 0x1E90E8; // type:func\nUpdateUi__FP2UI = 0x1e9108; // type:func\nPushUiActiveBlot__FP2UIP4BLOT = 0x1E9498; // type:func\nPopUiActiveBlot__FP2UI = 0x1E9570; // type:func\nDrawUi__Fv = 0x1e9648; // type:func\nRenderUi__Fv = 0x1e9668; // type:func\nResetUi__FP2UI = 0x1E9688; // type:func\nSetUiUis__FP2UI3UIS = 0x1E96F8; // type:func\nSetUiUPause__FP2UIf = 0x1E98E8; // type:func\nFUN_001e9970__Fv = 0x1E9970; // type:func\nFUN_001e9a10__Fv = 0x1E9A10; // type:func\nFUN_001e9a68__Fv = 0x1E9A68; // type:func\nFUN_001e9ad8__Fv = 0x1E9AD8; // type:func\ncheck_anticrack_collectibles_Fv = 0x1E9B30; // type:func\n\ng_ui = 0x275BC0;\n\n\n////////////////////////////////////////////////////////////////\n// P2/update.c\n////////////////////////////////////////////////////////////////\nUpdateSwObjects__FP2SWf     = 0x1E9C78; // type:func\nUpdateSwPosWorldPrev__FP2SW = 0x1E9E30; // type:func\nUpdateSwRealClock__FP2SWf   = 0x1E9EE8; // type:func\nUpdateSwDarkening__FP2SWf   = 0x1EA0A8; // type:func\nUpdateSw__FP2SWf            = 0x1EA118; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/util.c\n////////////////////////////////////////////////////////////////\nRadNormalize__Ff = 0x1EA408; // type:func\nGLimitAbs__Fff = 0x1EA480; // type:func\nGSmooth__FfffP3SMPPf = 0x1EA4B8; // type:func\nGSmoothA__FffffP4SMPAPf = 0x1EA620; // type:func\njunk_001EA720 = 0x1EA720; // type:func\nRadSmooth__FfffP3SMPPf = 0x1EA728; // type:func\nRadSmoothA__FffffP4SMPAPf = 0x1EA798; // type:func\nPosSmooth = 0x1EA818; // type:func\nSmoothMatrix = 0x1EA918; // type:func\nNRandInRange__Fii = 0x1EAA70; // type:func\nGRandInRange__Fff = 0x1EAAE0; // type:func\nGRandGaussian__Ffff = 0x1EAB48; // type:func\nFFloatsNear__Ffff = 0x1EAC68; // type:func\nCSolveQuadratic__FfffPf = 0x1EACA0; // type:func\nPrescaleClq__FP3CLQffT0 = 0x1EAD30; // type:func\nCalculateSinCos__FfPfT1 = 0x1EAD88; // type:func\nGTrunc__Fd = 0x1EAE78; // type:func\nGTrunc__Ff = 0x1EAF28; // type:func\nGModPositive__Fff = 0x1EAFE0; // type:func\nFitClq__FffffP3CLQ = 0x1EB018; // type:func\nFCheckLm__FP2LMf = 0x1EB050; // type:func\nFCheckAlm__FiP2LMf = 0x1EB080; // type:func\nGLimitLm__FP2LMf = 0x1EB0F8; // type:func\nSgnCompareG__FPfT0 = 0x1EB128; // type:func\nForce__FPv = 0x1EB160; // type:func\nMinimizeRange = 0x1EB168; // type:func\njunk_001EB458 = 0x1EB458; // type:func\n\ng_lmZeroOne = 0x275C60;\n\n\n////////////////////////////////////////////////////////////////\n// P2/vec.c\n////////////////////////////////////////////////////////////////\nSetVectorCylind__FP6VECTORfff = 0x1ED650; // type:func\nSetVectorSphere__FP6VECTORfff = 0x1ED6B0; // type:func\nSProjectVector__FP6VECTORT0 = 0x1ED738; // type:func\nGetNormalVectors__FP6VECTORN30 = 0x1ED780; // type:func\nGetNormalVector__FP6VECTORT0 = 0x1ED840; // type:func\njunk_001ED900 = 0x1ED900; // type:func\nRadBetweenVectors__FP6VECTORN20 = 0x1ED908; // type:func\nFindClosestPointBetweenLines__FP6VECTORN30PfT4T0 = 0x1EDA80; // type:func\nFindClosestPointBetweenLineSegments__FP6VECTORN40PfT0 = 0x1EDC08; // type:func\nCalculateVectorPanTilt__FP6VECTORPfT1 = 0x1EDDB0; // type:func\nConvertDeulToW__FP6VECTORN20 = 0x1EDE38; // type:func\nFCalculateMuzzleVelocity__FP6VECTORT0fT0P2SO = 0x1EDEF0; // type:func\nFCalculateMuzzleVelocity1 = 0x1EE090; // type:func\nFCalculateMuzzleVelocityAngle__FP6VECTORT0fT0P2SO = 0x1EE290; // type:func\nLimitVectorLength = 0x1EE2B0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/vifs.c\n////////////////////////////////////////////////////////////////\n__4VIFS                             = 0x1EE318; // type:func\njunk_001EE360                       = 0x1EE360; // type:func\nAlign__4VIFSi                       = 0x1EE368; // type:func\nAddVifBaseOffset__4VIFSii           = 0x1EE3B8; // type:func\nAddVifMscal__4VIFSPv                = 0x1EE3F0; // type:func\nAddVifMscalf__4VIFSPv               = 0x1EE420; // type:func\nAddVifFlush__4VIFS                  = 0x1EE450; // type:func\nAddVifFlusha__4VIFS                 = 0x1EE468; // type:func\nAddVifFlushe__4VIFS                 = 0x1EE480; // type:func\nAddVifStcycl__4VIFSii               = 0x1EE498; // type:func\nAddVifStrow__4VIFSP2QW              = 0x1EE4C0; // type:func\nAddVifStmask__4VIFSUi               = 0x1EE528; // type:func\nCbUnpackSetup__4VIFS3UPKii          = 0x1EE560; // type:func\nUnpackHelper__4VIFS3UPKiiPiPPUi     = 0x1EE5C8; // type:func\nAddVifUnpack__4VIFS3UPKiPvi         = 0x1EE668; // type:func\nAddVifUnpackRefs__4VIFS3UPKiPviPPPv = 0x1EE718; // type:func\nAddVifDirect__4VIFSiP2QWi           = 0x1EE7D0; // type:func\nAddVifDirectRefs__4VIFSiP2QWi       = 0x1EE850; // type:func\nAddVifGifs__4VIFSP4GIFS             = 0x1EE8D0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/vis.c\n////////////////////////////////////////////////////////////////\nInitVismap__FP6VISMAP                               = 0x1EE900; // type:func\nLoadVismapFromBrx__FP6VISMAPP18CBinaryInputStream   = 0x1EE930; // type:func\nGrfzonOneHop__FP6VISMAPP4VBSP                       = 0x1EE9D0; // type:func\nClipVbspSphereOneHop__FP6VISMAPP4VBSPG9VU_VECTORfPi = 0x1EEA40; // type:func\nClipVismapPointNoHop__FP6VISMAPP6VECTORPi           = 0x1EEBB0; // type:func\nClipVismapSphereOneHop__FP6VISMAPP6VECTORfPi        = 0x1EEB60; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/water.c\n////////////////////////////////////////////////////////////////\nInitWater__FP5WATER                          = 0x1EEC60; // type:func\nPostWaterLoad__FP5WATER                      = 0x1EECE0; // type:func\nCalculateWaterCurrent__FP5WATERP6VECTORN21   = 0x1EED68; // type:func\nUpdateSwXaList__FP2SWPP2XA                   = 0x1EEE50; // type:func\nUpdateWater__FP5WATERf                       = 0x1EEF90; // type:func\nAddWaterExternalAccelerations__FP5WATERP2XAf = 0x1EF3A8; // type:func\nHandleWaterMessage__FP5WATER5MSGIDPv         = 0x1EF3D8; // type:func\nUpdateWaterMergeGroup__FP5WATER              = 0x1EF520; // type:func\nUGetWaterSubmerged__FP5WATERP2SOP6VECTORT2   = 0x1EF5B8; // type:func\nUpdateWaterBounds__FP5WATER                  = 0x1EF768; // type:func\nFInflictWaterZap__FP5WATERP2XPP3ZPR          = 0x1EF808; // type:func\nPzpdEnsureWater__FP5WATER4ENSK               = 0x1EF828; // type:func\nFUN_001ef830                                 = 0x1EF830; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/waypoint.c\n////////////////////////////////////////////////////////////////\nInitWaypoint__FP8WAYPOINT                  = 0x1EF838; // type:func\nPostWaypointLoad__FP8WAYPOINT              = 0x1EF868; // type:func\nSetWaypointRsmg__FP8WAYPOINTi3OIDN22       = 0x1EF8C0; // type:func\nUpdateWaypoint__FP8WAYPOINTf               = 0x1EF8F8; // type:func\nSetWaypointWps__FP8WAYPOINT3WPS            = 0x1EF900; // type:func\nHandleWaypointMessage__FP8WAYPOINT5MSGIDPv = 0x1EF9C8; // type:func\nPwpsgNew__Fv                               = 0x1EFA30; // type:func\nAddWpsgWaypoint__FP4WPSGP8WAYPOINT         = 0x1EFA60; // type:func\nRemoveWpsgWaypoint__FP4WPSGP8WAYPOINT      = 0x1EFA88; // type:func\nUpdateWpsgCallback__FP4WPSG5MSGIDPv        = 0x1EFB20; // type:func\nEnsureWpsgCallback__FP4WPSG                = 0x1EFC98; // type:func\njunk_001EFCE0                              = 0x1EFCE0; // type:func\n\ns_asnipPostWaypointLoad = 0x275E10;\n\n// TODO: Where does this belong to?\ng_vtwpsg = 0x2505c0;\n\n\n////////////////////////////////////////////////////////////////\n// P2/wipe.c\n////////////////////////////////////////////////////////////////\nInitWipe__FP4WIPE                         = 0x1EFCE8; // type:func\nUpdateWipe__FP4WIPEP3JOY                  = 0x1EFD10; // type:func\nDrawWipe__FP4WIPE                         = 0x1EFEE0; // type:func\nActivateWipe__FP4WIPEP5TRANS5WIPEK        = 0x1EFFA0; // type:func\nSetWipeButtonTrans__FP4WIPEP5TRANS5WIPEK  = 0x1F00C0; // type:func\nFCatchWipeButtonTrans__FP4WIPEP3JOY5WIPES = 0x1F00F0; // type:func\njunk_001F0218                             = 0x1F0218; // type:func\nSetWipeWipes__FP4WIPE5WIPES               = 0x1F0220; // type:func\nWipeToWorldWarp                           = 0x1F0428; // type:func\n\ng_wipe = 0x275f80;\ng_pwipe = 0x275f84;\n\n\n////////////////////////////////////////////////////////////////\n// P2/wm.c\n////////////////////////////////////////////////////////////////\nFUN_001f0468                                   = 0x1F0468; // type:func\nFUN_001f0490                                   = 0x1F0490; // type:func\nFUN_001f0580                                   = 0x1F0580; // type:func\nPostWmLoad__FP2WM                              = 0x1F0660; // type:func\nBindWm__FP2WM                                  = 0x1F0758; // type:func\nRefreshWmMoveStats__FP2WM10WORLDLEVEL          = 0x1F0878; // type:func\nThrowWmDisplayState__FP2WM10WORLDLEVELi        = 0x1F08F0; // type:func\nCatchWmDisplayState__FP2WM                     = 0x1F0908; // type:func\nUpdateWm__FP2WMf                               = 0x1F0AE0; // type:func\nRenderWmAll__FP2WMP2CMP2RO                     = 0x1F0EB8; // type:func\nHandleWmMessage__FP2WM5MSGIDPv                 = 0x1F0F70; // type:func\nSetWmWms__FP2WM3WMS                            = 0x1F1050; // type:func\nShowWm__FP2WM10WORLDLEVEL3WMS                  = 0x1F1590; // type:func\nHideWm__FP2WM                                  = 0x1F1610; // type:func\nMoveWm__FP2WM3WMD                              = 0x1F1648; // type:func\nGetWmWorldPosScreen__FP2WM10WORLDLEVELP6VECTOR = 0x1F17A0; // type:func\nSetWmCursor__FP2WM10WORLDLEVEL                 = 0x1F18B0; // type:func\nPostWmcLoad__FP3WMC                            = 0x1F1960; // type:func\nUpdateWmcActive__FP3WMCP3JOY                   = 0x1F1A08; // type:func\nOnWmcActive__FP3WMCi                           = 0x1F1C90; // type:func\nDrawWmFan__FffffiG4RGBAT5i                     = 0x1F1E38; // type:func\nDrawWmc__FP3WMC                                = 0x1F20A8; // type:func\nwm__static_initialization_and_destruction_0    = 0x1F2688; // type:func\njunk_001F2728                                  = 0x1F2728; // type:func\n_GLOBAL_$I$U_WmFadedLevels                     = 0x1F2738; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/wr.c\n////////////////////////////////////////////////////////////////\nInitWr__FP2WR                                  = 0x1F2758; // type:func\nApplyWrGlob__FP2WRP3ALOP4GLOB                  = 0x1F2798; // type:func\nUpdateWrStateVectors__FP2WR                    = 0x1F2840; // type:func\nWarpWrTransform__FP2WRfP6VECTORP7MATRIX3T2T3T2 = 0x1F2EF0; // type:func\nGetWrBounds__FP2WRP6VECTOR                     = 0x1F3140; // type:func\nUNoise__Fi                                     = 0x1F31F8; // type:func\nUNoise__Ffff                                   = 0x1F3250; // type:func\nUBias__Fff                                     = 0x1F3328; // type:func\nGFromOnz__FP3ONZ                               = 0x1F3358; // type:func\nUpdateWrMatrixes__FP2WR                        = 0x1F3408; // type:func\nAddWrCircleWarp__FP2WR                         = 0x1F36E8; // type:func\nAddWrBendWarp__FP2WR                           = 0x1F3768; // type:func\nPwreGetWrCur__FP2WR4ENSK4WREK                  = 0x1F37D8; // type:func\nPwreGetWrCircle__FP2WR4ENSK                    = 0x1F3810; // type:func\nPwreGetWrBend__FP2WR4ENSK                      = 0x1F3830; // type:func\nSetWrWavelength__FP2WRf                        = 0x1F3850; // type:func\nGetWrWavelength__FP2WRPf                       = 0x1F38A0; // type:func\nAddOnzOnze__FP3ONZffff                         = 0x1F38F0; // type:func\nAddWrBendNoise__FP2WRffff                      = 0x1F3928; // type:func\nAddWrSwivelNoise__FP2WRffff                    = 0x1F3990; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/xform.c\n////////////////////////////////////////////////////////////////\nInitXfm__FP3XFM                               = 0x1F39F8; // type:func\nLoadXfmFromBrx__FP3XFMP18CBinaryInputStream   = 0x1F3A40; // type:func\nSetXfmParent__FP3XFMP3ALO                     = 0x1F3A90; // type:func\nApplyXfmProxy__FP3XFMP5PROXY                  = 0x1F3AF0; // type:func\nConvertXfmLocalToWorld__FP3XFMP6VECTORT1      = 0x1F3B48; // type:func\nGetXfmPos__FP3XFMP6VECTOR                     = 0x1F3BD8; // type:func\nGetXfmMat__FP3XFMP7MATRIX3                    = 0x1F3C08; // type:func\nPwarpFromOid__F3OIDT0                         = 0x1F3C38; // type:func\nLoadWarpFromBrx__FP4WARPP18CBinaryInputStream = 0x1F3D80; // type:func\nCloneWarp__FP4WARPT0                          = 0x1F3EE0; // type:func\nPostWarpLoad__FP4WARP                         = 0x1F3F80; // type:func\nTriggerWarp__FP4WARP                          = 0x1F4008; // type:func\nSetWarpRsmg__FP4WARPi3OIDN22                  = 0x1F42D0; // type:func\nFUN_001F4308                                  = 0x1F4308; // type:func\nTeleportSwPlayer__FP2SW3OIDT1                 = 0x1F4318; // type:func\nPexitDefault__Fv                              = 0x1F4378; // type:func\nTriggerDefaultExit__Fi5WIPEK                  = 0x1F4408; // type:func\nLoadExitFromBrx__FP4EXITP18CBinaryInputStream = 0x1F4500; // type:func\nPostExitLoad__FP4EXIT                         = 0x1F4660; // type:func\nSetExitExits__FP4EXIT5EXITS                   = 0x1F4760; // type:func\nTriggerExit__FP4EXIT                          = 0x1F4808; // type:func\nWipeExit__FP4EXIT                             = 0x1F4A30; // type:func\nUpdateExit__FfP4EXIT                          = 0x1F4AE0; // type:func\nInitCamera__FP6CAMERA                         = 0x1F4E18; // type:func\nPostCameraLoad__FP6CAMERA                     = 0x1F4E48; // type:func\nEnableCamera__FP6CAMERA                       = 0x1F4ED0; // type:func\nDisableCamera__FP6CAMERA                      = 0x1F4F20; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// P2/zap.c\n////////////////////////////////////////////////////////////////\nInitTzp__FP3TZP                 = 0x1F4F70; // type:func\nPostTzpLoad__FP3TZP             = 0x1F4FD8; // type:func\nUpdateTzp__FP3TZPf              = 0x1F5008; // type:func\nCloneTzp__FP3TZPT0              = 0x1F51A0; // type:func\nRenderTzpAll__FP3TZPP2CMP2RO    = 0x1F51C8; // type:func\nFInflictTzpZap__FP3TZPP2XPP3ZPR = 0x1F51E8; // type:func\nPzpdEnsureTzp__FP3TZP4ENSK      = 0x1F5208; // type:func\nFUN_001F5210__FP3TZP            = 0x1F5210; // type:func\nInitVolzp__FP5VOLZP             = 0x1F5218; // type:func\nUpdateVolzp__FP5VOLZPf          = 0x1F5268; // type:func\nInitZpd__FP3ZPDP2SO             = 0x1F5590; // type:func\nPostZpdLoad__FP3ZPD             = 0x1F55A8; // type:func\nApplyZpdThrow__FP3ZPDP2PO       = 0x1F56D8; // type:func\nInflictZpdZap__FP3ZPDP2XPP3ZPR  = 0x1F57E0; // type:func\nAddZpdZapObject__FP3ZPD3OID     = 0x1F5840; // type:func\nAddZpdZapLo__FP3ZPDP2LO         = 0x1F5868; // type:func\nRemoveZpdZapLo__FP3ZPDP2LO      = 0x1F5930; // type:func\n\n\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n// LIBRARIES\n////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nmemcmp = 0x1F59C4; // type:func\nmemcpy = 0x01f5a58; // type:func\nmemmove = 0x1f5b08; // type:func\nmemset = 0x1f5c0c; // type:func\nqsort =  0x1f5cd0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// /usr/local/sce/ee/gcc/src/newlib/libc/stdlib/rand.c\n////////////////////////////////////////////////////////////////\nsrand = 0x1F66F8; // type:func\nrand = 0x1F6708; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// klib.s\n////////////////////////////////////////////////////////////////\nCreateThread = 0x1F6A10; // type:func\nChangeThreadPriority = 0x1F6A50; // type:func\nGetThreadId = 0x1F6A90; // type:func\nCreateSema = 0x1F6B20; // type:func\nSignalSema = 0x1F6B40; // type:func\nWaitSema = 0x1F6B60; // type:func\nFlushCache = 0x1F6C20; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// sifrpc.c\n////////////////////////////////////////////////////////////////\nsceSifInitRpc      = 0x1F7BE8; // type:func\nsceSifBindRpc      = 0x1F80C0; // type:func\nsceSifCallRpc      = 0x1F8290; // type:func\nsceSifCheckStatRpc = 0x1F8480; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// filestub.c\n////////////////////////////////////////////////////////////////\nsceFsReset = 0x1F8BF8; // type:func\nsceClose   = 0x1F8C38; // type:func\nsceRead    = 0x1F8DB8; // type:func\nsceIoctl   = 0x1F92E8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// eeloadfile.c\n////////////////////////////////////////////////////////////////\nsceSifLoadFileReset = 0x1F9820; // type:func\nsceSifLoadModule    = 0x1F9A90; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// iopreset.c\n////////////////////////////////////////////////////////////////\nsceSifSyncIop   = 0x1F9C18; // type:func\nsceSifRebootIop = 0x1F9C50; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// /usr/local/sce/ee/gcc/src/newlib/libc/stdlib/rand.c\n////////////////////////////////////////////////////////////////\n__main__Fv = 0x1fae18; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// /usr/local/sce/ee/gcc/build/gcc/dp-bit.c\n////////////////////////////////////////////////////////////////\ndpcmp = 0x1FD308; // type:func\nfptodp = 0x1FD868; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// vu/vu.c\n////////////////////////////////////////////////////////////////\nsceGsResetPath = 0x2018E8; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// libdma.c\n////////////////////////////////////////////////////////////////\nmemclr = 0x202768; // type:func\nsceDmaGetChan = 0x2027A0; // type:func\nsceDmaReset = 0x2027C8; // type:func\nsceDmaPutEnv = 0x2028a8; // type:func\nsceDmaSend = 0x202A80; // type:func\nsceDmaRecv = 0x202b68; // type:func\nsceDmaSync = 0x202c38; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// ../eecdvd.c\n////////////////////////////////////////////////////////////////\nsceCdSync        = 0x2032C8; // type:func\nsceCdInit        = 0x203548; // type:func\nsceCdDiskReady   = 0x203828; // type:func\nsceCdMmode       = 0x203A20; // type:func\nsceCdRead        = 0x203B18; // type:func\nsceCdGetDiskType = 0x203CF8; // type:func\nsceCdGetError    = 0x203D90; // type:func\nsceCdBreak       = 0x203E28; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// libpad.c\n////////////////////////////////////////////////////////////////\nscePadInit = 0x2040E8; // type:func\nscePadPortOpen = 0x2042C8; // type:func\nscePadGetState = 0x204678; // type:func\nscePadInfoAct = 0x2046D0; // type:func\nscePadInfoMode = 0x2047F8; // type:func\nscePadSetMainMode = 0x204930; // type:func\nscePadSetActDirect = 0x2049E8; // type:func\nscePadSetActAlign = 0x204AA8; // type:func\nscePadInfoPressMode = 0x204CE8; // type:func\nscePadEnterPressMode = 0x204D48; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// /usr/local/sce/ee/gcc/src/newlib/libm/math/sf_cos.c\n////////////////////////////////////////////////////////////////\ncosf = 0x205210; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// /usr/local/sce/ee/gcc/src/newlib/libm/math/sf_tan.c\n////////////////////////////////////////////////////////////////\ntanf = 0x2054F0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// sce/ee/gcc/src/newlib/libm/math/wf_atan2.c\n////////////////////////////////////////////////////////////////\natan2f = 0x205778; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// /usr/local/sce/ee/gcc/src/newlib/libm/math/wf_fmod.c\n////////////////////////////////////////////////////////////////\nfmodf = 0x2058a0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// libmc.c\n////////////////////////////////////////////////////////////////\nmcInit__Fv = 0x2093F0; // type:func\n\n\n////////////////////////////////////////////////////////////////\n// misc\n////////////////////////////////////////////////////////////////\n__floatdisf = 0x1fb6b0; // type:func\n"
  },
  {
    "path": "config/symbol_addrs_may19.txt",
    "content": "ENTRYPOINT = 0x100008; // type:func\n_exit = 0x1000B8; // type:func\n_root = 0x1000C0; // type:func\nRefThunkBasicDERIVED_FROMQ = 0x1000C8; // type:func\nRefThunkLoREMOVEFnUser = 0x1001B8; // type:func\nRefThunkLoREMOVEFn = 0x100298; // type:func\nRefThunkLoADD = 0x100378; // type:func\nRefThunkLoCLONE = 0x100458; // type:func\nRefThunkLoSETPARENT = 0x100560; // type:func\nRefThunkLoANCESTORQ = 0x100650; // type:func\nRefThunkLoMATCHES_NAMEQ = 0x100740; // type:func\nRefThunkLoCUSTOM_BOOL_PROPERTY = 0x100830; // type:func\nRefThunkLoCUSTOM_INT_PROPERTY = 0x100938; // type:func\nRefThunkLoCUSTOM_FLOAT_PROPERTY = 0x100A40; // type:func\nRefThunkLoCUSTOM_CLQ_PROPERTY = 0x100B48; // type:func\nRefThunkLoCUSTOM_LM_PROPERTY = 0x100C60; // type:func\nRefThunkLoCUSTOM_OID_PROPERTY = 0x100D78; // type:func\nRefThunkLoCUSTOM_VECTOR_PROPERTY = 0x100E80; // type:func\nRefThunkAloINVALIDATE_LIGHTING = 0x100F98; // type:func\nRefThunkAloROTATION_MATCHES_VELOCITY = 0x101078; // type:func\nRefThunkAloSCROLLING_MASTER_SPEEDS = 0x101190; // type:func\nRefThunkAloEYES_CLOSED = 0x101298; // type:func\nRefThunkAloSTART_SOUND = 0x101388; // type:func\nRefThunkAloSTOP_SOUND = 0x1014D0; // type:func\nRefThunkAloFADE_IN = 0x1015B0; // type:func\nRefThunkAloFADE_OUT = 0x1016A0; // type:func\nRefThunkAloCURRENT_SMA = 0x101790; // type:func\nRefThunkAloCURRENT_ASEGA = 0x101880; // type:func\nRefThunkAloNEAREST_ASEGA = 0x101970; // type:func\nRefThunkAloMATCH_OTHER_OBJECT = 0x101A50; // type:func\nRefThunkSoEDGE_GRAB = 0x101B40; // type:func\nRefThunkWarpSET_SM_GOAL = 0x101C30; // type:func\nRefThunkWarpTRIGGER = 0x101D58; // type:func\nRefThunkExitTRIGGER = 0x101E38; // type:func\nRefThunkAsegAPPLY = 0x101F18; // type:func\nRefThunkAsegENSURE = 0x102040; // type:func\nRefThunkAsegFIND_LABEL = 0x102180; // type:func\nRefThunkAsegaSEEK = 0x102270; // type:func\nRefThunkAsegaRETRACT = 0x102388; // type:func\nRefThunkAsegaSNAP = 0x102468; // type:func\nRefThunkBrkBREAK = 0x102558; // type:func\nRefThunkButtonSET_SM_GOAL = 0x102638; // type:func\nRefThunkVolbtnSET_SM_GOAL = 0x102760; // type:func\nRefThunkPoMAKE_ACTIVE = 0x102888; // type:func\nRefThunkPoINVULNERABLEQ = 0x102968; // type:func\nRefThunkAlarmTRIGGER = 0x102A58; // type:func\nRefThunkAlarmSET_SM_GOAL = 0x102B48; // type:func\nRefThunkSensorENABLE = 0x102C70; // type:func\nRefThunkSensorDISABLE = 0x102D60; // type:func\nRefThunkLasenEXTEND = 0x102E40; // type:func\nRefThunkLasenRETRACT = 0x102F30; // type:func\nRefThunkEmitterPAUSE = 0x103020; // type:func\nRefThunkEmitterPAUSE_FOREVER = 0x103110; // type:func\nRefThunkEmitterUNPAUSE = 0x1031F0; // type:func\nRefThunkEmitterADD_SKELETON = 0x1032D0; // type:func\nRefThunkExploADD_SKELETON = 0x103420; // type:func\nRefThunkExplsEXPLODE = 0x103570; // type:func\nRefThunkExplsEXPLODE_OVR = 0x103650; // type:func\nRefThunkExplgEXPLODE = 0x1037B8; // type:func\nRefThunkSmAPPLY = 0x103898; // type:func\nRefThunkSmaRETRACT = 0x1039B0; // type:func\nRefThunkSwDEFAULT_REVERB = 0x103A90; // type:func\nRefThunkSwPUSH_REVERB = 0x103B98; // type:func\nRefThunkSwPOP_REVERB = 0x103CA0; // type:func\nRefThunkSwLEVEL_VISITEDQ = 0x103D80; // type:func\nRefThunkSwLEVEL_PRIMARYQ = 0x103E70; // type:func\nRefThunkSwLEVEL_SECONDARYQ = 0x103F60; // type:func\nRefThunkSwLEVEL_TERTIARYQ = 0x104050; // type:func\nRefThunkSwCANCEL_DIALOG = 0x104140; // type:func\nRefThunkCmPUSH_LOOK_KIND = 0x104220; // type:func\nRefThunkCmPOP_LOOK_KIND = 0x104310; // type:func\nRefThunkCmLOOK_KIND = 0x1043F0; // type:func\nRefThunkCmSET_SNIPER_FOCUS = 0x1044D0; // type:func\nRefThunkCmJOLT = 0x1045E8; // type:func\nRefThunkClueBREAK = 0x1046C8; // type:func\nRefThunkPipeCAMERA_MANUAL_OFFSET = 0x1047A8; // type:func\nRefThunkStepguardUSE_ANIMATION = 0x1048B0; // type:func\nRefThunkStepguardUSE_ANIMATION_IMMEDIATE = 0x1049B8; // type:func\nRefThunkStepguardMATCH_ANIMATION_PHASE = 0x104AC0; // type:func\nRefThunkStepguardADD_ATTACK_EFFECT = 0x104BE8; // type:func\nRefThunkStepguardUSE_DEATH_ANIMATION = 0x104CF0; // type:func\nRefThunkStepguardSET_STATE_EXTERNAL = 0x104DF8; // type:func\nRefThunkStepguardUSE_PHYS = 0x104F00; // type:func\nRefThunkStepguardJUMP = 0x105008; // type:func\nRefThunkStepguardSET_PATROL_ANIMATION = 0x1050E8; // type:func\nRefThunkSmartguardUSE_FLASHLIGHT_TARGET = 0x1051D8; // type:func\nRefThunkBombPRIME = 0x1052E0; // type:func\nRefThunkBombDETONATE = 0x1053D0; // type:func\nRefThunkCanFIRE_AT_POSITION = 0x1054B0; // type:func\nRefThunkJtTHROW = 0x1055B0; // type:func\nRefThunkJtUNHOOK = 0x1056D8; // type:func\nRefThunkJtPROFILE = 0x1057B8; // type:func\nRefThunkJtADD_SPEED_BOOST = 0x1058A8; // type:func\nRefThunkJtPLACE_ON_PIPE = 0x105998; // type:func\nRefThunkRchmSET_NATURAL_COEFFICIENTS = 0x105A88; // type:func\nRefThunkRchmSET_CENTER_COEFFICIENTS = 0x105BA0; // type:func\nRefThunkDartgunSTART_TARGET_AREA_CHANGE = 0x105CB8; // type:func\nRefThunkDartgunADD_TARGET_AREA_TARGET = 0x105D98; // type:func\nRefThunkWaypointSET_SM_GOAL = 0x105E88; // type:func\nRefThunkJloACTIVATE = 0x105FB0; // type:func\nRefThunkJloDEACTIVATE = 0x106090; // type:func\nRefThunkRwmADD_AMMO = 0x106170; // type:func\nRefThunkRwmENABLE_CACHE = 0x106298; // type:func\nRefThunkRwmDISABLE_CACHE = 0x106388; // type:func\nRefThunkRwmRESIZE_CACHE = 0x106478; // type:func\nRefThunkRwmRELOAD = 0x106580; // type:func\nRefThunkRwmFIRE = 0x106660; // type:func\nRefThunkRwmCLEAR_FIRE_INFO = 0x106750; // type:func\nRefThunkRwmCLEAR_TARGET_INFO = 0x106830; // type:func\nRefThunkRwmCLEAR_AIM_CONSTRAINTS = 0x106910; // type:func\nRefThunkDialogINSTRUCT = 0x1069F0; // type:func\nRefThunkDialogCONFRONT = 0x106AD0; // type:func\nRefThunkDialogADD_DIALOG_EQUIVALENCE = 0x106BB0; // type:func\nRefThunkDialogTRIGGER = 0x106CB8; // type:func\nRefThunkDialogUNTRIGGER = 0x106D98; // type:func\nRefThunkLockgTRIGGER = 0x106E78; // type:func\nRefThunkWrADD_CIRCLE_WARP = 0x106F58; // type:func\nRefThunkWrADD_BEND_WARP = 0x107038; // type:func\nRefThunkWrADD_BEND_NOISE = 0x107118; // type:func\nRefThunkWrADD_SWIVEL_NOISE = 0x107240; // type:func\nRefThunkVaultADD_GOAD_DIALOG = 0x107368; // type:func\nRefThunkCrbrainACTIVATE = 0x107470; // type:func\nRefThunkCrbrainSCORE = 0x107550; // type:func\nRefThunkMgcGENERATE = 0x107640; // type:func\nRefThunkSuvADD_BOOST_OPPORTUNITY = 0x107758; // type:func\nRefThunkSuvADD_BOOST_COLLECT = 0x107848; // type:func\nRefThunkSuvADD_CHECK_POINT = 0x107938; // type:func\nRefThunkSuvADD_FEATURE = 0x107A28; // type:func\nRefThunkSuvRESET = 0x107B68; // type:func\nRefThunkVolCHECK_POINT = 0x107C48; // type:func\nRefThunkMurrayADD_ENEMY = 0x107D48; // type:func\nRefThunkSwpSET_SHAPE = 0x107E38; // type:func\nRefThunkJackADD_PRIZE = 0x107F40; // type:func\nRefThunkLgnbATTACK = 0x108058; // type:func\nRefThunkJsgCLEAR = 0x108158; // type:func\nRefThunkJsgAPPLY = 0x108238; // type:func\nRefThunkJsgRETRACT = 0x108328; // type:func\nRefThunkJsgSET_CONTEXT = 0x108408; // type:func\nRefThunkJsgCUT = 0x1084F8; // type:func\nRefThunkJsgSET_FOCUS = 0x1085E8; // type:func\nRefThunkJsgCALL_SPLICE = 0x1086D8; // type:func\nRefThunkJsgSET_TUNNEL = 0x1087C8; // type:func\nRefThunkJsgPAUSE = 0x1088B8; // type:func\nRefThunkJsgJUMP = 0x1089C0; // type:func\nRefThunkJsgRUN = 0x108AE8; // type:func\nRefThunkJsgCLIMB = 0x108C00; // type:func\nRefThunkJsgATTACK = 0x108D18; // type:func\nRefThunkJsgCALL_ANIMATION = 0x108E30; // type:func\nRefThunkJsgSET_CLOCK_SPEED = 0x108F38; // type:func\nBuildEopids = 0x109028; // type:func\nRefOpAdd = 0x110DF0; // type:func\nRefOpSub = 0x111118; // type:func\nRefOpMult = 0x111440; // type:func\nRefOpDiv = 0x111B20; // type:func\nRefOpPrint = 0x1120A8; // type:func\nRefOpPrintFrame = 0x112118; // type:func\nRefOpPrintSidebag = 0x112188; // type:func\nRefOpIntEqual = 0x1121F8; // type:func\nRefCmp = 0x112280; // type:func\nRefOpL = 0x112408; // type:func\nRefOpLE = 0x112440; // type:func\nRefOpG = 0x112478; // type:func\nRefOpGE = 0x1124B0; // type:func\nRefOpEqv = 0x1124E8; // type:func\nRefEqualHelper = 0x1125C0; // type:func\nRefOpEqual = 0x112930; // type:func\nRefOpIsBoolean = 0x112968; // type:func\nRefOpIsNum = 0x1129F0; // type:func\nRefOpIsFloat = 0x112A78; // type:func\nRefOpIsInteger = 0x112B00; // type:func\nRefOpIsSymbol = 0x112B88; // type:func\nRefOpIsVector = 0x112C10; // type:func\nRefOpIsMatrix = 0x112C98; // type:func\nRefOpIsClq = 0x112D20; // type:func\nRefOpIsLm = 0x112DA8; // type:func\nRefOpIsSmp = 0x112E30; // type:func\nRefOpIsList = 0x112EB8; // type:func\nRefOpIsNull = 0x112F50; // type:func\nRefOpIsObject = 0x112FD0; // type:func\nRefOpIsNullObj = 0x113058; // type:func\nRefOpIsMethod = 0x1130E8; // type:func\nRefOpIsProcedure = 0x113170; // type:func\nRefOpAreNear = 0x113208; // type:func\nRefOpNot = 0x1132E0; // type:func\nRefOpCons = 0x113370; // type:func\nRefOpCar = 0x113448; // type:func\nRefOpCdr = 0x1134C8; // type:func\nRefOpSetCadr = 0x113568; // type:func\nRefOpSetCar = 0x113630; // type:func\nRefOpSetCdr = 0x113668; // type:func\nRefOpLength = 0x1136A0; // type:func\nRefOpNth = 0x113760; // type:func\nRefOpIsMember = 0x113830; // type:func\nRefOpList = 0x113A10; // type:func\nRefOpAppend = 0x113A48; // type:func\nRefOpMap = 0x113C08; // type:func\nRefOpFilter = 0x113EA8; // type:func\nRefOpForEach = 0x1141A8; // type:func\nRefOpEval = 0x1143D8; // type:func\nRefOpVector = 0x1144B8; // type:func\nRefOpMatrix = 0x1145E8; // type:func\nRefOpSetMusicRegister = 0x1147E8; // type:func\nRefOpClq = 0x114870; // type:func\nRefOpLm = 0x1149A0; // type:func\nRefOpSmp = 0x114AC0; // type:func\nRefOpGetElement = 0x114C10; // type:func\nRefOpRandomSeed = 0x114E30; // type:func\nRefOpRandom = 0x114EE0; // type:func\nRefUfo = 0x114FB0; // type:func\nRefOpSqrt = 0x115078; // type:func\nRefOpSin = 0x1150B0; // type:func\nRefOpCos = 0x1150E8; // type:func\nRefOpTan = 0x115120; // type:func\nRefOpAsin = 0x115158; // type:func\nRefOpAcos = 0x115190; // type:func\nRefOpAtan = 0x1151C8; // type:func\nRefOpRadNormalize = 0x115200; // type:func\nRefOpAtan2 = 0x115238; // type:func\nRefOpVectorDotProduct = 0x115308; // type:func\nRefOpVectorCrossProduct = 0x1153B0; // type:func\nRefOpVectorLth = 0x115460; // type:func\nRefOpVectorDistance = 0x115508; // type:func\nRefOpVectorDistanceSquared = 0x115620; // type:func\nRefOpVectorNormalize = 0x115720; // type:func\nRefOpVectorProjectNormal = 0x115878; // type:func\nRefOpVectorProjectTangent = 0x115930; // type:func\nRefOpVectorBallisticVelocity = 0x1159E8; // type:func\nRefOpVectorRadianNormal = 0x115B00; // type:func\nRefOpMatrixTranspose = 0x115C08; // type:func\nRefOpMatrixInvert = 0x115CB8; // type:func\nRefOpMatrixCalculateDmat = 0x115D68; // type:func\nRefOpMatrixInterpolateRotate = 0x115E18; // type:func\nRefOpMatrixDecomposeToTranslate = 0x115F98; // type:func\nRefOpMatrixDecomposeToRotate = 0x116030; // type:func\nRefOpMatrixDecomposeToEuler = 0x116100; // type:func\nRefOpMatrixDecomposeToRadianNormal = 0x1161B0; // type:func\nRefOpMatrixLookAt = 0x1162B8; // type:func\nRefOpMatrixTiltUpright = 0x1163A8; // type:func\nRefOpClqEvaluate = 0x116480; // type:func\nRefOpClqEvaluateLm = 0x116550; // type:func\nRefOpClqFit = 0x116658; // type:func\nRefOpLmLimit = 0x1167D0; // type:func\nRefOpLmCheck = 0x116898; // type:func\nRefOpFloor = 0x116960; // type:func\nRefOpCeiling = 0x1169E8; // type:func\nRefOpRound = 0x116A78; // type:func\nRefOpTruncate = 0x116B08; // type:func\nRefOpAbs = 0x116B90; // type:func\nRefOpMaximum = 0x116C68; // type:func\nRefOpMinimum = 0x116DB0; // type:func\nRefOpModulo = 0x116EF8; // type:func\nRefOpCurrentTime = 0x116F90; // type:func\nRefOpScheduleCallback = 0x117008; // type:func\nRefOpDeferObjectUpdate = 0x1172A8; // type:func\nRefOpObjectOption = 0x117358; // type:func\nRefOpAddO = 0x1174C8; // type:func\nRefOpEnsureO = 0x117500; // type:func\nRefOpSetO = 0x117538; // type:func\nRefOpGetO = 0x117570; // type:func\nRefPairFromAplo = 0x1175A8; // type:func\nRefOpFindObject = 0x1176E0; // type:func\nRefOpFindObjects = 0x117788; // type:func\nRefOpFindNearestObject = 0x117870; // type:func\nRefOpFindNearestObjects = 0x117910; // type:func\nRefOpFindPlayerObject = 0x1179F0; // type:func\nRefOpFindWorldObject = 0x117A70; // type:func\nRefOpFindCameraObject = 0x117AE8; // type:func\nRefOpFindClassObjects = 0x117B60; // type:func\nRefOpFindObjectsInBoundingBox = 0x117C48; // type:func\nRefOpFindObjectsInBoundingSphere = 0x117D70; // type:func\nFUN_00117da0 = 0x117DA0; // type:func\nRefOpHitTestObjectsImpl = 0x117E98; // type:func\nRefOpHitTestObjects = 0x118140; // type:func\nRefOpHitTestObjectsFirst = 0x118208; // type:func\nRefOpConvertObjectPosition = 0x1182D0; // type:func\nRefOpConvertObjectVector = 0x118388; // type:func\nRefOpConvertObjectMatrix = 0x118440; // type:func\nRefOpNearClipCenter = 0x118508; // type:func\nRefOpStartSound = 0x1185B8; // type:func\nRefOpStopSound = 0x1186A0; // type:func\nRefOpStartRumble = 0x118728; // type:func\nRefOpEmitSmokeCloud = 0x1187F0; // type:func\nRefOpPredictAnimationEffect = 0x1188B8; // type:func\nVU_FLOAT__VU_FLOAT = 0x118CF0; // type:func\nVU_VECTOR__VU_VECTOR = 0x118D10; // type:func\nVECTOR__operatorEQ = 0x118D20; // type:func\noperatorSTAR = 0x118D30; // type:func\nsqrtf = 0x118D48; // type:func\nRefEvalSymbol = 0x118D58; // type:func\nRefEvalSet = 0x118DE8; // type:func\nRefEvalDefine = 0x118EF0; // type:func\nRefEvalAssert = 0x118FF8; // type:func\nRefEvalIf = 0x119128; // type:func\nRefEvalOr = 0x119278; // type:func\nRefEvalAnd = 0x1193C8; // type:func\nRefEvalCond = 0x119520; // type:func\nRefEvalCase = 0x119708; // type:func\nRefEvalLet = 0x1199A8; // type:func\nRefEvalWhile = 0x119BB0; // type:func\nRefEvalLambda = 0x119D00; // type:func\nRefEvalLambdaBody = 0x119E10; // type:func\nRefEvalBegin = 0x119F00; // type:func\nRefEvalApply = 0x11A010; // type:func\nRefEvalImport = 0x11A4E0; // type:func\nRefEval = 0x11A618; // type:func\nCFrame__SetSingleParent = 0x11A8F8; // type:func\nCFrame__AddParent = 0x11A908; // type:func\nCFrame__RefAddBinding = 0x11A928; // type:func\nCFrame__RefSetBinding = 0x11A9F0; // type:func\nCFrame__FFindBinding = 0x11AAB8; // type:func\nCFrame__PrefFindBinding = 0x11AB08; // type:func\nCFrame__CloneTo = 0x11AC00; // type:func\nPframeNew = 0x11ACE8; // type:func\nDeleteFrame = 0x11AD80; // type:func\nCGc__CGc = 0x11ADE8; // type:func\nCGc__~CGc = 0x11ADF0; // type:func\nCGc__Startup = 0x11AE20; // type:func\nCGc__Shutdown = 0x11AE30; // type:func\nCGc__AddRootFrame = 0x11AE38; // type:func\nCGc__AddRootSidebag = 0x11AE80; // type:func\nCGc__PushFrame = 0x11AEA0; // type:func\nCGc__PframePop = 0x11AEC0; // type:func\nCGc__PushPair = 0x11AEE8; // type:func\nCGc__PpairPop = 0x11AF08; // type:func\nCGc__PushProc = 0x11AF30; // type:func\nCGc__PprocPop = 0x11AF50; // type:func\nCGc__UpdateRecyclable = 0x11AF78; // type:func\nCGc__MarkLiveObjects = 0x11AFD0; // type:func\nCGc__Collect = 0x11B390; // type:func\n__static_initialization_and_destruction_0 = 0x11B610; // type:func\n_GLOBAL_$I$g_gc = 0x11B660; // type:func\n_GLOBAL_$D$g_gc = 0x11B688; // type:func\nPmethodNew = 0x11B6B0; // type:func\nCPair__CloneTo = 0x11B700; // type:func\nPpairNew = 0x11B788; // type:func\nDeletePair = 0x11B7F0; // type:func\nCProc__CloneTo = 0x11B818; // type:func\nPprocNew = 0x11B848; // type:func\nCRef__CRef = 0x11B898; // type:func\nCRef__CRef1 = 0x11B8A8; // type:func\nCRef__~CRef = 0x11B8F8; // type:func\nCRef__operatorEQ = 0x11B948; // type:func\nCRef__operatorEQEQ = 0x11B9A8; // type:func\nCRef__CloneTo = 0x11BB10; // type:func\nCRef__Decref = 0x11BD20; // type:func\nCRef__Incref = 0x11BDD8; // type:func\nCRef__SetTag = 0x11BE90; // type:func\nCRef__SetS32 = 0x11BED0; // type:func\nCRef__SetF32 = 0x11BF18; // type:func\nCRef__SetBool = 0x11BF60; // type:func\nCRef__SetSymid = 0x11BFB8; // type:func\nCRef__SetBifk = 0x11C000; // type:func\nCRef__SetPair = 0x11C048; // type:func\nCRef__SetProc = 0x11C090; // type:func\nCRef__SetVector = 0x11C0D8; // type:func\nCRef__SetMatrix = 0x11C130; // type:func\nCRef__SetClq = 0x11C188; // type:func\nCRef__SetLm = 0x11C1E0; // type:func\nCRef__SetSmp = 0x11C238; // type:func\nCRef__SetBasic = 0x11C290; // type:func\nCRef__SetMethod = 0x11C2D8; // type:func\nCRef__RefCoerceS32 = 0x11C320; // type:func\nCRef__RefCoerceF32 = 0x11C3C8; // type:func\nPpairSerializeIn = 0x11C470; // type:func\nCSidebag__RefAddBinding = 0x11C818; // type:func\nCSidebag__RefSetBinding = 0x11C8E0; // type:func\nCSidebag__FFindBinding = 0x11CA30; // type:func\nCSidebag__CloneTo = 0x11CAB0; // type:func\nPsidebagNew = 0x11CB68; // type:func\nStartupSplice = 0x11CC00; // type:func\nShutdownSplice = 0x11CCC8; // type:func\n__static_initialization_and_destruction_01 = 0x11CD40; // type:func\n_GLOBAL_$I$g_splotheapPair = 0x11CD78; // type:func\n_GLOBAL_$D$g_splotheapPair = 0x11CDA0; // type:func\nCSplotheap__Startup = 0x11CDC8; // type:func\nCSplotheap__Shutdown = 0x11CE88; // type:func\nCSplotheap__PvAllocUnsafe = 0x11CE90; // type:func\nCSplotheap__PvAllocClear = 0x11CF08; // type:func\nCSplotheap__PsplotLookup = 0x11CF60; // type:func\nCSplotheap__UpdateRecyclable = 0x11CF78; // type:func\nCSplotheap__UnmarkAll = 0x11CF88; // type:func\nCSplotheap__FreeGarbage = 0x11CFC0; // type:func\nPvFromPsplot = 0x11D088; // type:func\nPsplotFromPv = 0x11D090; // type:func\nFIsPvGarbage = 0x11D098; // type:func\nMarkPvAlive = 0x11D0C8; // type:func\nPvectorNew = 0x11D0F8; // type:func\nIncrefVector = 0x11D190; // type:func\nDecrefVector = 0x11D1C0; // type:func\nPmatrixNew = 0x11D230; // type:func\nIncrefMatrix = 0x11D2C8; // type:func\nDecrefMatrix = 0x11D2F8; // type:func\nDeleteMatrix = 0x11D360; // type:func\nPclqNew = 0x11D390; // type:func\nIncrefClq = 0x11D428; // type:func\nDecrefClq = 0x11D458; // type:func\nPlmNew = 0x11D4C8; // type:func\nIncrefLm = 0x11D560; // type:func\nDecrefLm = 0x11D590; // type:func\nPsmpNew = 0x11D600; // type:func\nIncrefSmp = 0x11D698; // type:func\nDecrefSmp = 0x11D6D8; // type:func\nStartupSpliceStructuredTypeFactories = 0x11D750; // type:func\nShutdownSpliceStructuredTypeFactories = 0x11D888; // type:func\nsnd_StartSoundSystem = 0x11D890; // type:func\nsnd_FlushSoundCommands = 0x11DB20; // type:func\nsnd_StopSoundSystem = 0x11DD68; // type:func\nsnd_GotReturns = 0x11DDB0; // type:func\nsnd_PrepareReturnBuffer = 0x11DE20; // type:func\nsnd_BankLoadByLoc = 0x11DE50; // type:func\nsnd_BankLoadByLoc_CB = 0x11DFD8; // type:func\nsnd_ResolveBankXREFS = 0x11E168; // type:func\nsnd_UnloadBank = 0x11E1A0; // type:func\nsnd_SetMasterVolume = 0x11E1D8; // type:func\nsnd_GetMasterVolume = 0x11E218; // type:func\nsnd_SetMixerMode = 0x11E258; // type:func\nsnd_SetGroupVoiceRange = 0x11E298; // type:func\nsnd_PlaySoundVolPanPMPB = 0x11E2D8; // type:func\nsnd_StopSound = 0x11E328; // type:func\nsnd_PauseSound = 0x11E360; // type:func\nsnd_ContinueSound = 0x11E398; // type:func\nsnd_PauseAllSoundsInGroup = 0x11E3D8; // type:func\nsnd_ContinueAllSoundsInGroup = 0x11E410; // type:func\nsnd_SoundIsStillPlaying = 0x11E448; // type:func\nsnd_SoundIsStillPlaying_CB = 0x11E478; // type:func\nsnd_IsSoundALooper = 0x11E4B0; // type:func\nsnd_SetSoundVolPan = 0x11E4F0; // type:func\nsnd_GetSoundOriginalPitch = 0x11E530; // type:func\nsnd_SetSoundPitch = 0x11E570; // type:func\nsnd_AutoVol = 0x11E5C8; // type:func\nsnd_SetMIDIRegister = 0x11E620; // type:func\nsnd_SetGlobalExcite = 0x11E670; // type:func\nsnd_SendIOPCommandAndWait = 0x11E6B8; // type:func\nsnd_SendIOPCommandNoWait = 0x11E8C8; // type:func\nsnd_PostMessage = 0x11EBA8; // type:func\nsnd_SendCurrentBatch = 0x11EBF0; // type:func\nsnd_InitVAGStreamingEx = 0x11ED40; // type:func\nsnd_StopAllStreams = 0x11EE10; // type:func\nsnd_PlayVAGStreamByLoc = 0x11EE48; // type:func\nsnd_ContinueVAGStream = 0x11EEB8; // type:func\nsnd_IsVAGStreamBuffered_CB = 0x11EEF0; // type:func\nsnd_StreamSafeCheckCDIdle = 0x11EF28; // type:func\nsnd_StreamSafeCdRead = 0x11EF58; // type:func\nsnd_StreamSafeCdSync = 0x11F030; // type:func\nsnd_StreamSafeCdBreak = 0x11F100; // type:func\nsnd_StreamSafeCdGetError = 0x11F158; // type:func\nsnd_SetReverbType = 0x11F198; // type:func\nsnd_SetReverbDepth = 0x11F1D8; // type:func\nsnd_PreAllocReverbWorkArea = 0x11F218; // type:func\nsnd_InitMovieSound = 0x11F2A8; // type:func\nsnd_ResetMovieSound = 0x11F2E8; // type:func\nsnd_CloseMovieSound = 0x11F320; // type:func\nsnd_StartMovieSound = 0x11F350; // type:func\nsnd_GetTransStatus = 0x11F388; // type:func\nsnd_GetDopplerPitchMod = 0x11F3C0; // type:func\nStartupBrx = 0x11F3E8; // type:func\nPchzFromWid = 0x11F410; // type:func\nPchzFriendlyFromWid = 0x11F460; // type:func\nPchzFriendlyFromCid = 0x11F498; // type:func\nPchzFromOid = 0x11F4D8; // type:func\nOidFromPchz = 0x11F528; // type:func\nPloNew = 0x11F5C8; // type:func\nLoadOptionFromBrx = 0x11F708; // type:func\nLoadOptionsFromBrx = 0x11FDF0; // type:func\nIploFromStockOid = 0x11FE68; // type:func\nLoadSwObjectsFromBrx = 0x11FE80; // type:func\nSetLoDefaults = 0x11FFA8; // type:func\nFindKey = 0x1200B0; // type:func\nEvaluateAcp = 0x120180; // type:func\nGetAcpTimes = 0x120188; // type:func\nEvaluateAcr = 0x1201A0; // type:func\nEvaluateAcrEul = 0x1201A8; // type:func\nGetAcrTimes = 0x1201B0; // type:func\nEvaluateAcs = 0x1201C8; // type:func\nGetAcsTimes = 0x1201D0; // type:func\nEvaluateAcg = 0x1201E8; // type:func\nGetAcgTimes = 0x1201F0; // type:func\nLoadAcgbFromBrx = 0x120208; // type:func\nEvaluateAcgb = 0x120340; // type:func\nGetAcgbTimes = 0x120408; // type:func\nLoadAcgbwFromBrx = 0x1204A0; // type:func\nEvaluateAcgbw = 0x1205F8; // type:func\nGetAcgbwTimes = 0x1206D0; // type:func\nEvaluateAcgl = 0x120768; // type:func\nLoadAcglFromBrx = 0x120860; // type:func\nGetAcglTimes = 0x120948; // type:func\nEvaluateApacg = 0x1209E0; // type:func\nLoadApacgFromBrx = 0x120AC8; // type:func\nGetApacgTimes = 0x120BA8; // type:func\nEvaluateAkvb = 0x120D70; // type:func\nLoadAkvbFromBrx = 0x120E10; // type:func\nGetAkvbTimes = 0x120F40; // type:func\nEvaluateAcpc = 0x120FD0; // type:func\nLoadAcpcFromBrx = 0x121048; // type:func\nGetAcpcTimes = 0x121188; // type:func\nEvaluateAcpb = 0x1211B0; // type:func\nLoadAcpbFromBrx = 0x121220; // type:func\nGetAcpbTimes = 0x1212C0; // type:func\nEvaluateAcrc = 0x1212F8; // type:func\nEvaluateAcrcEul = 0x1213B0; // type:func\nLoadAcrcFromBrx = 0x1213E8; // type:func\nGetAcrcTimes = 0x121550; // type:func\nEvaluateAcrb = 0x121578; // type:func\nEvaluateAcrbEul = 0x121630; // type:func\nLoadAcrbFromBrx = 0x121658; // type:func\nGetAcrbTimes = 0x121750; // type:func\nEvaluateAcsc = 0x121788; // type:func\nLoadAcscFromBrx = 0x121808; // type:func\nGetAcscTimes = 0x121838; // type:func\nEvaluateAcsb = 0x121860; // type:func\nLoadAcsbFromBrx = 0x1218E0; // type:func\nGetAcsbTimes = 0x121910; // type:func\nEvaluateAcpbl = 0x121948; // type:func\nEvaluateAcrbl = 0x121BE0; // type:func\nEvaluateAcgblt = 0x121FC8; // type:func\nEvaluateAcgblp = 0x122288; // type:func\nPacpNew = 0x1224E8; // type:func\nPacrNew = 0x1225A0; // type:func\nPacsNew = 0x122658; // type:func\nPacgNew = 0x1226D8; // type:func\nPactNew = 0x1227C8; // type:func\nPactNewClone = 0x122828; // type:func\nCloneAct = 0x122888; // type:func\nInitAct = 0x1228F8; // type:func\nRetractAct = 0x122918; // type:func\nGetActPositionGoal = 0x122AA8; // type:func\nGetActRotationGoal = 0x122AF8; // type:func\nGetActTwistGoal = 0x122B58; // type:func\nGetActScale = 0x122B70; // type:func\nGGetActPoseGoal = 0x122B98; // type:func\nCalculateActDefaultAck = 0x122BB0; // type:func\nSnapAct = 0x122C38; // type:func\nCalculateAloPositionSpring = 0x122D50; // type:func\nProjectActPosition = 0x122EB0; // type:func\nCalculateAloRotationSpring = 0x123258; // type:func\nProjectActRotation = 0x123400; // type:func\nProjectActPose = 0x123B20; // type:func\nPredictAloPosition = 0x123BF0; // type:func\nPredictAloRotation = 0x123C70; // type:func\nAdaptAct = 0x123D80; // type:func\nInitActval = 0x123DB0; // type:func\nGetActvalPositionGoal = 0x123E60; // type:func\nGetActvalRotationGoal = 0x123EA0; // type:func\nGetActvalTwistGoal = 0x123EF0; // type:func\nGetActvalScale = 0x123F08; // type:func\nGGetActvalPoseGoal = 0x123F28; // type:func\nInitActref = 0x123F40; // type:func\nGetActrefPositionGoal = 0x123FD8; // type:func\nGetActrefRotationGoal = 0x124020; // type:func\nGetActrefTwistGoal = 0x124078; // type:func\nGetActrefScale = 0x124098; // type:func\nGGetActrefPoseGoal = 0x1240B8; // type:func\nInitActadj = 0x1240D0; // type:func\nGetActadjPositionGoal = 0x124140; // type:func\nGetActadjRotationGoal = 0x1241F8; // type:func\nGetActadjTwistGoal = 0x124318; // type:func\nGetActadjScale = 0x124388; // type:func\nGGetActadjPoseGoal = 0x124390; // type:func\nInitActbank = 0x1243A0; // type:func\nGetActbankRotationGoal = 0x1243E8; // type:func\nRetractActseg = 0x124538; // type:func\nCloneActseg = 0x1245A8; // type:func\nGetActsegPositionGoal = 0x124608; // type:func\nGetActsegRotationGoal = 0x124758; // type:func\nGetActsegTwistGoal = 0x1248B0; // type:func\nGetActsegScale = 0x124930; // type:func\nGGetActsegPoseGoal = 0x1249A8; // type:func\nBreakAlbrk = 0x124A10; // type:func\nSetAlbrkAlarm = 0x124A50; // type:func\nInitAlarm = 0x124A58; // type:func\nPostAlarmLoad = 0x124AA8; // type:func\nCloneAlarm = 0x124BD8; // type:func\nUpdateAlarm = 0x124C18; // type:func\nGetAlarmParams = 0x124CD0; // type:func\nPostAlarmLoadCallbackHookup = 0x124D38; // type:func\nSetAlarmAlarms = 0x124F68; // type:func\nTriggerAlarm = 0x125220; // type:func\nDisableAlarmAlbrk = 0x125290; // type:func\nEnableAlarmSensors = 0x1252A0; // type:func\nDisableAlarmSensors = 0x125328; // type:func\nNotifyAlarmSensorsOnTrigger = 0x125398; // type:func\nAddAlarmAlbrk = 0x125408; // type:func\nAddAlarmSensor = 0x125430; // type:func\nAddAlarmStepguard = 0x125458; // type:func\nSetAlarmRsmg = 0x125480; // type:func\nFGetAlarmSensorList = 0x1254C0; // type:func\nFIsZeroV = 0x125550; // type:func\nFIsZeroW = 0x125590; // type:func\nFIsZeroDv = 0x1255D8; // type:func\nFIsZeroDw = 0x125618; // type:func\nInitAlo = 0x125660; // type:func\nAddAloHierarchy = 0x125808; // type:func\nOnAloAdd = 0x1258B0; // type:func\nRemoveAloHierarchy = 0x125B48; // type:func\nOnAloRemove = 0x125BF0; // type:func\nUpdateAloOrig = 0x125D98; // type:func\nSetAloParent = 0x125E08; // type:func\nApplyAloProxy = 0x126100; // type:func\nBindAlo = 0x126260; // type:func\nPostAloLoad = 0x1262E0; // type:func\nPostAloLoadCallback = 0x1265D0; // type:func\nSnipAloObjects = 0x126720; // type:func\nUpdateAloHierarchy = 0x126840; // type:func\nUpdateAlo = 0x126928; // type:func\nInvalidateAloLighting = 0x126A50; // type:func\nUpdateAloXfWorld = 0x126A90; // type:func\nUpdateAloXfWorldHierarchy = 0x126AC0; // type:func\nPresetAloAccel = 0x126E48; // type:func\nProjectAloTransform = 0x126E50; // type:func\nPredictAloTransform = 0x1271A0; // type:func\nPredictAloTransformAdjust = 0x127410; // type:func\nToggleShowPhys = 0x1275B0; // type:func\nDupAloRo = 0x1275F0; // type:func\nRenderFastShadow = 0x127678; // type:func\nRenderAloAll = 0x127740; // type:func\nRenderAloSelf = 0x127CF0; // type:func\nRenderAloGlobset = 0x127FC8; // type:func\nRenderAloLine = 0x1286A0; // type:func\nSetAloOverrideCel = 0x128840; // type:func\nUpdateAloThrob = 0x1288D8; // type:func\nSetAloBlotContext = 0x128A00; // type:func\nEnsureAloFader = 0x128AA8; // type:func\nFadeAloIn = 0x128B18; // type:func\nFadeAloOut = 0x128BD0; // type:func\nAdjustAloRtckMat = 0x128C60; // type:func\nCloneAloHierarchy = 0x128E20; // type:func\nCloneAlo = 0x128F10; // type:func\nHandleAloMessage = 0x1292C8; // type:func\nTranslateAloToPos = 0x129348; // type:func\nRotateAloToMat = 0x1293D8; // type:func\nSetAloVelocityVec = 0x129458; // type:func\nSetAloVelocityXYZ = 0x1294D0; // type:func\nSetAloAngularVelocityVec = 0x129508; // type:func\nSetAloAngularVelocityXYZ = 0x129580; // type:func\nSetAloVelocityLocal = 0x1295B8; // type:func\nGetAloVelocityLocal = 0x129608; // type:func\nMatchAloOtherObject = 0x129650; // type:func\nCalculateAloMovement = 0x129858; // type:func\nCalculateAloTransform = 0x129AE8; // type:func\nCalculateAloTransformAdjust = 0x129E18; // type:func\nConvertAloPos = 0x129FD8; // type:func\nConvertAloVec = 0x12A080; // type:func\nConvertAloMat = 0x12A110; // type:func\nFDrivenAlo = 0x12A1F8; // type:func\nRetractAloDrive = 0x12A240; // type:func\nConvertAloMovement = 0x12A2F8; // type:func\nCalculateAloDrive = 0x12A5B8; // type:func\nFGetAloChildrenList = 0x12A920; // type:func\nPactsegNewAlo = 0x12A9E0; // type:func\nLoadAloFromBrx = 0x12AA10; // type:func\nLoadAloAloxFromBrx = 0x12ACE8; // type:func\nBindAloAlox = 0x12AF60; // type:func\nAdjustAloRotation = 0x12B220; // type:func\nUnadjustAloRotation = 0x12B368; // type:func\nSetAloInitialVelocity = 0x12B458; // type:func\nSetAloInitialAngularVelocity = 0x12B480; // type:func\nPasegdEnsureAlo = 0x12B4A8; // type:func\nSetAloFastShadowRadius = 0x12B518; // type:func\nGetAloFastShadowRadius = 0x12B520; // type:func\nSetAloFastShadowDepth = 0x12B530; // type:func\nGetAloFastShadowDepth = 0x12B538; // type:func\nPshadowAloEnsure = 0x12B548; // type:func\nSetAloCastShadow = 0x12B5B8; // type:func\nSetAloShadowShader = 0x12B630; // type:func\nSetAloShadowNearRadius = 0x12B670; // type:func\nSetAloShadowFarRadius = 0x12B6B0; // type:func\nSetAloShadowNearCast = 0x12B6F0; // type:func\nSetAloShadowFarCast = 0x12B730; // type:func\nSetAloShadowConeAngle = 0x12B770; // type:func\nSetAloShadowFrustrumUp = 0x12B7B0; // type:func\nSetAloDynamicShadowObject = 0x12B7F0; // type:func\nPshadowInferAlo = 0x12B820; // type:func\nGetAloCastShadow = 0x12B868; // type:func\nGetAloShadowShader = 0x12B878; // type:func\nGetAloShadowNearRadius = 0x12B8A8; // type:func\nGetAloShadowFarRadius = 0x12B8E0; // type:func\nGetAloShadowNearCast = 0x12B918; // type:func\nGetAloShadowFarCast = 0x12B950; // type:func\nGetAloShadowConeAngle = 0x12B988; // type:func\nGetAloShadowFrustrumUp = 0x12B9F0; // type:func\nGetAloEuler = 0x12BA28; // type:func\nSetAloEuler = 0x12BAB0; // type:func\nEnsureAloActRestore = 0x12BB50; // type:func\nEnsureAloActla = 0x12BBB0; // type:func\nRecacheAloActList = 0x12BC10; // type:func\nInsertAloAct = 0x12BE90; // type:func\nResortAloActList = 0x12BF10; // type:func\nPasegaFindAlo = 0x12C068; // type:func\nPsmaFindAlo = 0x12C100; // type:func\nPasegaFindAloNearest = 0x12C198; // type:func\nCreateAloActadj = 0x12C1F0; // type:func\nFIsAloStatic = 0x12C270; // type:func\nResolveAlo = 0x12C310; // type:func\nSetAloPositionSpring = 0x12C328; // type:func\nSetAloPositionSpringDetail = 0x12C3C0; // type:func\nSetAloPositionDamping = 0x12C420; // type:func\nSetAloPositionDampingDetail = 0x12C4B8; // type:func\nSetAloRotationSpring = 0x12C518; // type:func\nSetAloRotationSpringDetail = 0x12C5B0; // type:func\nSetAloRotationDamping = 0x12C610; // type:func\nSetAloRotationDampingDetail = 0x12C6A8; // type:func\nSetAloPositionSmooth = 0x12C708; // type:func\nSetAloPositionSmoothMaxAccel = 0x12C760; // type:func\nSetAloPositionSmoothDetail = 0x12C7C8; // type:func\nSetAloRotationSmooth = 0x12C840; // type:func\nSetAloRotationSmoothMaxAccel = 0x12C898; // type:func\nSetAloRotationSmoothDetail = 0x12C900; // type:func\nSetAloDefaultAckPos = 0x12C978; // type:func\nSetAloDefaultAckRot = 0x12C980; // type:func\nSetAloRestorePosition = 0x12C988; // type:func\nSetAloNoFreeze = 0x12C9B8; // type:func\nSetAloRestorePositionAck = 0x12C9E8; // type:func\nSetAloRestoreRotation = 0x12CA38; // type:func\nSetAloRestoreRotationAck = 0x12CA68; // type:func\nSetAloLookAt = 0x12CAB8; // type:func\nSetAloLookAtIgnore = 0x12CB18; // type:func\nGetAloLookAtIgnore = 0x12CB58; // type:func\nSetAloLookAtPanFunction = 0x12CB70; // type:func\nGetAloLookAtPanFunction = 0x12CBB8; // type:func\nSetAloLookAtPanLimits = 0x12CBD8; // type:func\nGetAloLookAtPanLimits = 0x12CC28; // type:func\nSetAloLookAtTiltFunction = 0x12CC50; // type:func\nGetAloLookAtTiltFunction = 0x12CC98; // type:func\nSetAloLookAtTiltLimits = 0x12CCB8; // type:func\nGetAloLookAtTiltLimits = 0x12CD08; // type:func\nSetAloLookAtEnabledPriority = 0x12CD30; // type:func\nGetAloLookAtEnabledPriority = 0x12CD70; // type:func\nSetAloLookAtDisabledPriority = 0x12CD88; // type:func\nGetAloLookAtDisabledPriority = 0x12CDC8; // type:func\nSetAloRotationMatchesVelocity = 0x12CDE0; // type:func\nPtargetEnsureAlo = 0x12CE88; // type:func\nSetAloTargetAttacks = 0x12CEF0; // type:func\nSetAloTargetRadius = 0x12CF30; // type:func\nSetAloTargetHitTest = 0x12CF60; // type:func\nSetAloScrollingMasterSpeeds = 0x12CF90; // type:func\nSetAloEyesClosed = 0x12D038; // type:func\nEnsureAloSfx = 0x12D108; // type:func\nSetAloSfxid = 0x12D138; // type:func\nSetAloSfxidSpl = 0x12D178; // type:func\nGetAloSfxid = 0x12D210; // type:func\nSetAloSStart = 0x12D228; // type:func\nGetAloSStart = 0x12D268; // type:func\nSetAloSFull = 0x12D288; // type:func\nSetAloSndRepeat = 0x12D2C8; // type:func\nGetAloSFull = 0x12D318; // type:func\nSetAloUVolume = 0x12D338; // type:func\nSetAloUDoppler = 0x12D378; // type:func\nGetAloUDoppler = 0x12D3B8; // type:func\nSetAloUVolumeSpl = 0x12D3D0; // type:func\nGetAloUVolume = 0x12D408; // type:func\nSetAloUPitch = 0x12D428; // type:func\nSetAloUPitchSpl = 0x12D468; // type:func\nGetAloUPitch = 0x12D4A0; // type:func\nGetAloSndRepeat = 0x12D4B8; // type:func\nStartAloSound = 0x12D4F0; // type:func\nStopAloSound = 0x12D5E0; // type:func\nEnsureAloThrob = 0x12D618; // type:func\nSetAloThrobKind = 0x12D690; // type:func\nGetAloThrobKind = 0x12D710; // type:func\nSetAloThrobInColor = 0x12D728; // type:func\nGetAloThrobInColor = 0x12D780; // type:func\nSetAloThrobOutColor = 0x12D7A0; // type:func\nGetAloThrobOutColor = 0x12D7F8; // type:func\nSetAloThrobDtInOut = 0x12D818; // type:func\nGetAloThrobDtInOut = 0x12D868; // type:func\nSetAloInteractCane = 0x12D880; // type:func\nGetAloInteractCane = 0x12D890; // type:func\nSetAloInteractCaneSweep = 0x12D8A0; // type:func\nGetAloInteractCaneSweep = 0x12D8A8; // type:func\nSetAloInteractCaneRush = 0x12D8B8; // type:func\nGetAloInteractCaneRush = 0x12D8C0; // type:func\nSetAloInteractCaneSmash = 0x12D8D0; // type:func\nGetAloInteractCaneSmash = 0x12D8D8; // type:func\nSetAloInteractBomb = 0x12D8E8; // type:func\nGetAloInteractBomb = 0x12D8F0; // type:func\nSetAloInteractShock = 0x12D900; // type:func\nGetAloInteractShock = 0x12D908; // type:func\nFAbsorbAloWkr = 0x12D918; // type:func\nSetAloPoseCombo = 0x12D928; // type:func\nSetAloForceCameraFade = 0x12DA60; // type:func\nSetAloRealClock = 0x12DB20; // type:func\nGetAloParams = 0x12DBB0; // type:func\nOnAloThrobParamsChanged = 0x12DC58; // type:func\nInitAseg = 0x12DCB8; // type:func\nLoadAsegFromBrx = 0x12DD20; // type:func\nLoadAsegEventsFromBrx = 0x12E140; // type:func\nCloneAseg = 0x12E790; // type:func\nPostAsegLoad = 0x12E7B8; // type:func\nPostAsegLoadCallback = 0x12E870; // type:func\nApplyAsegOvr = 0x12E8E0; // type:func\nApplyAseg = 0x12EED8; // type:func\nPasegaApplyAseg = 0x12EF08; // type:func\nPasegaFindAseg = 0x12EF40; // type:func\nEnsureAseg = 0x12EF78; // type:func\nPasegaEnsureAseg = 0x12F048; // type:func\nApplyAsegCur = 0x12F070; // type:func\nFWipingAseg = 0x12F110; // type:func\nFindAsegClosestPoint = 0x12F150; // type:func\nPeaFindAsegLabel = 0x12F360; // type:func\nTFindAsegLabel = 0x12F438; // type:func\nPchnFindAseg = 0x12F468; // type:func\nPredictAsegEffect = 0x12F500; // type:func\nGetAsegWaypoints = 0x12F920; // type:func\nStripAsegChn = 0x12FA30; // type:func\nStripAsegAlo = 0x12FB28; // type:func\nLoadAsegblFromBrx = 0x12FB80; // type:func\nPostAsegblLoad = 0x12FB88; // type:func\nCloneAsegbl = 0x12FB90; // type:func\nRenderAsegPath = 0x12FBA0; // type:func\nPasegaNew = 0x12FD98; // type:func\nSetAsegaHandsOff = 0x12FDF8; // type:func\nUpdateAsegaIeaCur = 0x12FE68; // type:func\nPactsegFindAsega = 0x12FF30; // type:func\nHandleAsegaEvent = 0x12FFA0; // type:func\nHandleAsegaEventsFF = 0x1310B0; // type:func\nHandleAsegaEvents = 0x1311A8; // type:func\nRemoveAsega = 0x1312F8; // type:func\nRetractAsega = 0x131358; // type:func\nUFromEaErrorFunc = 0x131568; // type:func\nFWrapAsegaTime = 0x1315E0; // type:func\nUpdateAsega = 0x1317E8; // type:func\nSeekAsega = 0x131CF8; // type:func\nSnapAsega = 0x131E20; // type:func\nAdaptAsega = 0x131E80; // type:func\nFindChnClosestPointLocal = 0x131EC8; // type:func\nSetAsegaSpeed = 0x132368; // type:func\nSetAsegaMasterSpeed = 0x132388; // type:func\nSetAsegaPriority = 0x1323D8; // type:func\nSendAsegaMessage = 0x132438; // type:func\nSubscribeAsegaStruct = 0x1324B8; // type:func\nSubscribeAsegaObject = 0x1324F0; // type:func\nInitBarrier = 0x132528; // type:func\nCloneBarrier = 0x132580; // type:func\nPostBarrierLoad = 0x1325D0; // type:func\nUpdateBarrier = 0x1326E0; // type:func\nFIgnoreBarrierIntersection = 0x1327C0; // type:func\nNotifyBarrierImpact = 0x1328C0; // type:func\nAddBarrierObject = 0x1329E8; // type:func\nAddBarrierClass = 0x132A08; // type:func\nCBinaryAsyncStream__CBinaryAsyncStream = 0x132A28; // type:func\nCBinaryAsyncStream__~CBinaryAsyncStream = 0x132A68; // type:func\nCBinaryAsyncStream__FOpenFile = 0x132AB8; // type:func\nCBinaryAsyncStream__FOpenSector = 0x132AF0; // type:func\nCBinaryAsyncStream__Close = 0x132B58; // type:func\nCBinaryAsyncStream__StartSpooling = 0x132BC0; // type:func\nCBinaryAsyncStream__FSpooling = 0x132C78; // type:func\nCBinaryAsyncStream__FSpoolingComplete = 0x132C88; // type:func\nCBinaryAsyncStream__FinishSpooling = 0x132D68; // type:func\nCBinaryAsyncStream__Spool = 0x132DF8; // type:func\nCBinaryAsyncStream__Skip = 0x132E80; // type:func\nFIsBasicDerivedFrom = 0x132E90; // type:func\nEnsureBasicSidebag = 0x132EB8; // type:func\nGetBasicCid = 0x132F10; // type:func\nEvaluateBezierWeightedFloat = 0x132F20; // type:func\nEvaluateBezierFloat = 0x1331A8; // type:func\nEvaluateBezierPos = 0x1332F8; // type:func\nEvaluateBezierMat = 0x133500; // type:func\nTesselateBezier = 0x133938; // type:func\nSBezierPosLength = 0x133A20; // type:func\nLimitBezierMulti = 0x133A68; // type:func\nInitBei = 0x133D68; // type:func\nGEvaluateBei = 0x133E20; // type:func\nInitBinoc = 0x133F10; // type:func\nResetBinoc = 0x133F60; // type:func\nPostBinocLoad = 0x133FC0; // type:func\nDrawBinocCompass = 0x1345A0; // type:func\nDrawBinocZoom = 0x134EB0; // type:func\nDrawBinocReticle = 0x135400; // type:func\nDrawBinocOutline = 0x136A98; // type:func\nDrawBinocScan = 0x137AB8; // type:func\nDrawBinocFilter = 0x137FD0; // type:func\nSetBinocBlots = 0x1385F0; // type:func\nSetBinocBinocs = 0x1387E0; // type:func\nNCmpSlo = 0x138840; // type:func\nUpdateFilterRose = 0x1388B8; // type:func\nGetSoSphere = 0x138DF0; // type:func\nGetAloSphere = 0x138E08; // type:func\nChpFillAlo = 0x138E18; // type:func\nChpFillSo = 0x138E48; // type:func\nSetBinocBfk = 0x138ED0; // type:func\nUpdateBinocActiveFilter = 0x138FD8; // type:func\nUpdateBinocActive = 0x1391C8; // type:func\nOnBinocActive = 0x1393E0; // type:func\nOnBinocReset = 0x139500; // type:func\nSetBinocAchzDraw = 0x139560; // type:func\nFDoneBinocAchz = 0x1396D0; // type:func\nSetBinocLookat = 0x139750; // type:func\nSetBinocZoom = 0x139758; // type:func\nDtAppearBinoc = 0x1397A0; // type:func\nDtDisappearBinoc = 0x139800; // type:func\nDrawBinoc = 0x139860; // type:func\nGetBinocReticleFocus = 0x13A128; // type:func\nOnBinocPush = 0x13A158; // type:func\nOnBinocPop = 0x13A248; // type:func\n__static_initialization_and_destruction_02 = 0x13A298; // type:func\nCTextBox__SetPos = 0x13A418; // type:func\nCTextBox__SetSize = 0x13A428; // type:func\nCTextBox__SetTextColor = 0x13A438; // type:func\nCTextBox__SetHorizontalJust = 0x13A450; // type:func\nCTextBox__SetVerticalJust = 0x13A458; // type:func\n_GLOBAL_$I$InitBei__FP3BEIP3CLQffi = 0x13A460; // type:func\nCBinaryInputStream__CBinaryInputStream = 0x13A488; // type:func\nCBinaryInputStream__~CBinaryInputStream = 0x13A4D8; // type:func\nCBinaryInputStream__FOpenSector = 0x13A528; // type:func\nCBinaryInputStream__OpenMemory = 0x13A5B0; // type:func\nCBinaryInputStream__FOpenFile = 0x13A5C8; // type:func\nCBinaryInputStream__Close = 0x13A600; // type:func\nCBinaryInputStream__DecrementCdReadLimit = 0x13A6C0; // type:func\nCBinaryInputStream__PumpCd = 0x13A6D0; // type:func\nCBinaryInputStream__PumpHost = 0x13AA58; // type:func\nCBinaryInputStream__Pump = 0x13AAC0; // type:func\nCBinaryInputStream__Decompress = 0x13AB58; // type:func\nCBinaryInputStream__Read = 0x13AD28; // type:func\nCBinaryInputStream__Align = 0x13AE58; // type:func\nCBinaryInputStream__U8Read = 0x13AE88; // type:func\nCBinaryInputStream__U16Read = 0x13AEE0; // type:func\nCBinaryInputStream__U32Read = 0x13AF48; // type:func\nCBinaryInputStream__S8Read = 0x13AFD0; // type:func\nCBinaryInputStream__S16Read = 0x13B028; // type:func\nCBinaryInputStream__S32Read = 0x13B098; // type:func\nCBinaryInputStream__F32Read = 0x13B120; // type:func\nCBinaryInputStream__ReadVector = 0x13B1A0; // type:func\nCBinaryInputStream__ReadVector4 = 0x13B1C8; // type:func\nCBinaryInputStream__ReadMatrix = 0x13B1F0; // type:func\nCBinaryInputStream__ReadMatrix4 = 0x13B258; // type:func\nCBinaryInputStream__ReadGeom = 0x13B310; // type:func\nCBinaryInputStream__ReadBspc = 0x13B648; // type:func\nCBinaryInputStream__ReadVbsp = 0x13B788; // type:func\nCBinaryInputStream__ReadStringSw = 0x13B8D0; // type:func\nUpdateSwPox = 0x13B968; // type:func\nPoxAddSw = 0x13BB38; // type:func\nPoxRemoveSw = 0x13BB90; // type:func\nPoxFromSoSo = 0x13BBC8; // type:func\nPxpFirstFromSoSo = 0x13BC00; // type:func\nAddSwAaobrObject = 0x13BC38; // type:func\nRemoveSwAaobrObject = 0x13BCB8; // type:func\nInvalidateSwAaox = 0x13BDE0; // type:func\nUpdateSwAaox = 0x13BDE8; // type:func\nInvalidateSwXpForObject = 0x13C020; // type:func\nRecalcSwXpAll = 0x13C040; // type:func\nRecalcSwOxfFilterForObject = 0x13C390; // type:func\nVerifyAeaEquivalence = 0x13C470; // type:func\nEnsureAsegBlendDynamic = 0x13C4B8; // type:func\nFillBlAmrsg = 0x13CB08; // type:func\nCalculateBlendAmrsg = 0x13CC50; // type:func\nImrsgLookUp = 0x13CE88; // type:func\nReblendAsegbl = 0x13CF10; // type:func\nSetAsegblSlerp = 0x13D060; // type:func\nBuildBlipAqwGifs = 0x13D0A0; // type:func\nStartupBlips = 0x13D1A8; // type:func\nPblipNew = 0x13D1F0; // type:func\nRemoveBlip = 0x13D2D0; // type:func\nPblipgNew = 0x13D320; // type:func\nInitBlipg = 0x13D3B0; // type:func\nOnBlipgAdd = 0x13D448; // type:func\nOnBlipgRemove = 0x13D4A8; // type:func\nSetBlipgShader = 0x13D598; // type:func\nPropagateBlipgShader = 0x13D630; // type:func\nSetBlipgEmitb = 0x13D760; // type:func\nUpdateBlipg = 0x13DA10; // type:func\nSubscribeBlipgObject = 0x13DA98; // type:func\nCblipeProjectBlipTransformAccel = 0x13DB30; // type:func\nProjectBlipgTransformAccel = 0x13DCB8; // type:func\nProjectBlipgTransform = 0x13E018; // type:func\nRenderBlipgSelf = 0x13E400; // type:func\nDrawBlipg = 0x13E490; // type:func\nPropagateBlipgShaders = 0x13ECC8; // type:func\nInitBomb = 0x13ED60; // type:func\nLoadBombFromBrx = 0x13EE50; // type:func\nCloneBomb = 0x13EE90; // type:func\nPostBombLoad = 0x13EEE8; // type:func\nHandleBombMessage = 0x13F018; // type:func\nUpdateBomb = 0x13F088; // type:func\nOnBombAdd = 0x13F228; // type:func\nGetBombParams = 0x13F268; // type:func\nDecideBombPrime = 0x13F2D0; // type:func\nFAbsorbBombWkr = 0x13F3E0; // type:func\nPrimeBomb = 0x13F450; // type:func\nApplyBombThrow = 0x13F468; // type:func\nDetonateBomb = 0x13F580; // type:func\nPsfxEnsureBomb = 0x13FF88; // type:func\nRenderAloAsBone = 0x13FFC8; // type:func\nRenderBoneSelf = 0x1401C0; // type:func\nRenderLboneSelf = 0x140220; // type:func\nCByteQueue__Init = 0x140280; // type:func\nCByteQueue__Reset = 0x1402B0; // type:func\nCByteQueue__CbFill = 0x1402D0; // type:func\nCByteQueue__CbDrain = 0x1403D8; // type:func\nCByteQueue__CbFill1 = 0x140500; // type:func\nCByteQueue__FreeDrain = 0x140558; // type:func\nCQueueInputMemory__CbRead = 0x140590; // type:func\nCQueueInputFile__CbRead = 0x140600; // type:func\nInitBrk = 0x140610; // type:func\nLoadBrkFromBrx = 0x1406A8; // type:func\nCloneBrk = 0x140730; // type:func\nPostBrkLoad = 0x140798; // type:func\nPostBrkLoadCallbackHookup = 0x1407E8; // type:func\nUpdateBrk = 0x1409C0; // type:func\nFAbsorbBrkWkr = 0x140A10; // type:func\nBreakBrk = 0x140BA0; // type:func\nSetBrkBroken = 0x1411C0; // type:func\nSetBrkExclude = 0x141218; // type:func\nSetBrkRemain = 0x141260; // type:func\nSetBrkFixed = 0x1412B0; // type:func\nSetBrkRemainFixed = 0x141300; // type:func\nSetBrkOnPlayer = 0x141350; // type:func\nGetBrkOnPlayer = 0x141390; // type:func\nSetBrkOnBomb = 0x1413A0; // type:func\nGetBrkOnBomb = 0x1413E0; // type:func\nAddBrkTouchObject = 0x1413F8; // type:func\nAddBrkTouchClass = 0x141430; // type:func\nPsfxEnsureBrk = 0x141468; // type:func\nFCheckBrkTouchObject = 0x1414A8; // type:func\nUpdateBrkp = 0x1415D0; // type:func\nHandleBrkpMessage = 0x141658; // type:func\nFIgnoreBrkpIntersection = 0x1416C8; // type:func\nSetBrkpBrkps = 0x141740; // type:func\nInitBreak = 0x141788; // type:func\nInitFragile = 0x1417C8; // type:func\nAdjustFragileNewXp = 0x141800; // type:func\nAdjustZapbreakNewXp = 0x141870; // type:func\nUpdateZapbreak = 0x141900; // type:func\nClsgClipEdgeToBsp = 0x141980; // type:func\nPruneBsp = 0x141DE8; // type:func\nPbspPointInBspQuick = 0x142018; // type:func\nCloneBspc = 0x142098; // type:func\nPostAshLoad = 0x142198; // type:func\nFFoundAshAseg = 0x142270; // type:func\nFAddAshAseg = 0x1422F0; // type:func\nFAddAshOid = 0x142310; // type:func\nInitBtn = 0x142330; // type:func\nLoadBtn = 0x142388; // type:func\nPostBtnLoad = 0x142498; // type:func\nRestoreBtnFromCheckpointCallback = 0x142568; // type:func\nSetBtnRsmg = 0x1425C8; // type:func\nSetBtnButtons = 0x142608; // type:func\nFAddRsmg = 0x1426B8; // type:func\nTriggerRsmg = 0x142768; // type:func\nRunBtnAsegs = 0x142860; // type:func\nTriggerBtn = 0x142A50; // type:func\nUntriggerBtn = 0x142B98; // type:func\nInitButton = 0x142C10; // type:func\nLoadButtonFromBrx = 0x142C50; // type:func\nInsertButtonPos = 0x142C90; // type:func\nInsertButtonMat = 0x142D38; // type:func\nPostButtonLoad = 0x142E00; // type:func\nCloneButton = 0x1432A0; // type:func\nSetButtonButtons = 0x1432E0; // type:func\nFCheckButtonObject = 0x143308; // type:func\nIposFindButtonClosest = 0x1434C0; // type:func\nImatFindButtonClosest = 0x143560; // type:func\nPresetButtonAccel = 0x143658; // type:func\nUpdateButtonInternalXps = 0x143748; // type:func\nUpdateButton = 0x1439C8; // type:func\nFAbsorbButtonWkr = 0x143D38; // type:func\nGetButtonParams = 0x143DC8; // type:func\nInitVolbtn = 0x143E30; // type:func\nLoadVolbtnFromBrx = 0x143EA0; // type:func\nPostVolbtnLoad = 0x143EF0; // type:func\nCloneVolbtn = 0x143FD8; // type:func\nSetVolbtnButtons = 0x144018; // type:func\nUpdateVolbtn = 0x144040; // type:func\nFGetVolbtnPushObjectsWithinList = 0x1443A8; // type:func\nAddBtnAseg = 0x144438; // type:func\nAddButtonAseg = 0x144460; // type:func\nAddVolbtnAseg = 0x144490; // type:func\nAddBtnOffAseg = 0x1444C0; // type:func\nAddButtonOffAseg = 0x1444E8; // type:func\nAddVolbtnOffAseg = 0x144518; // type:func\nAddButtonPushObject = 0x144548; // type:func\nAddButtonNoPushObject = 0x144568; // type:func\nAddButtonPushClass = 0x144588; // type:func\nAddButtonNoPushClass = 0x1445A8; // type:func\nAddVolbtnPushObject = 0x1445C8; // type:func\nSetButtonRsmg = 0x1445E8; // type:func\nSetVolbtnRsmg = 0x144610; // type:func\nStartupCatalog = 0x144638; // type:func\nCWalCatalog__Init = 0x144660; // type:func\nCWalCatalog__Reload = 0x1446A8; // type:func\nCWalCatalog__FFindFile = 0x144930; // type:func\nCWalCatalog__BuildFl = 0x144A68; // type:func\nCWalCatalog__FDefaultWorld = 0x144AA0; // type:func\nCWalCatalog__CGetWorlds = 0x144B18; // type:func\nCCatalog__Init = 0x144BF8; // type:func\nCCatalog__Reload = 0x144CE0; // type:func\nCCatalog__FFindFile = 0x144CE8; // type:func\nCCatalog__FDefaultWorld = 0x144EF8; // type:func\nCCatalog__CGetWorlds = 0x144F20; // type:func\n__static_initialization_and_destruction_03 = 0x145050; // type:func\nCFileLocation__Clear = 0x1450A0; // type:func\n_GLOBAL_$I$StartupCatalog__Fv = 0x1450C8; // type:func\nInitCan = 0x1450F0; // type:func\nPostCanLoad = 0x1451B0; // type:func\nFIgnoreCanIntersection = 0x145248; // type:func\nUpdateCan = 0x1452B0; // type:func\nGetCanParams = 0x1454C8; // type:func\nBreakCan = 0x145530; // type:func\nSetCanGoalState = 0x145578; // type:func\nTrackCan = 0x145630; // type:func\nFPrepareCanToFire = 0x145A08; // type:func\nFireCan = 0x145A60; // type:func\nPsoFireCanAtPos = 0x145D78; // type:func\nAddCanFireAccuracy = 0x145DE8; // type:func\nCpchzTokenizePath = 0x145E18; // type:func\nFValidCdMmode = 0x145FF8; // type:func\nSetCdMmode = 0x146060; // type:func\nStartupCd = 0x1460C0; // type:func\nUpdateCd = 0x1460E0; // type:func\nCdPath = 0x1460E8; // type:func\nReadCd = 0x1461D0; // type:func\nReadCdDirect = 0x146298; // type:func\nFCdCompleted = 0x146360; // type:func\nResetChkmgrCheckpoints = 0x146390; // type:func\nSaveChkmgrCheckpoint = 0x146420; // type:func\nReturnChkmgrToCheckpoint = 0x1464E0; // type:func\nRestoreChkmgrFromCheckpoint = 0x146560; // type:func\nIchkAllocChkmgr = 0x146610; // type:func\nFGetChkmgrIchk = 0x146620; // type:func\nSetChkmgrIchk = 0x146658; // type:func\nClearChkmgrIchk = 0x1466B8; // type:func\nLoadVolFromBrx = 0x146720; // type:func\nFCheckVolPoint = 0x1467A8; // type:func\nInitChkpnt = 0x1467F0; // type:func\nLoadChkpntFromBrx = 0x146850; // type:func\nBindChkpnt = 0x1469D0; // type:func\nPostChkpntLoad = 0x146AE8; // type:func\nCloneChkpnt = 0x146BA0; // type:func\nUpdateChkpnt = 0x146C78; // type:func\nTriggerChkpnt = 0x146E08; // type:func\nAddChkpntVol = 0x146F08; // type:func\nAddChkpntAseg = 0x146F28; // type:func\nSetChkpntWarp = 0x146F48; // type:func\nPsoHitTestLineObjects = 0x146F50; // type:func\nClsgClipEdgeToObject = 0x1470B8; // type:func\nClsgClipEdgeToObjectPruned = 0x147130; // type:func\nClsgClipCylinderToObject = 0x1471B0; // type:func\nClsgClipLineToSphere = 0x147250; // type:func\nClsgClipEdgeToSphere = 0x147410; // type:func\nClsgClipCylinderToSphere = 0x147638; // type:func\nClsgClipEdgeToCylinder = 0x147758; // type:func\nSgnCompareMaa = 0x147E80; // type:func\nClsgMergeAlsg = 0x147EE0; // type:func\nClsgClipCylinderToBsp = 0x148080; // type:func\nSetClockRate = 0x148418; // type:func\nMarkClockTick = 0x148468; // type:func\nMarkClockTickRealOnly = 0x1485A8; // type:func\nResetClock = 0x148640; // type:func\nSetClockEnabled = 0x148648; // type:func\nStartupClock = 0x148650; // type:func\nTickNow = 0x148688; // type:func\nStartupCm = 0x1486D0; // type:func\nCheckCmProgress = 0x1486D8; // type:func\nResetCmProgress = 0x148770; // type:func\nCalcCmAdjust = 0x148788; // type:func\nSpringCm = 0x1487C8; // type:func\nAdjustCmCpdefi = 0x148850; // type:func\nResetCmAdjust = 0x148A58; // type:func\nGetCmCpdefi = 0x148A98; // type:func\nBuildCmFgfn = 0x148B50; // type:func\nRecalcCmFrustrum = 0x148BF0; // type:func\nInitCm = 0x148CF0; // type:func\nSetSwCameraFov = 0x148E78; // type:func\nSetSwCameraNearClip = 0x148EA8; // type:func\nSetSwCameraFarClip = 0x148ED8; // type:func\nSetSwCameraNearFog = 0x148F08; // type:func\nSetSwCameraFarFog = 0x148F38; // type:func\nSetSwCameraUFogMax = 0x148F68; // type:func\nSetSwCameraRgbaFog = 0x148F98; // type:func\nSetSwCameraMrdRatio = 0x148FC8; // type:func\nSetCmPos = 0x148FF8; // type:func\nSetCmMat = 0x149020; // type:func\nSetCmFov = 0x149048; // type:func\nSetCmNearClip = 0x149070; // type:func\nSetCmFarClip = 0x149098; // type:func\nSetCmNearFog = 0x1490C0; // type:func\nSetCmFarFog = 0x1490E8; // type:func\nSetCmUFogMax = 0x149110; // type:func\nSetCmRgbaFog = 0x149138; // type:func\nSetCmMrdRatio = 0x149170; // type:func\nGetCmParams = 0x1491A0; // type:func\nResetCm = 0x1491D0; // type:func\nFFilterCamera = 0x149298; // type:func\nCpsoClipCmObjects = 0x1492D8; // type:func\nClearCmFadeObjects = 0x1493E0; // type:func\nAddCmFadeObject = 0x1493E8; // type:func\nRemoveCmFadeObject = 0x149410; // type:func\nUpdateCmFade = 0x1494A0; // type:func\nPxpMarkCmContacts = 0x149728; // type:func\nFDisplaceCmPos = 0x149730; // type:func\nUpdateCmLast = 0x149738; // type:func\nSetupCmRotateToCam = 0x1498E8; // type:func\nConvertCmScreenToWorld = 0x149A08; // type:func\nConvertCmWorldToScreen = 0x149AA0; // type:func\nUnlockCm = 0x149B58; // type:func\nSetupCm = 0x149B68; // type:func\nCombineEyeLookAtProj = 0x149BF0; // type:func\nBuildFrustrum = 0x149D08; // type:func\nUpdateCmMat4 = 0x149E80; // type:func\nDrawCm = 0x14A1C0; // type:func\nSetCmPosMat = 0x14A268; // type:func\nSetCmLookAt = 0x14A330; // type:func\nConvertWorldToCylindVelocity = 0x14A378; // type:func\nConvertCylindToWorldVelocity = 0x14A4A8; // type:func\nResetCmLookAtSmooth = 0x14A580; // type:func\nSetCmLookAtSmooth = 0x14A608; // type:func\nAdjustCmJoy = 0x14AE30; // type:func\nSetCmPolicy = 0x14AEE0; // type:func\nRevokeCmPolicy = 0x14B050; // type:func\nFInsideCmMrd = 0x14B210; // type:func\nDecomposeCylind = 0x14B2F0; // type:func\nDecomposeSphere = 0x14B3A8; // type:func\nSetCmCut = 0x14B4A8; // type:func\nAdaptCm = 0x14B4E8; // type:func\nSetCm = 0x14B5F8; // type:func\nSquishCmEye = 0x14B718; // type:func\nPushCmLookk = 0x14BA78; // type:func\nLookkPopCm = 0x14BAA0; // type:func\nLookkCurCm = 0x14BAC8; // type:func\nSetCmSniperFocus = 0x14BAF0; // type:func\nJoltCm = 0x14BB00; // type:func\n__static_initialization_and_destruction_04 = 0x14BB10; // type:func\n_GLOBAL_$I$StartupCm__Fv = 0x14BB38; // type:func\nInitCnvo = 0x14BB60; // type:func\nLoadCnvoFromBrx = 0x14BB98; // type:func\nPostCnvoLoad = 0x14BBF8; // type:func\nAdjustCnvoXpVelocity = 0x14BC38; // type:func\nGetCnvoParams = 0x14BCD0; // type:func\nSetCnvoBeltSpeed = 0x14BD38; // type:func\nMatchCnvoScrollerToBeltSpeed = 0x14BDA8; // type:func\nInitDprize = 0x14BE50; // type:func\nLoadDprizeFromBrx = 0x14BEE0; // type:func\nCloneDprize = 0x14BF50; // type:func\nPostDprizeLoad = 0x14BFB0; // type:func\nProjectDprizeTransform = 0x14C050; // type:func\nFFilterDprizeObjects = 0x14C8C8; // type:func\nCheckDprizeBounce = 0x14C978; // type:func\nCheckDprizeCollect = 0x14CD68; // type:func\nFAbsorbDprizeWkr = 0x14CE78; // type:func\nUpdateDprize = 0x14CEB0; // type:func\nRenderDprizeAll = 0x14D388; // type:func\nSetDprizeDprizes = 0x14D568; // type:func\nInitCoin = 0x14D948; // type:func\nUpdateCoin = 0x14D9E0; // type:func\nCreateSwCharm = 0x14DA50; // type:func\nAddLife = 0x14DB98; // type:func\nOnCoinSmack = 0x14DBC0; // type:func\nSetCoinDprizes = 0x14DCC0; // type:func\nInitCharm = 0x14DE70; // type:func\nSetCharmDprizes = 0x14DEE8; // type:func\nInitKey = 0x14DF78; // type:func\nSetKeyDprizes = 0x14E008; // type:func\nInitGold = 0x14E0E8; // type:func\nSetGoldDprizes = 0x14E178; // type:func\nSgnCompareSdprize = 0x14E350; // type:func\nCpdprizeFindSwDprizes = 0x14E378; // type:func\nCpdprizeAttractSwDprizes = 0x14E528; // type:func\nRemoveSwExtraneousCharms = 0x14E780; // type:func\nInitCplcy = 0x14E810; // type:func\nFActiveCplcy = 0x14E818; // type:func\nSetCpmanCpmt = 0x14E830; // type:func\nSetCpmanCpmtGlobal = 0x14E878; // type:func\nToggleCpmanOverride = 0x14E930; // type:func\nUpdateCpman = 0x14E960; // type:func\nPosCplookAnchor = 0x14EF58; // type:func\nPosCplookEye = 0x14F000; // type:func\nStartCplookSound = 0x14F0C0; // type:func\nPushCplookLookk = 0x14F1B8; // type:func\nLookkPopCplook = 0x14F1E0; // type:func\nLookkCurCplook = 0x14F208; // type:func\nInitCplook = 0x14F230; // type:func\nActivateCplook = 0x14F2A0; // type:func\nUpdateCplook = 0x14F340; // type:func\nDeactivateCplook = 0x150040; // type:func\nInitCpalign = 0x1501F0; // type:func\nActivateCpalign = 0x150240; // type:func\nUpdateCpalign = 0x150270; // type:func\nActivateCpaseg = 0x150410; // type:func\nDeactivateCpaseg = 0x150418; // type:func\nUpdateCpaseg = 0x150420; // type:func\nInitCredit = 0x150580; // type:func\nPostCreditLoad = 0x150600; // type:func\nSetCreditClock = 0x1506F0; // type:func\nUpdateCredit = 0x150768; // type:func\nDrawCredit = 0x1507E0; // type:func\nPlaceCredit = 0x150898; // type:func\nVacateCredit = 0x150910; // type:func\nSetCreditLine = 0x150938; // type:func\nCroutDecomp = 0x150AD0; // type:func\nCroutSolve = 0x150DF0; // type:func\nOnCrfodAdd = 0x150F60; // type:func\nOnCrfodRemove = 0x150FA8; // type:func\nCloneCrfod = 0x150FF0; // type:func\nInitCrfodb = 0x151040; // type:func\nCalcHeadingVector = 0x151078; // type:func\nUpdateCrfodbGoal = 0x1510B0; // type:func\nFDetectCrfodb = 0x151568; // type:func\nFAbsorbCrfodbWkr = 0x151730; // type:func\nSgsNextCrfodkAI = 0x151788; // type:func\nFDetectCrfodk = 0x1518D0; // type:func\nFAbsorbCrfodkWkr = 0x1518F8; // type:func\nInitCrbrain = 0x1519A8; // type:func\nActivateCrbrain = 0x1519E8; // type:func\nScoreCrbrain = 0x151A30; // type:func\nSMeasureApos = 0x151A58; // type:func\nGWrapApos = 0x151AE8; // type:func\nIposFindAposG = 0x151B50; // type:func\nEvaluateAposG = 0x151C38; // type:func\nFindAposClosestPointAll = 0x151D68; // type:func\nFindAposClosestPointSegment = 0x152050; // type:func\nConvertApos = 0x152318; // type:func\nPcrvNew = 0x1523A0; // type:func\nSFromCrvU = 0x152420; // type:func\nUFromCrvS = 0x152430; // type:func\nIcvFindCrvU = 0x152440; // type:func\nIcvFindCrvS = 0x152478; // type:func\nGMeasureCrvU = 0x1524B8; // type:func\nUMaxCrv = 0x152570; // type:func\nSMaxCrv = 0x152588; // type:func\nSMeasureCrvSegmentU = 0x1525A8; // type:func\nFindCrvClosestPointOnLineSegmentFromU = 0x152608; // type:func\nRenderCrv = 0x152738; // type:func\nRenderCrvAxesU = 0x1527F8; // type:func\nRenderCrvAxesS = 0x1528D8; // type:func\nDuGetCrvSearchIncrement = 0x152948; // type:func\nLoadCrvlFromBrx = 0x152970; // type:func\nEvaluateCrvlFromU = 0x152A80; // type:func\nEvaluateCrvlFromS = 0x152AC0; // type:func\nRenderCrvlSegment = 0x152B00; // type:func\nConvertCrvl = 0x152C08; // type:func\nSFromCrvlU = 0x152C40; // type:func\nUFromCrvlS = 0x152CB0; // type:func\nMeasureCrvl = 0x152D20; // type:func\nFindCrvlClosestPointAll = 0x152D50; // type:func\nFindCrvlClosestPointFromU = 0x152E30; // type:func\nFindCrvlClosestPointFromS = 0x152F70; // type:func\nLoadCrvcFromBrx = 0x1530B0; // type:func\nInvalidateCrvcCache = 0x153218; // type:func\nFillCrvcCache = 0x153228; // type:func\nEvaluateCrvcFromU = 0x1532E0; // type:func\nEvaluateCrvcFromS = 0x1533E0; // type:func\nRenderCrvcSegment = 0x153448; // type:func\nConvertCrvc = 0x153568; // type:func\nSFromCrvcU = 0x153668; // type:func\nUFromCrvcS = 0x1536F8; // type:func\nMeasureCrvc = 0x1537C8; // type:func\nFindCrvcClosestPointAll = 0x153898; // type:func\nFindCrvcClosestPointFromU = 0x153A18; // type:func\nFindCrvcClosestPointFromS = 0x153B48; // type:func\nInitCycle = 0x153BF0; // type:func\nPostCycleLoad = 0x153C50; // type:func\nPresetCycleAccel = 0x153CB0; // type:func\nUpdateCycleWheels = 0x1547A8; // type:func\nUpdateCycleExpls = 0x154A90; // type:func\nUpdateCycle = 0x154EF8; // type:func\nUpdateCycleActive = 0x154F58; // type:func\nUpdateCycleInternalXps = 0x155040; // type:func\nAddCycleCustomXps = 0x155050; // type:func\nAdjustCycleNewXp = 0x155260; // type:func\nRenderCycleSelf = 0x155388; // type:func\nUpdateCycleBounds = 0x155628; // type:func\nUpdateCycleXfWorld = 0x1556E0; // type:func\nGetCycleCpdefi = 0x155708; // type:func\nOnCycleActive = 0x155730; // type:func\nSetCycleCycles = 0x155758; // type:func\nInitDart = 0x155778; // type:func\nOnDartAdd = 0x1557B8; // type:func\nRemoveDart = 0x155868; // type:func\nCloneDart = 0x1558C0; // type:func\nLoadDartFromBrx = 0x155910; // type:func\nHandleDartMessage = 0x155950; // type:func\nPostDartLoad = 0x1559C8; // type:func\nUpdateDart = 0x155A10; // type:func\nGetDartParams = 0x155AE0; // type:func\nSetDartDarts = 0x155B48; // type:func\nApplyDartThrow = 0x155BA8; // type:func\nUpdateDartAirborne = 0x155C80; // type:func\nInitDartgun = 0x1561E0; // type:func\nHandleDartgunMessage = 0x156218; // type:func\nBindDartgun = 0x156310; // type:func\nPostDartgunLoad = 0x1563E8; // type:func\nUpdateDartgun = 0x156578; // type:func\nFIgnoreDartgunIntersection = 0x156710; // type:func\nGetDartgunParams = 0x156780; // type:func\nBreakDartgun = 0x1567E8; // type:func\nSetDartgunGoalState = 0x1568B0; // type:func\nTrackDartgun = 0x156980; // type:func\nFPrepareDartgunToFire = 0x156AB0; // type:func\nFireDartgun = 0x156C18; // type:func\nAgeDartgunStuckDart = 0x156EE0; // type:func\nPratGetDartgunRatTarget = 0x156FA0; // type:func\nAddDartgunRatTarget = 0x157050; // type:func\nStartDartgunTargetAreaChange = 0x157078; // type:func\nAddDartgunTargetAreaTarget = 0x157088; // type:func\nInitDialog = 0x157160; // type:func\nLoadDialogFromBrx = 0x1571C0; // type:func\nLoadDialogEventsFromBrx = 0x157218; // type:func\nSetDialogInstruct = 0x157400; // type:func\nSetDialogConfront = 0x157410; // type:func\nGetDialogPlayed = 0x157420; // type:func\nSetDialogPlayed = 0x157430; // type:func\nSetDialogDialogs = 0x157440; // type:func\nUpdateDialog = 0x157738; // type:func\nHandleDialogEvent = 0x157920; // type:func\nHandleDialogMessage = 0x157E58; // type:func\nFPauseDialog = 0x157EB8; // type:func\nHandleDialogEvents = 0x1582C0; // type:func\nTriggerDialog = 0x1583D0; // type:func\nUntriggerDialog = 0x1584B8; // type:func\nAddDialogEquivalence = 0x1584E8; // type:func\nPdifficultyEnsureSw = 0x1585B8; // type:func\nOnDifficultyGameLoad = 0x1585C8; // type:func\nOnDifficultyWorldPreLoad = 0x1585F0; // type:func\nOnDifficultyWorldPostLoad = 0x1586B0; // type:func\nOnDifficultyInitialTeleport = 0x158778; // type:func\nOnDifficultyPlayerDeath = 0x158780; // type:func\nOnDifficultyTriggerCheckpoint = 0x1587E0; // type:func\nOnDifficultyCollectKey = 0x1588E8; // type:func\nOnDifficultyAward = 0x158928; // type:func\nOnDifficultyBreak = 0x1589D8; // type:func\nOnDifficultyNpc = 0x158B28; // type:func\nOnDifficultyMiniNpc = 0x158B90; // type:func\nChangeSuck = 0x158BF8; // type:func\nResetSuckChkpnts = 0x158C58; // type:func\nSetSuckChkpnts = 0x158C90; // type:func\nInitDl = 0x158D00; // type:func\nClearDl = 0x158D08; // type:func\nClearDle = 0x158D18; // type:func\nPdleFromDlEntry = 0x158D28; // type:func\nAppendDlEntry = 0x158D38; // type:func\nPrependDlEntry = 0x158DB0; // type:func\nInsertDlEntryBefore = 0x158E28; // type:func\nRemoveDlEntry = 0x158F00; // type:func\nFFindDlEntry = 0x158FF0; // type:func\nFIsDlEmpty = 0x159048; // type:func\nMergeDl = 0x159058; // type:func\nCPvDl = 0x159120; // type:func\nStartupDma = 0x159158; // type:func\nDMAS__DMAS = 0x1591E8; // type:func\nDMAS__Clear = 0x159230; // type:func\nDMAS__Reset = 0x159248; // type:func\nDMAS__AllocGlobal = 0x159258; // type:func\nDMAS__AllocSw = 0x1592A8; // type:func\nDMAS__AllocStack = 0x1592F8; // type:func\nDMAS__AllocStatic = 0x159348; // type:func\nDMAS__Detach = 0x159360; // type:func\nDMAS__DetachCopySw = 0x1593E0; // type:func\nDMAS__Send = 0x159488; // type:func\nDMAS__Sync = 0x1594F0; // type:func\nDMAS__AddDmaCnt = 0x159520; // type:func\nDMAS__AddDmaRefs = 0x159570; // type:func\nDMAS__AddDmaCall = 0x159610; // type:func\nDMAS__AddDmaRet = 0x1596A0; // type:func\nDMAS__AddDmaBulk = 0x1596E8; // type:func\nDMAS__AddDmaEnd = 0x159740; // type:func\nDMAS__EndDmaCnt = 0x159788; // type:func\nDMAS__EndPrim = 0x159830; // type:func\nPostDspLoad = 0x159840; // type:func\nUpdateDsp = 0x159A18; // type:func\nInitDysh = 0x159CA0; // type:func\nSetDyshShadow = 0x159CC8; // type:func\nRenderDyshSelf = 0x15A2C8; // type:func\nDrawDysh = 0x15A370; // type:func\nInitDzg = 0x15A540; // type:func\nClearDzgSolution = 0x15A648; // type:func\nAppendDzgDz = 0x15A730; // type:func\nFillDzgDz = 0x15A7F0; // type:func\nEnforceDzgDz = 0x15AAF0; // type:func\nSolveDzg = 0x15AFD8; // type:func\nSolveDzgFric = 0x15B1C8; // type:func\nApplyDzg = 0x15B4D0; // type:func\nSolveInequalities = 0x15BA10; // type:func\nInitEmitb = 0x15BB90; // type:func\nInitEmitter = 0x15BDF0; // type:func\nLoadEmitmeshFromBrx = 0x15BE70; // type:func\nLoadEmitblipColorsFromBrx = 0x15BFF8; // type:func\nLoadEmitterFromBrx = 0x15C0D8; // type:func\nCloneEmitter = 0x15C208; // type:func\nBindEmitterCallback = 0x15C248; // type:func\nBindEmitter = 0x15C278; // type:func\nPostEmitterLoad = 0x15C450; // type:func\nHandleEmitterMessage = 0x15C888; // type:func\nGetEmitterParams = 0x15C8F8; // type:func\nRenderEmitterSelf = 0x15C928; // type:func\nPemitbCopyOnWrite = 0x15CA00; // type:func\nPemitbEnsureEmitter = 0x15CAA0; // type:func\nPemitterEnsureEmitter = 0x15CB00; // type:func\nAddEmitterSkeleton = 0x15CB18; // type:func\nModifyEmitterParticles = 0x15CBC0; // type:func\nUpdateEmitter = 0x15CE20; // type:func\nPauseEmitter = 0x15D3C0; // type:func\nPauseEmitterIndefinite = 0x15D3D8; // type:func\nUnpauseEmitter = 0x15D3E8; // type:func\nFPausedEmitter = 0x15D3F8; // type:func\nSetEmitterEnabled = 0x15D448; // type:func\nGetEmitterEnabled = 0x15D488; // type:func\nGetEmitterPaused = 0x15D4C0; // type:func\nOnEmitterValuesChanged = 0x15D4F0; // type:func\nSetEmitterParticleCount = 0x15D588; // type:func\nSetEmitterAutoPause = 0x15D608; // type:func\nSetEmitbRipt = 0x15D618; // type:func\nSetEmitterRipt = 0x15D6B0; // type:func\nSetExploRipt = 0x15D6F8; // type:func\nWakeSoWater = 0x15D740; // type:func\nStandardSmokeCloud = 0x15DBA0; // type:func\nChooseEmitoPos = 0x15DBF0; // type:func\nConvertEmitoPosVec = 0x15E400; // type:func\nCalculateEmitvx = 0x15E4D8; // type:func\nChooseEmitVelocity = 0x15E5B8; // type:func\nChooseEmitvVelocityAge = 0x15E798; // type:func\nEmitRips = 0x15E888; // type:func\nEmitBlips = 0x15EB60; // type:func\nOriginateParticles = 0x15EF70; // type:func\nOriginateSplineSinkParticles = 0x15F180; // type:func\nEmitParticles = 0x15F420; // type:func\nEmitRipsSphere = 0x15F548; // type:func\nStockSplashBig = 0x15F660; // type:func\nStockSplashSmall = 0x15F770; // type:func\nAddEmitoSkeleton = 0x15F808; // type:func\nBindEmitb = 0x15F900; // type:func\nSetEmitdvEmitb = 0x15FA80; // type:func\nCalculateEmitdvMatrix = 0x15FB18; // type:func\nPostExplLoad = 0x15FCB8; // type:func\nCalculateExplTransform = 0x15FCF8; // type:func\nExplodeExpl = 0x15FDF8; // type:func\nExplodeExplParams = 0x15FE48; // type:func\nExplodeExplExplso = 0x15FE90; // type:func\nLoadExplgFromBrx = 0x15FE98; // type:func\nCloneExplg = 0x160098; // type:func\nBindExplg = 0x160140; // type:func\nExplodeExplgExplso = 0x1601B0; // type:func\nInitExplo = 0x160230; // type:func\nLoadExploFromBrx = 0x160268; // type:func\nCloneExplo = 0x1603B0; // type:func\nBindExplo = 0x1603F0; // type:func\nExplodeExploExplso = 0x1604E8; // type:func\nGetExploParams = 0x1604F0; // type:func\nAddExploSkeleton = 0x160520; // type:func\nPemitbEnsureExplo = 0x1605C8; // type:func\nInitExpls = 0x160608; // type:func\nBindExpls = 0x160648; // type:func\nHandleExplsMessage = 0x160740; // type:func\nExplodeExplsExplso = 0x1607B0; // type:func\nGetExplsParams = 0x1608B8; // type:func\nUpdateExplsLiveEdit = 0x1608E8; // type:func\nPsfxEnsureExpls = 0x160A50; // type:func\nFireExplsExplso = 0x160A90; // type:func\nInferExpl = 0x160EC0; // type:func\nFireSwTimedExplodeStyles = 0x160FE8; // type:func\nInitEyes = 0x161110; // type:func\nPostEyesLoad = 0x161178; // type:func\nSetEyesEyess = 0x161220; // type:func\nUpdateEyes = 0x161350; // type:func\nSetEyesClosed = 0x1614E0; // type:func\nPsaiFromEyesShd = 0x161580; // type:func\nUpdateFader = 0x1615D8; // type:func\nPfaderNew = 0x1616C8; // type:func\nRemoveFader = 0x161758; // type:func\nPdlFromSwOid = 0x1617E8; // type:func\nMatchSwObject = 0x161810; // type:func\nCploFindSwObjects = 0x161A68; // type:func\nPloFindSwObject = 0x161D08; // type:func\nPloFindSwNearest = 0x161D40; // type:func\nPloFindSwChild = 0x161D80; // type:func\nFIsCidDerivedFrom = 0x161DC0; // type:func\nCploFindSwObjectsByClass = 0x161DF8; // type:func\nPloFindSwObjectByClass = 0x162168; // type:func\nPaloFindLoCommonParent = 0x1621A0; // type:func\nInitFlash = 0x1621F0; // type:func\nLoadFlashFromBrx = 0x162258; // type:func\nUpdateFlash = 0x1622B0; // type:func\nRenderFlashSelf = 0x162308; // type:func\nFPosFlashWithin = 0x1623D0; // type:func\nInitFly = 0x162470; // type:func\nLoadFlyFromBrx = 0x1625A8; // type:func\nCloneFly = 0x162778; // type:func\nFreezeFly = 0x162850; // type:func\nPostFlyLoad = 0x1628D8; // type:func\nPresetFlyAccel = 0x1629A0; // type:func\nUpdateFly = 0x162BC0; // type:func\nRenderFlySelf = 0x162FD0; // type:func\nFAbsorbFlyWkr = 0x163228; // type:func\nGetFlyParams = 0x1632D0; // type:func\nSetFlyFlys = 0x163338; // type:func\nEmitFlyDroppings = 0x163868; // type:func\nFFindFlyClosestLandingPos = 0x163948; // type:func\nFlysAttemptedFlyLanding = 0x163B20; // type:func\nFShouldFlyFlee = 0x163C00; // type:func\nFFilterFly = 0x163CA0; // type:func\nFCheckFlyOpenSpaceBelow = 0x163CE8; // type:func\nStartupFont = 0x163DE0; // type:func\nCFont__CopyTo = 0x163DF8; // type:func\nCFont__SetupDraw = 0x163E88; // type:func\nCFont__CleanupDraw = 0x163F68; // type:func\nCFont__DxFromPchz = 0x163FD0; // type:func\nCFont__DyWrapPchz = 0x164060; // type:func\nCFont__ClineWrapPchz = 0x1640A8; // type:func\nCFont__DxMaxLine = 0x1641F0; // type:func\nCFont__GetExtents = 0x1642A0; // type:func\nCFont__DrawPchz = 0x164340; // type:func\nCFont__PushScaling = 0x1645C0; // type:func\nCFont__PopScaling = 0x164630; // type:func\nCFontDebug__CFontDebug = 0x164698; // type:func\nCFontDebug__PfontClone = 0x1646E0; // type:func\nCFontDebug__CopyTo = 0x164778; // type:func\nCFontDebug__FValid = 0x1647A0; // type:func\nCFontDebug__DxFromCh = 0x1647E0; // type:func\nCFontDebug__SetupDraw = 0x164850; // type:func\nCFontDebug__SwitchTex0 = 0x164908; // type:func\nCFontDebug__DxDrawCh = 0x164910; // type:func\nCFontDebug__EdgeRect = 0x164C70; // type:func\nCFontBrx__PfontClone = 0x164C78; // type:func\nCFontBrx__CopyTo = 0x164D08; // type:func\nCFontBrx__FValid = 0x164D90; // type:func\nCFontBrx__DxFromCh = 0x164DC0; // type:func\nCFontBrx__FEnsureLoaded = 0x164E20; // type:func\nCFontBrx__SetupDraw = 0x164F10; // type:func\nCFontBrx__SwitchTex0 = 0x165038; // type:func\nCFontBrx__DxDrawCh = 0x165100; // type:func\nCFontBrx__DrawPart = 0x165380; // type:func\nCFontBrx__EdgeRect = 0x165550; // type:func\nCFontBrx__LoadFromBrx = 0x165930; // type:func\nCFontBrx__PostLoad = 0x165A20; // type:func\nCFontBrx__PglyffFromCh = 0x165B98; // type:func\nCRichText__CRichText = 0x165C08; // type:func\nCRichText__Reset = 0x165C68; // type:func\nCRichText__SetBaseColor = 0x165CA0; // type:func\nCRichText__ChNext = 0x165CC8; // type:func\nCRichText__Cch = 0x165FD0; // type:func\nCRichText__Trim = 0x166030; // type:func\nCRichText__Dx = 0x1660A0; // type:func\nCRichText__ClineWrap = 0x166120; // type:func\nCRichText__DxMaxLine = 0x166258; // type:func\nCRichText__GetExtents = 0x166300; // type:func\nCRichText__Draw = 0x166398; // type:func\nPostFontsLoad = 0x166698; // type:func\n__static_initialization_and_destruction_05 = 0x166730; // type:func\n_GLOBAL_$I$g_fontDebug = 0x166798; // type:func\nVU1_Interrupt = 0x1667C0; // type:func\nStartupFrame = 0x166928; // type:func\nOpenFrame = 0x166AE8; // type:func\nEnsureVu1Code = 0x166CC8; // type:func\nFinalizeFrameVifs = 0x166D10; // type:func\nFinalizeFrameGifs = 0x166E30; // type:func\nCloseFrame = 0x166ED0; // type:func\nPrepareGsForFrameRender = 0x166FE0; // type:func\nFrameRenderLoop = 0x167058; // type:func\nRenderFrame = 0x1671F0; // type:func\nClearPendingFrame = 0x167268; // type:func\nFlushFrames = 0x1674F8; // type:func\nBlendPrevFrame = 0x167640; // type:func\n__static_initialization_and_destruction_06 = 0x1679C8; // type:func\n_GLOBAL_$I$g_gifs = 0x167A10; // type:func\nRemergeSwObject = 0x167A38; // type:func\nMergeSwFreezeGroups = 0x167A80; // type:func\nSplinterSwFreezeGroup = 0x167AD8; // type:func\nMergeSwGroup = 0x167BC0; // type:func\nAddSwMergeGroup = 0x167CC0; // type:func\nRemoveFromArray = 0x167D48; // type:func\nRemoveSwMergeGroup = 0x167DC0; // type:func\nRemergeSwObjects = 0x167E90; // type:func\nFreezeAloHierarchy = 0x167F78; // type:func\nGetAloFrozen = 0x168000; // type:func\nFreezeAlo = 0x168018; // type:func\nFreezeSo = 0x168148; // type:func\nRefreezeSwObjects = 0x168210; // type:func\nUpdateSwBusyList = 0x168448; // type:func\nPostFrzgLoad = 0x168488; // type:func\nAddFrzgObject = 0x168578; // type:func\nStartupGame = 0x168598; // type:func\nPchzFromLevel = 0x1686E0; // type:func\nPchzFriendlyFromLevel = 0x168730; // type:func\nPchzFriendlyFromWorld = 0x168790; // type:func\nFFindLevel = 0x168820; // type:func\nInitGameState = 0x1688D8; // type:func\nSetupGame = 0x168968; // type:func\nUpdateGameState = 0x168AC8; // type:func\nGrflsFromWid = 0x168B08; // type:func\nClearLs = 0x168B80; // type:func\nUnloadGame = 0x168BA8; // type:func\nRetryGame = 0x168C10; // type:func\nStartGame = 0x168C50; // type:func\nSetCcharm = 0x168C90; // type:func\nFCharmAvailable = 0x168CA0; // type:func\nSetClife = 0x168CE8; // type:func\nSetCcoin = 0x168D40; // type:func\nPfLookupDialog = 0x168D78; // type:func\nAchzFromGameworld = 0x168DA0; // type:func\nCwlpGetWlps = 0x168DB8; // type:func\nOnGameLoad = 0x168E30; // type:func\nOnGameWorldTransition = 0x168E58; // type:func\nOnGameAlarmTriggered = 0x168EB0; // type:func\nOnGameAlarmDisabled = 0x168EF8; // type:func\nOnGameEnterUis = 0x168F48; // type:func\nStartGameTimedChallenge = 0x168F98; // type:func\nEndGameTimedChallenge = 0x169098; // type:func\nOnGameTimedChallengeTimerNotify = 0x169168; // type:func\nStartGameTimedChallengeTimer = 0x169258; // type:func\nResetGameTimedChallenge = 0x169320; // type:func\nPrepareGameGoldForTimedChallenge = 0x169330; // type:func\nGetBlueprintInfo = 0x169340; // type:func\nCcharmMost = 0x1693D0; // type:func\nInitGeom = 0x169400; // type:func\nCloneGeom = 0x169420; // type:func\nBuildGeomPointMap = 0x1695C8; // type:func\nGIFS__GIFS = 0x169778; // type:func\nGIFS__AddPrimEnd = 0x1697C8; // type:func\nGIFS__EndPrim = 0x169848; // type:func\nGIFS__CheckReg = 0x1698B8; // type:func\nGIFS__AddPrimBulk = 0x1698C8; // type:func\nGIFS__AddPrimPack = 0x169990; // type:func\nGIFS__PackRGBA = 0x169A28; // type:func\nGIFS__PackUV = 0x169AA0; // type:func\nGIFS__PackSTQ = 0x169B00; // type:func\nGIFS__PackXYZ = 0x169B70; // type:func\nGIFS__PackXYZF = 0x169BE0; // type:func\nGIFS__PackXYZFNoKick = 0x169C68; // type:func\nGIFS__PackAD = 0x169D08; // type:func\nGIFS__AddPrimList = 0x169D70; // type:func\nGIFS__ListRGBAQ = 0x169DF0; // type:func\nGIFS__ListUV = 0x169E70; // type:func\nGIFS__ListXYZF = 0x169ED8; // type:func\nGIFS__AddImage = 0x169F78; // type:func\nGLBS__GLBS = 0x169FE0; // type:func\nGLBS__~GLBS = 0x16A0C0; // type:func\nGLBS__SetTransform = 0x16A0F0; // type:func\nGLBS__FindLights = 0x16A168; // type:func\nGLBS__ResetStrip = 0x16A1E8; // type:func\nGLBS__BeginStrip = 0x16A220; // type:func\nGLBS__DrawPrelit = 0x16A280; // type:func\nGLBS__DrawThreeWay = 0x16A658; // type:func\nGLBS__EndStrip = 0x16AC88; // type:func\nGLBS__SetPos = 0x16AE40; // type:func\nGLBS__SetNormal = 0x16AE60; // type:func\nGLBS__SetRgba = 0x16AE80; // type:func\nGLBS__SetUv = 0x16AE98; // type:func\nGLBS__AddVtx = 0x16AEB0; // type:func\nBuildGlobsetSaaArray = 0x16B000; // type:func\nLoadGlobsetFromBrx = 0x16B088; // type:func\nEnsureBuffer = 0x16C450; // type:func\nEnsureBufferCel = 0x16C4E8; // type:func\nBuildSubcel = 0x16C580; // type:func\nBuildSubglobSinglePass = 0x16CAC8; // type:func\nBuildSubglobThreeWay = 0x16D648; // type:func\nBuildSubglobLighting = 0x16E5E0; // type:func\nPostGlobsetLoad = 0x16E808; // type:func\nBindGlobset = 0x16E910; // type:func\nCloneGlobset = 0x16EA40; // type:func\nCloneGlob = 0x16EC38; // type:func\nUpdateGlobset = 0x16F180; // type:func\nUpdateAloConstraints = 0x16F258; // type:func\nUpdateAloInfluences = 0x16F2E8; // type:func\nPredrawGlob = 0x16F4D0; // type:func\nRotateVu1Buffer = 0x16F8C8; // type:func\nDrawGlob = 0x16F908; // type:func\n__static_initialization_and_destruction_07 = 0x1710B0; // type:func\n_GLOBAL_$I$g_dro = 0x1710D8; // type:func\nInitGomer = 0x171100; // type:func\nPostGomerLoad = 0x1711A8; // type:func\nRenderGomerSelf = 0x1712D8; // type:func\nFDetectGomer = 0x171748; // type:func\nGetGomerParams = 0x171970; // type:func\nBlendDisplayOnBufferMismatch = 0x1719D8; // type:func\nVBlankS_Interrupt = 0x171B68; // type:func\nSyncVBlank = 0x171C80; // type:func\nSwapGsBuffers = 0x171CB8; // type:func\nRestoreGsBuffers = 0x171DE8; // type:func\nGS_Interrupt = 0x171EF8; // type:func\nResetGs = 0x171F50; // type:func\nSendDmaSyncGsFinish = 0x171F90; // type:func\nBuildClearGifs = 0x172040; // type:func\nStartupGs = 0x1721B0; // type:func\nBlastAqwGifsBothFrames = 0x172390; // type:func\nClearFrameBuffers = 0x172470; // type:func\nFadeFramesToBlack = 0x172510; // type:func\nResetGsMemory = 0x172728; // type:func\nNLog2 = 0x172760; // type:func\nInitGsb = 0x172798; // type:func\nResetGsb = 0x1727A8; // type:func\nIgsAllocGsb = 0x1727B8; // type:func\nBuildImageGifs = 0x1727C8; // type:func\nBuildClutTex2 = 0x1728C0; // type:func\nBuildClutGifs = 0x172990; // type:func\nBuildBmpTex0 = 0x172A00; // type:func\nBuildBmpGifs = 0x172AE8; // type:func\nFBuildUploadBitmapGifs = 0x172B28; // type:func\nUploadBitmaps = 0x172D60; // type:func\nPqwGifsBitmapUpload = 0x172EB8; // type:func\nPropagateSur = 0x173018; // type:func\nReferenceShaderAqwRegs = 0x173078; // type:func\nReferenceUVAnimation = 0x173198; // type:func\nRebaseSurs = 0x173258; // type:func\nPropagateSurs = 0x1732B8; // type:func\nPqwVifsBitmapUpload = 0x173330; // type:func\nDrawOnBitmap = 0x1737A8; // type:func\nInitHg = 0x173900; // type:func\nPostHgLoad = 0x173960; // type:func\nPresetHgAccel = 0x1739F0; // type:func\nUpdateHg = 0x173E40; // type:func\nUpdateHgActive = 0x173F00; // type:func\nRenderHgSelf = 0x1743C8; // type:func\nGetHgCpdefi = 0x174468; // type:func\nSetHgHgs = 0x174490; // type:func\nStartupHide = 0x174558; // type:func\nResetHideList = 0x1745B0; // type:func\nInitHshape = 0x1745F8; // type:func\nOnHshapeAdd = 0x174640; // type:func\nOnHshapeRemove = 0x174688; // type:func\nBindHshape = 0x1746D0; // type:func\nCloneHshape = 0x174718; // type:func\nGetHshapeHidePos = 0x174768; // type:func\nGetHshapeClosestHidePos = 0x174928; // type:func\nInitHpnt = 0x174A70; // type:func\nOnHpntAdd = 0x174AB0; // type:func\nOnHpntRemove = 0x174AF8; // type:func\nBindHpnt = 0x174B40; // type:func\nCloneHpnt = 0x174B88; // type:func\nGetHpntClosestHidePos = 0x174BD8; // type:func\nInitHbsk = 0x174D58; // type:func\nLoadHbskFromBrx = 0x174DE8; // type:func\nOnHbskAdd = 0x174E68; // type:func\nOnHbskRemove = 0x174EB0; // type:func\nCloneHbsk = 0x174EF8; // type:func\nFIgnoreHbskIntersection = 0x174F48; // type:func\nPresetHbskAccel = 0x174F90; // type:func\nSetHbskHbsks = 0x175018; // type:func\nCdartStuckHbsk = 0x1751C0; // type:func\nPdartOldestHbskStuck = 0x175298; // type:func\nGetHbskClosestHidePos = 0x175398; // type:func\nInitHnd = 0x1754B0; // type:func\nLoadHndFromBrx = 0x1754F0; // type:func\nRenderIkhSelf = 0x175520; // type:func\nRenderLikhSelf = 0x175548; // type:func\nSolveAloIK = 0x175570; // type:func\nInitJack = 0x175E98; // type:func\nPostJackLoad = 0x175F00; // type:func\nUpdateJackActive = 0x176168; // type:func\nSetJackJacks = 0x1768A0; // type:func\nPjacknAllocJack = 0x176970; // type:func\nTakeJackDamage = 0x176A48; // type:func\nAddJackPrize = 0x176A70; // type:func\nInitJackb = 0x176B20; // type:func\nPostJackbLoad = 0x176B58; // type:func\nPlanJackbChase = 0x176C60; // type:func\nUpdateJackb = 0x177280; // type:func\nHandleJackbMessage = 0x177530; // type:func\nSetJackbJbs = 0x177610; // type:func\nInitJackn = 0x1776B0; // type:func\nLoadJacknFromBrx = 0x1776D8; // type:func\nUpdateJackn = 0x177778; // type:func\nRenderJacknSelf = 0x1779A8; // type:func\nRebindJackn = 0x177A20; // type:func\nInitJackf = 0x177CB8; // type:func\nUpdateJackf = 0x177D48; // type:func\nBuildJackfRim = 0x177DE8; // type:func\nJekClassifyJackfVertex = 0x177F20; // type:func\nJekClassifyJackfEdge = 0x178018; // type:func\nNCmpJep = 0x1780F0; // type:func\nUpdateJackfGrid = 0x178140; // type:func\nCjeSpliceJackfRim = 0x178548; // type:func\nApplyJackfGap = 0x178648; // type:func\nJkFromJackfIJK = 0x1789E0; // type:func\nGetJackfPos = 0x178A28; // type:func\nGetJackfRim = 0x178A80; // type:func\nGetJackfGap = 0x178BD8; // type:func\nMapJackfCell = 0x178D50; // type:func\nIjeFindJackfClosestEdge = 0x178E60; // type:func\nDrawJackf = 0x179080; // type:func\nRenderJackfSelf = 0x179AB0; // type:func\nDropJackf = 0x179B68; // type:func\nCalculateJackfField = 0x179D40; // type:func\nInitJlo = 0x17A0D8; // type:func\nLoadJloFromBrx = 0x17A150; // type:func\nPostJloLoad = 0x17A260; // type:func\nPresetJloAccel = 0x17A3C8; // type:func\nUpdateJlo = 0x17A438; // type:func\nJlosNextJlo = 0x17A510; // type:func\nSetJloJlovol = 0x17A740; // type:func\nFireJlo = 0x17A7D8; // type:func\nLandJlo = 0x17AAE8; // type:func\nJumpJlo = 0x17AB98; // type:func\nHandleJloMessage = 0x17ACB0; // type:func\nSetJloJlos = 0x17AD78; // type:func\nActivateJlo = 0x17B010; // type:func\nDeactivateJlo = 0x17B020; // type:func\nInitJloc = 0x17B030; // type:func\nLoadJlocFromBrx = 0x17B0B8; // type:func\nPostJlocLoad = 0x17B120; // type:func\nPxfmChooseJloc = 0x17B160; // type:func\nGetJlocParams = 0x17B298; // type:func\nInitJlovol = 0x17B300; // type:func\nBindJlovol = 0x17B340; // type:func\nHandleJlovolMessage = 0x17B3E0; // type:func\nStartupJoy = 0x17B480; // type:func\nAddGrfusr = 0x17B4D0; // type:func\nRemoveGrfusr = 0x17B500; // type:func\nUpdateGrfjoytFromGrfusr = 0x17B538; // type:func\nInitJoy = 0x17B590; // type:func\nUpdateJoy = 0x17B650; // type:func\nSetJoyJoys = 0x17BAE8; // type:func\nGetJoyXYDeflection = 0x17BBF8; // type:func\nFReadJoy = 0x17BE00; // type:func\nSetJoyBtnHandled = 0x17C020; // type:func\nTriggerJoyRumbleRumk = 0x17C038; // type:func\nEnableJoyRumble = 0x17C080; // type:func\nStartJoySelection = 0x17C0E8; // type:func\nDxSelectionJoy = 0x17C0F8; // type:func\nDySelectionJoy = 0x17C2C0; // type:func\nUBtnpJoy = 0x17C488; // type:func\nAddCode = 0x17C508; // type:func\n_ResetCodes = 0x17C578; // type:func\n_MatchCodes = 0x17C5B8; // type:func\nUpdateCodes = 0x17C660; // type:func\nAddFcht = 0x17C7A0; // type:func\nLoadLevel = 0x17C7E8; // type:func\nStartupCodes = 0x17C8D0; // type:func\nInitJt = 0x17CA10; // type:func\nLoadJtFromBrx = 0x17CBA0; // type:func\nPostJtLoad = 0x17CC18; // type:func\nPresetJtAccelBase = 0x17D1B0; // type:func\nPresetJtAccel = 0x17D628; // type:func\nAdjustJtNewXp = 0x17D858; // type:func\nAdjustJtDz = 0x17D958; // type:func\nHandleJtGrfjtsc = 0x17DA00; // type:func\nUpdateJtInternalXps = 0x17DAA8; // type:func\nFCheckJtXpBase = 0x17DC08; // type:func\nAdjustJtXpVelocity = 0x17DCA0; // type:func\nHandleJtMessage = 0x17DDE8; // type:func\nFTurnJtToTarget = 0x17E688; // type:func\nUpdateJtBalance = 0x17E760; // type:func\nRebuildJtXmg = 0x17ECA8; // type:func\nFMatchJtXmg = 0x17EF60; // type:func\nUpdateJtStand = 0x17F0E8; // type:func\nThrowJt = 0x17F270; // type:func\nUnhookJt = 0x17F338; // type:func\nCalculateJtToolSpin = 0x17F3D0; // type:func\nRenderJtAll = 0x17F510; // type:func\nRenderJtSelf = 0x17F888; // type:func\nUpdateJtTool = 0x17FCC8; // type:func\nAdjustJtXps = 0x17FDC0; // type:func\nUpdateJtPosWorldPrev = 0x1801B8; // type:func\nProjectJtTransform = 0x1801E8; // type:func\nUpdateJtBounds = 0x1802A0; // type:func\nPsoGetJtEffect = 0x180320; // type:func\nAddJtCustomXps = 0x180400; // type:func\nCtTorqueJt = 0x180598; // type:func\nGetJtCpdefi = 0x1805C0; // type:func\nGetJtCpdefiFlatten = 0x180C88; // type:func\nUpdateJtActive = 0x180FF0; // type:func\nUpdateJt = 0x181E70; // type:func\nUpdateJtDrive = 0x182918; // type:func\nChooseJtPhys = 0x182A38; // type:func\nEnableJtActadj = 0x182B70; // type:func\nSetJtJts = 0x182C68; // type:func\nProfileJt = 0x184DA0; // type:func\nSetJtPuppet = 0x184DB0; // type:func\nPaloAbsorbWkr = 0x184E48; // type:func\nNCmpWkr = 0x184F78; // type:func\nUpdateJtEffect = 0x184FA0; // type:func\nFIsJtSoundBase = 0x185400; // type:func\nCollectJtPrize = 0x185458; // type:func\nGetJtDiapi = 0x185568; // type:func\nPlayJtDialog = 0x185658; // type:func\nInitJp = 0x1856F0; // type:func\nPostJpLoad = 0x185750; // type:func\nPresetJpAccel = 0x1857E0; // type:func\nUpdateJp = 0x185B38; // type:func\nUpdateJpActive = 0x185F18; // type:func\nRenderJpSelf = 0x186610; // type:func\nUseJpCharm = 0x1866B0; // type:func\nOnJpActive = 0x186700; // type:func\nRenderJpAll = 0x1867B8; // type:func\nFInvulnerableJp = 0x186A38; // type:func\nApplyJpThrow = 0x186A80; // type:func\nFTakeJpDamage = 0x186B88; // type:func\nAdjustJpXps = 0x186D00; // type:func\nHandleJpMessage = 0x186EB8; // type:func\nJthsCurrentJp = 0x186F28; // type:func\nSetJpJps = 0x186F38; // type:func\nInitJsg = 0x187100; // type:func\nGetJsgLocation = 0x187140; // type:func\nSetJsgFocus = 0x187330; // type:func\nSetJsgTn = 0x1873E0; // type:func\nNextJsgJsge = 0x1874B0; // type:func\nFIsJsgJsgeComplete = 0x187BD0; // type:func\nUpdateJsgJsge = 0x187DA0; // type:func\nReadJsgJoystick = 0x187E78; // type:func\nFIsJsgActive = 0x188158; // type:func\nClearJsg = 0x188198; // type:func\nApplyJsg = 0x1881D8; // type:func\nRetractJsg = 0x188230; // type:func\nPjsgeAllocJsg = 0x1882F0; // type:func\nAddJsgContext = 0x188390; // type:func\nAddJsgCut = 0x1883C0; // type:func\nAddJsgFocus = 0x1883F0; // type:func\nAddJsgLabel = 0x188420; // type:func\nAddJsgTunnel = 0x188450; // type:func\nAddJsgPause = 0x188480; // type:func\nAddJsgAseg = 0x1884C0; // type:func\nAddJsgJump = 0x1884F0; // type:func\nAddJsgRun = 0x188540; // type:func\nAddJsgClimb = 0x188580; // type:func\nAddJsgAttack = 0x1885C0; // type:func\nAddJsgClock = 0x1885F8; // type:func\nPresetJtAccelJump = 0x188638; // type:func\nUpdateJtActiveJump = 0x188A10; // type:func\nFCheckJtSingleEdge = 0x189168; // type:func\nFCheckJtEdgeNormal = 0x189310; // type:func\nFCheckJtEdgeGrab = 0x189540; // type:func\nPxpFindJtBestEdge = 0x189910; // type:func\nJtsResetJt = 0x189C30; // type:func\nHandleJtDiveEffect = 0x189C70; // type:func\nUpdateJtJump = 0x18A2C8; // type:func\nFTimeJtJumpToTarget = 0x18AC40; // type:func\nGetJtJumpVelocity = 0x18AD10; // type:func\nGetJtJumpToTargetVelocity = 0x18ADE0; // type:func\nGetJtJumpBoostVelocity = 0x18AE60; // type:func\nStartupJmt = 0x18AEE0; // type:func\nResetJmtList = 0x18AF10; // type:func\nOnJmtAdd = 0x18AF38; // type:func\nOnJmtRemove = 0x18AF80; // type:func\nCloneJmt = 0x18AFC8; // type:func\nPostJmtLoad = 0x18B018; // type:func\nInitKeyhole = 0x18B070; // type:func\nLoadKeyholeFromBrx = 0x18B0A8; // type:func\nDrawKeyholeMask = 0x18B340; // type:func\nDrawKeyhole = 0x18B610; // type:func\n__static_initialization_and_destruction_08 = 0x18C0F8; // type:func\n_GLOBAL_$I$InitKeyhole__FP7KEYHOLE = 0x18C150; // type:func\nOnLandingAdd = 0x18C178; // type:func\nOnLandingRemove = 0x18C1C0; // type:func\nCloneLanding = 0x18C208; // type:func\nInitLgn = 0x18C258; // type:func\nPostLgnLoad = 0x18C290; // type:func\nUpdateLgnActive = 0x18C370; // type:func\nUpdateLgn = 0x18C7B0; // type:func\nOnLgnActive = 0x18C9E0; // type:func\nRenderLgnAll = 0x18CA80; // type:func\nGetLgnCpdefi = 0x18CCE8; // type:func\nFInvulnerableLgn = 0x18CD30; // type:func\nJthsCurrentLgn = 0x18CD68; // type:func\nUseLgnCharm = 0x18CD78; // type:func\nApplyLgnThrow = 0x18CDC8; // type:func\nFTakeLgnDamage = 0x18CE88; // type:func\nHandleLgnMessage = 0x18D000; // type:func\nAdjustLgnXps = 0x18D078; // type:func\nSetLgnLgns = 0x18D220; // type:func\nUpdateLgnrAim = 0x18D330; // type:func\nDrawLgnr = 0x18D5D0; // type:func\nInitSwp = 0x18D858; // type:func\nPostSwpLoad = 0x18D8C8; // type:func\nUpdateSwp = 0x18D930; // type:func\nProjectSwpTransform = 0x18DB38; // type:func\nSetSwpShape = 0x18DD50; // type:func\nInitLgnb = 0x18E098; // type:func\nPostLgnbLoad = 0x18E0F0; // type:func\nUpdateLgnb = 0x18E168; // type:func\nPresetLgnbAccel = 0x18E2E0; // type:func\nFAbsorbLgnbWkr = 0x18E7E8; // type:func\nAttackLgnb = 0x18EB10; // type:func\nGetLgnbAttacking = 0x18EC38; // type:func\nInitLo = 0x18ECE0; // type:func\nPostLoLoad = 0x18ED20; // type:func\nAddLo = 0x18ED50; // type:func\nAddLoHierarchy = 0x18EDE8; // type:func\nOnLoAdd = 0x18EE30; // type:func\nRemoveLo = 0x18EE38; // type:func\nDeferLoRemove = 0x18EEE0; // type:func\nSetLoSuckHideLimits = 0x18EF48; // type:func\nRemoveLoHierarchy = 0x18EF98; // type:func\nOnLoRemove = 0x18EFE0; // type:func\nSnipLo = 0x18EFE8; // type:func\nFFindLoParent = 0x18F058; // type:func\nSetLoParent = 0x18F090; // type:func\nFIsLoInWorld = 0x18F0E0; // type:func\nGetLoInWorld = 0x18F150; // type:func\nPloCloneLo = 0x18F188; // type:func\nCloneLoHierarchy = 0x18F1E8; // type:func\nCloneLo = 0x18F210; // type:func\nSubscribeSwPpmqStruct = 0x18F380; // type:func\nUnsubscribeSwPpmqStruct = 0x18F3D8; // type:func\nSubscribeLoStruct = 0x18F438; // type:func\nUnsubscribeLoStruct = 0x18F470; // type:func\nSubscribeLoObject = 0x18F4A8; // type:func\nUnsubscribeLoObject = 0x18F4E0; // type:func\nSendLoMessage = 0x18F518; // type:func\nLoadLoFromBrx = 0x18F598; // type:func\nFMatchesLoName = 0x18F5C0; // type:func\nOidProxyLo = 0x18F608; // type:func\nOidProxyLoPreferred = 0x18F628; // type:func\nGetLoOidProxy = 0x18F648; // type:func\nPchzProxyLoPreferred = 0x18F680; // type:func\nPostSpliceEventCallback = 0x18F6A0; // type:func\nFFilterSpliceEvent = 0x18F8E8; // type:func\nHandleLoSpliceEvent = 0x18FA68; // type:func\nEnsureLoSidebagBool = 0x18FBF0; // type:func\nEnsureLoSidebagInt = 0x18FC90; // type:func\nEnsureLoSidebagFloat = 0x18FD30; // type:func\nEnsureLoSidebagClq = 0x18FDD8; // type:func\nEnsureLoSidebagLm = 0x18FE90; // type:func\nEnsureLoSidebagOid = 0x18FF50; // type:func\nEnsureLoSidebagVector = 0x18FFF0; // type:func\nPchzFromLo = 0x1900A8; // type:func\nInitLight = 0x1900E0; // type:func\nUpdateLightXfWorldHierarchy = 0x190198; // type:func\nRemoveLightFromSw = 0x1901E8; // type:func\nAddLightToSw = 0x190230; // type:func\nOnLightAdd = 0x190280; // type:func\nOnLightRemove = 0x1902C0; // type:func\nCloneLight = 0x190300; // type:func\nFitLinearFunction = 0x1903B8; // type:func\nFitRecipFunction = 0x190460; // type:func\nConvertFallOff = 0x190540; // type:func\nConvertAngleStrength = 0x190580; // type:func\nInvalidateLight = 0x190658; // type:func\nRebuildLightVifs = 0x190678; // type:func\nSetLightKind = 0x190CA8; // type:func\nSetLightHighlightColor = 0x190D18; // type:func\nSetLightMidtoneStrength = 0x190D48; // type:func\nSetLightShadowStrength = 0x190D70; // type:func\nSetLightHighlightAngle = 0x190D98; // type:func\nSetLightMidtoneAngle = 0x190DC0; // type:func\nSetLightShadowAngle = 0x190DE8; // type:func\nSetLightDirection = 0x190E10; // type:func\nSetLightDynamic = 0x190ED0; // type:func\nSetLightFallOff = 0x190F00; // type:func\nSetLightConeAngle = 0x190F50; // type:func\nSetLightHotSpotAngle = 0x190FA0; // type:func\nSetLightFrustrumUp = 0x190FE0; // type:func\nRebuildLightFrustrum = 0x191028; // type:func\nUpdateLightBeamGrfzon = 0x191120; // type:func\nSetLightDiffuse_Old = 0x1912B0; // type:func\nGetLightDiffuse_Old = 0x191300; // type:func\nSetLightSaturate_Old = 0x191310; // type:func\nGetLightSaturate_Old = 0x191358; // type:func\nGetLightParams = 0x191380; // type:func\nNCmpFindLight = 0x191410; // type:func\nPrepareSwLightsForDraw = 0x191480; // type:func\nTwpsFindSwLightsNoVu0 = 0x191838; // type:func\nTwpsFindSwLights = 0x191A28; // type:func\nInitActla = 0x191C50; // type:func\nSetActlaTarget = 0x191CE8; // type:func\nPaloGetActlaTarget = 0x191D00; // type:func\nUpdateActla = 0x191D38; // type:func\nGetActlaRotationGoal = 0x191DE8; // type:func\nmain = 0x192030; // type:func\nStartupSif = 0x192270; // type:func\nStartupVU0 = 0x1924B0; // type:func\nStartupVU1 = 0x192538; // type:func\nExecuteReset = 0x1925C0; // type:func\nStartupReset = 0x192648; // type:func\nClearReset = 0x1926F0; // type:func\niCheckReset = 0x1926F8; // type:func\nStartup = 0x192770; // type:func\nShutdown = 0x192908; // type:func\nPtriFindMap = 0x192B90; // type:func\nPvFromMapIpos = 0x192C08; // type:func\nPvecFromMapIpos = 0x192C20; // type:func\nReportXPs = 0x192C80; // type:func\nMuFromAmtlk = 0x192C90; // type:func\nElasFromAmtlk = 0x192D18; // type:func\nPxpAdd = 0x192D98; // type:func\nRecalcSwXpPos = 0x192FF8; // type:func\nRecalcSwXpMovement = 0x193168; // type:func\nFreeSwXpList = 0x1932C8; // type:func\nFindClosestPointOnLine = 0x193328; // type:func\nFindClosestPointOnLineSegment = 0x193420; // type:func\nClsgClipSoAllEdges = 0x193550; // type:func\nClsgClipSoBspEdges = 0x193670; // type:func\nCategorizeAlsg = 0x1938E0; // type:func\nCplsgFindEdgePath = 0x193B90; // type:func\nMarkSoContactsBspBsp = 0x193CC8; // type:func\nCsbiIntersectSphereBsp = 0x194250; // type:func\nMarkSoContactsSphereBsp = 0x1949E0; // type:func\nMarkSoContactsSphereSphere = 0x194AC0; // type:func\nCalculateCenterContact = 0x194BA0; // type:func\nFMarkSoContactsCenterBsp = 0x194C68; // type:func\nFClipEdgeToSphere = 0x194D60; // type:func\nFMarkSoContactsCenterSphere = 0x194EE0; // type:func\nAddSoXps = 0x194FB0; // type:func\nPxpMarkSwContactsRoot = 0x195330; // type:func\nMATRIX4__PostCopyMatrix3 = 0x1955A0; // type:func\nMATRIX4__operatorEQ = 0x1955C0; // type:func\nMatMulMatTransMat = 0x195608; // type:func\nLoadIdentityMatrix4 = 0x1956C8; // type:func\noperatorSTAR1 = 0x195718; // type:func\noperatorSTAR2 = 0x195758; // type:func\nMultiplyMatrix4Vector = 0x1957F0; // type:func\noperatorSTAR3 = 0x195830; // type:func\nTransposeMatrix4 = 0x195860; // type:func\nAddMatrix4Matrix4 = 0x195900; // type:func\nLoadRotateMatrixRad = 0x195938; // type:func\nLoadRotateMatrix = 0x195A68; // type:func\nLoadRotateMatrixEuler = 0x195B18; // type:func\nLoadMatrixFromPosRot = 0x195C10; // type:func\nLoadMatrixFromPosRotInverse = 0x195C50; // type:func\nLoadMatrixFromPosRotScale = 0x195D18; // type:func\nCosRotateMatrixMagnitude = 0x195DF0; // type:func\nDecomposeRotateMatrixRad = 0x195E40; // type:func\nDecomposeRotateMatrixEuler = 0x196200; // type:func\nNormalizeRotateMatrix3 = 0x1962F0; // type:func\nCalculateDmat = 0x1963A0; // type:func\nCalculateDmat4 = 0x196410; // type:func\nDecomposeRotateMatrixPanTilt = 0x196490; // type:func\nLoadRotateMatrixPanTilt = 0x196510; // type:func\nLoadLookAtMatrix = 0x1965D0; // type:func\nTiltMatUpright = 0x196600; // type:func\nLoadSquishStretchMatrix = 0x1966C0; // type:func\nFInvertMatrix = 0x196870; // type:func\nFInvertMatrix3 = 0x196C50; // type:func\nFInvertMatrix4 = 0x196F50; // type:func\nBuildOrthonormalMatrixY = 0x196F80; // type:func\nBuildOrthonormalMatrixZ = 0x197098; // type:func\nBuildRotateVectorsMatrix = 0x1971B0; // type:func\nBuildSimpleProjectionMatrix = 0x1973E0; // type:func\nLoadScaleMatrixScalar = 0x197498; // type:func\nLoadScaleMatrixVector = 0x1974D8; // type:func\nLoadRotateVectorMatrix = 0x197620; // type:func\nInitMecha = 0x197848; // type:func\nPostMechaLoad = 0x197898; // type:func\nPresetMechaAccel = 0x197948; // type:func\nUpdateMecha = 0x197C08; // type:func\nUpdateMechaActive = 0x197CC8; // type:func\nRenderMechaSelf = 0x198228; // type:func\nHandleMechaMessage = 0x198318; // type:func\nPsoGetMechaEffect = 0x198380; // type:func\nUpdateMechaEffect = 0x1983E0; // type:func\nAddMechaCustomXps = 0x198628; // type:func\nChooseStepAttackTarget = 0x198740; // type:func\nSetMechaMechas = 0x1989E0; // type:func\nInitMbg = 0x198C78; // type:func\nLoadMbgFromBrx = 0x198CB0; // type:func\nPostMbgLoad = 0x198D50; // type:func\nPsoHitTestCylinderObjects = 0x198DC0; // type:func\nFFilterMbgAttackObjects = 0x198F38; // type:func\nFObstructedMbg = 0x198FD0; // type:func\nFIgnoreMbgIntersection = 0x199088; // type:func\nFCanMbgAttack = 0x199118; // type:func\nFDetectMbg = 0x199260; // type:func\nOnMbgEnteringSgs = 0x1992D0; // type:func\nUpdateMbgGoal = 0x199370; // type:func\nUpdateMbgSgs = 0x1993E8; // type:func\nOnMbgExitingSgs = 0x199670; // type:func\nHandleMbgMessage = 0x1996B0; // type:func\nSetMbgMbsk = 0x199820; // type:func\nInitScentmap = 0x199840; // type:func\nLookupScentmap = 0x199878; // type:func\nPostScentmapLoad = 0x199928; // type:func\nPscpFindScentmap = 0x199B60; // type:func\nUpdateScentmap = 0x199D40; // type:func\nInitBhg = 0x199DC0; // type:func\nPostBhgLoad = 0x199E00; // type:func\nSgsNextBhgAI = 0x199E50; // type:func\nOnBhgEnteringSgs = 0x199E78; // type:func\nUpdateBhgSgs = 0x199EA0; // type:func\nStartupMemcard = 0x199EC8; // type:func\nStartupMemMgr = 0x199ED0; // type:func\nPvAllocGlobalImpl = 0x199F58; // type:func\nHardLockError = 0x199FA0; // type:func\nCheckForOutOfMemory = 0x19A148; // type:func\nPvAllocSwImpl = 0x19A1C0; // type:func\nFreeSw = 0x19A218; // type:func\nPvAllocSwCopyImpl = 0x19A230; // type:func\nPvAllocSwClearImpl = 0x19A298; // type:func\nInitStackImpl = 0x19A2F0; // type:func\nPvAllocStackImpl = 0x19A348; // type:func\nPvAllocStackClearImpl = 0x19A3A0; // type:func\nFreeStackImpl = 0x19A3F8; // type:func\nmalloc = 0x19A450; // type:func\n_malloc_r = 0x19A458; // type:func\nfree = 0x19A460; // type:func\n__builtin_new = 0x19A468; // type:func\n__builtin_delete = 0x19A490; // type:func\nCopyAqw = 0x19A498; // type:func\nCopyAb = 0x19A518; // type:func\nPushMenu = 0x19A610; // type:func\nPopMenu = 0x19A6B0; // type:func\nSetCurMenu = 0x19A830; // type:func\nToggleBool = 0x19AB00; // type:func\nDrawDebugmenu = 0x19AB20; // type:func\nSetMainMenu = 0x19B338; // type:func\nDismissDebugmenu = 0x19B418; // type:func\nUpdateDebugmenuActive = 0x19B460; // type:func\nOnDebugmenuActive = 0x19BEF0; // type:func\nOnDebugmenuReset = 0x19C0D0; // type:func\nShowBrxWorlds = 0x19C100; // type:func\nSetMusic = 0x19C260; // type:func\nSgnCompareMiName = 0x19C288; // type:func\nShowMusic = 0x19C2B0; // type:func\nShowWarpPositions = 0x19C3A8; // type:func\nTeleportPlayerGSwnd = 0x19C550; // type:func\nFAddClassObjectMenuItem = 0x19C600; // type:func\nPmiClassObjects = 0x19C6A0; // type:func\nRemoveClassObjects = 0x19C778; // type:func\nShowClassObjects = 0x19C818; // type:func\nNoParams = 0x19C950; // type:func\nShowParams = 0x19C958; // type:func\nRecalcMenu = 0x19CCF0; // type:func\nToggleRumbleEnabled = 0x19CD50; // type:func\nCkeyGetCkeyMaxGameworld = 0x19CD98; // type:func\nRefreshGwkmlText = 0x19CDE0; // type:func\nShowKeys = 0x19CE60; // type:func\nShowLevelKeys = 0x19CFF8; // type:func\nCollectWorldKeys = 0x19D0F0; // type:func\nToggleCollectKey = 0x19D218; // type:func\nEnsureCurrentKey = 0x19D2D8; // type:func\nVisitAllWorlds = 0x19D688; // type:func\nCSpliceVarAccessor__CSpliceVarAccessor = 0x19D6C0; // type:func\nCSpliceVarAccessor__~CSpliceVarAccessor = 0x19D750; // type:func\nCSpliceVarAccessor__Init = 0x19D7B8; // type:func\nCSpliceVarAccessor__Retrieve = 0x19D898; // type:func\nCSpliceVarAccessor__Draw = 0x19D968; // type:func\nCSpliceVarAccessor__Commit = 0x19DE18; // type:func\nCSpliceVarAccessor__Rollback = 0x19DF70; // type:func\nCSpliceVarAccessor__Reset = 0x19DF98; // type:func\nCSpliceVarAccessor__Adjust = 0x19E048; // type:func\nCSpliceVarAccessor__FHasChanged = 0x19E160; // type:func\nCSpliceVarAccessor__FLiveEditable = 0x19E290; // type:func\nCSpliceVarAccessor__PvVarOwner = 0x19E2A0; // type:func\nCSpliceVarAccessor__OnPopMenu = 0x19E2A8; // type:func\nCSpliceVarAccessor__GGetRef = 0x19E2D0; // type:func\nCSpliceVarAccessor__GGet = 0x19E340; // type:func\nCSpliceVarAccessor__SetGRef = 0x19E378; // type:func\nCSpliceVarAccessor__SetG = 0x19E510; // type:func\nCSpliceVarAccessor__GConstrain = 0x19E550; // type:func\n__static_initialization_and_destruction_09 = 0x19E6B0; // type:func\nCSpliceVarAccessor__IComponent = 0x19E7A0; // type:func\n_GLOBAL_$I$PushMenu__FP4BLOTP2MIiiiPcii = 0x19E7A8; // type:func\n_GLOBAL_$D$PushMenu__FP4BLOTP2MIiiiPcii = 0x19E7D0; // type:func\nInitMissile = 0x19E7F8; // type:func\nLoadMissileFromBrx = 0x19E830; // type:func\nOnMissileRemove = 0x19E890; // type:func\nProjectMissileTransform = 0x19E8D8; // type:func\nFireMissile = 0x19E970; // type:func\nRenderMissileAll = 0x19EA60; // type:func\nInitAccmiss = 0x19EBF0; // type:func\nFireAccmiss = 0x19EC30; // type:func\nPresetAccmissAccel = 0x19ECD0; // type:func\nInitTarmiss = 0x19ED60; // type:func\nUpdateTarmiss = 0x19EDC0; // type:func\nFireSplmiss = 0x19F018; // type:func\nProjectSplmissTransform = 0x19F190; // type:func\nInitGroundmiss = 0x19F5A8; // type:func\nPresetGroundmissAccel = 0x19F5E8; // type:func\nInitMgv = 0x19F778; // type:func\nLoadMgvFromBrx = 0x19F7B8; // type:func\nOidTmblGoal = 0x19F800; // type:func\nPostMgvLoad = 0x19F850; // type:func\nUpdateMgvActive = 0x19F978; // type:func\nHandleMgvMessage = 0x19FA20; // type:func\nDamageMgv = 0x19FAA8; // type:func\nScoreMgv = 0x19FB58; // type:func\nInitMgc = 0x19FC08; // type:func\nLoadMgcFromBrx = 0x19FC60; // type:func\nPostMgcLoad = 0x19FCA8; // type:func\nUpdateMgc = 0x19FD78; // type:func\nGenerateMgc = 0x19FFA0; // type:func\nHandleMgcMessage = 0x1A0088; // type:func\nClearMgc = 0x1A0100; // type:func\nCQueueOutputIop__Init = 0x1A0210; // type:func\nCQueueOutputIop__Reset = 0x1A0240; // type:func\nCQueueOutputIop__CbWrite = 0x1A0260; // type:func\nCQueueOutputIop__CbSend = 0x1A0368; // type:func\nCQueueOutputIop__Update = 0x1A03F8; // type:func\nCQueueOutputIop__FAsyncDrain = 0x1A0488; // type:func\nCQueueOutputIpu__CbWrite = 0x1A0490; // type:func\nCQueueOutputIpu__FAsyncDrain = 0x1A0500; // type:func\nCMpegAudio__Init = 0x1A0508; // type:func\nCMpegAudio__Reset = 0x1A0668; // type:func\nCMpegAudio__Close = 0x1A06D8; // type:func\nCMpegAudio__FAccept = 0x1A0748; // type:func\nCMpegAudio__Update = 0x1A07F8; // type:func\nFMpegAcceptVideo = 0x1A08B8; // type:func\nFMpegAcceptAudio = 0x1A0900; // type:func\nFMpegDecodeVideo = 0x1A0930; // type:func\nFMpegDecoderIdle = 0x1A0A50; // type:func\nFMpegDecoderError = 0x1A0AD0; // type:func\nBuildMpegGifs = 0x1A0AD8; // type:func\nCMpeg__Set = 0x1A0D88; // type:func\nCMpeg__Execute = 0x1A0DA0; // type:func\nCMpeg__Start = 0x1A1020; // type:func\nCMpeg__Update = 0x1A11A0; // type:func\nCMpeg__Finish = 0x1A15A8; // type:func\nCMpeg__CbDemuxed = 0x1A16D8; // type:func\nPlayMovie = 0x1A17C0; // type:func\n__static_initialization_and_destruction_010 = 0x1A17F0; // type:func\n_GLOBAL_$I$g_mpeg = 0x1A1818; // type:func\nInitMrkv = 0x1A1840; // type:func\nRenderMsGlobset = 0x1A18A0; // type:func\nInitMurray = 0x1A1E08; // type:func\nPostMurrayLoad = 0x1A1E40; // type:func\nOnMurrayEnteringSgs = 0x1A1EA8; // type:func\nOnMurrayExitingSgs = 0x1A1EE0; // type:func\nUpdateMurrayGoal = 0x1A1F38; // type:func\nUpdateMurraySgs = 0x1A20A8; // type:func\nFAbsorbMurrayWkr = 0x1A2230; // type:func\nFDetectMurray = 0x1A22B0; // type:func\nFCanMurrayAttack = 0x1A2388; // type:func\nAddMurrayEnemy = 0x1A2390; // type:func\nSetMurrayPursueXfm = 0x1A23C0; // type:func\nSetMurrayPatrolXfm = 0x1A23C8; // type:func\nCollectMurrayPrize = 0x1A23D0; // type:func\nPcbspExtract = 0x1A2418; // type:func\nPcgtExtract = 0x1A2428; // type:func\nPcgtPointInCbspQuick = 0x1A2448; // type:func\nPcgtPointInCbspSafe = 0x1A2510; // type:func\nCbskFromG = 0x1A2648; // type:func\nClsgClipEdgeToCbsp = 0x1A2690; // type:func\nFClipEdgeToCbsp = 0x1A2B08; // type:func\nIcgvFromPcgv = 0x1A2B88; // type:func\nFindPathAStar = 0x1A2B98; // type:func\nSimplifyApcgvNeighbor = 0x1A2E30; // type:func\nCposFindPath = 0x1A2FD8; // type:func\nFindClosestPointInCg = 0x1A3308; // type:func\nLoadPathzoneFromBrx = 0x1A3478; // type:func\nHookupCg = 0x1A3830; // type:func\nCposFindPathzonePath = 0x1A3958; // type:func\nFindPathzoneClosestPoint = 0x1A3980; // type:func\nChoosePathzoneRandomPoint = 0x1A39B8; // type:func\nOnPathzoneAdd = 0x1A3BC8; // type:func\nOnPathzoneRemove = 0x1A3C10; // type:func\nClonePathzone = 0x1A3C58; // type:func\nRenderPathzone = 0x1A3CA8; // type:func\nSetPhase = 0x1A3DD8; // type:func\nClearPhase = 0x1A3E20; // type:func\nStartupPipe = 0x1A3E30; // type:func\nResetPipeList = 0x1A3E60; // type:func\nInitPipe = 0x1A3E88; // type:func\nOnPipeAdd = 0x1A3ED0; // type:func\nOnPipeRemove = 0x1A3F18; // type:func\nClonePipe = 0x1A3F60; // type:func\nSetPipeCameraOffset = 0x1A3FB0; // type:func\nLoadPntFromBrx = 0x1A3FC8; // type:func\nGetPntPos = 0x1A4020; // type:func\nSetPntParent = 0x1A4058; // type:func\nApplyPntProxy = 0x1A40B0; // type:func\nInitPo = 0x1A40E0; // type:func\nClonePo = 0x1A4130; // type:func\nHandlePoMessage = 0x1A4188; // type:func\nOnPoActive = 0x1A41E0; // type:func\nGetPoCpdefi = 0x1A4290; // type:func\nFIsPoSoundBase = 0x1A4330; // type:func\nMakePoActive = 0x1A4338; // type:func\nFInvulnerablePo = 0x1A4378; // type:func\nFTakePoDamage = 0x1A4380; // type:func\nJthsCurrentPo = 0x1A4388; // type:func\nCollectPoPrize = 0x1A4390; // type:func\nPpoCur = 0x1A4398; // type:func\nPpoStart = 0x1A43C8; // type:func\n_IppoFindPo = 0x1A4420; // type:func\nAddPoToList = 0x1A4468; // type:func\nRemovePoFromList = 0x1A4528; // type:func\nOnPoAdd = 0x1A45E0; // type:func\nOnPoRemove = 0x1A4620; // type:func\nSwitchToIppo = 0x1A4660; // type:func\nSetPoPlayable = 0x1A4770; // type:func\nSwitchToPo = 0x1A47C0; // type:func\nPpziCur = 0x1A47F8; // type:func\nGetPoDiapi = 0x1A4830; // type:func\nPlayPoDialog = 0x1A4840; // type:func\nUpdatePo = 0x1A4880; // type:func\nUsePoCharm = 0x1A4968; // type:func\n__static_initialization_and_destruction_011 = 0x1A4AF8; // type:func\n_GLOBAL_$I$InitPo__FP2PO = 0x1A4BE8; // type:func\nCProg__CProg = 0x1A4C10; // type:func\nCProg__Begin = 0x1A4C70; // type:func\nCProg__SetRemain = 0x1A4C88; // type:func\nCProg__End = 0x1A4D20; // type:func\nCProg__Draw = 0x1A4D38; // type:func\nAchzFromRespk = 0x1A5028; // type:func\nPostPromptLoad = 0x1A5040; // type:func\nOnPromptActive = 0x1A50C0; // type:func\nUpdatePromptActive = 0x1A5330; // type:func\nSetPrompt = 0x1A5530; // type:func\nSetPromptBlots = 0x1A5650; // type:func\nDrawPrompt = 0x1A56A8; // type:func\nSetPromptPrk = 0x1A5FC0; // type:func\nExecutePrompt = 0x1A62A8; // type:func\nCancelPrompt = 0x1A65A8; // type:func\n__static_initialization_and_destruction_012 = 0x1A66A0; // type:func\n_GLOBAL_$I$AchzFromRespk__F5RESPK = 0x1A6730; // type:func\nInitProxy = 0x1A6758; // type:func\nLoadProxyFromBrx = 0x1A67A0; // type:func\nCloneProxy = 0x1A6C48; // type:func\nPostProxyLoad = 0x1A6D68; // type:func\nInitPuffer = 0x1A6DA8; // type:func\nLoadPufferFromBrx = 0x1A6E18; // type:func\nPostPufferLoad = 0x1A6E60; // type:func\nPresetPufferAccel = 0x1A6FC0; // type:func\nFFilterPuffer = 0x1A72E0; // type:func\nUpdatePuffer = 0x1A7350; // type:func\nPpufftChoosePuffer = 0x1A76A8; // type:func\nOnPufferActive = 0x1A7910; // type:func\nUpdatePufferActive = 0x1A79E8; // type:func\nAdjustPufferNewXp = 0x1A7DE8; // type:func\nAddPufferWaterAcceleration = 0x1A7E08; // type:func\nHandlePufferMessage = 0x1A8258; // type:func\nPostPuffcLoad = 0x1A82C0; // type:func\nPresetPuffcAccel = 0x1A8300; // type:func\nFDetectPuffc = 0x1A8528; // type:func\nUpdatePuffcGoal = 0x1A8530; // type:func\nOnPuffcExitingSgs = 0x1A85E8; // type:func\nOnPuffcEnteringSgs = 0x1A8668; // type:func\nUpdatePuffcSgs = 0x1A8748; // type:func\nHandlePuffcMessage = 0x1A8828; // type:func\nUpdatePuffc = 0x1A88A8; // type:func\nFCanPuffcAttack = 0x1A8980; // type:func\nPostPuffbLoad = 0x1A89F8; // type:func\nUpdatePuffb = 0x1A8B88; // type:func\nPpuffvChoosePuffb = 0x1A8DD8; // type:func\nLandPuffb = 0x1A8F70; // type:func\nJumpPuffb = 0x1A8FB8; // type:func\nDiePuffb = 0x1A9000; // type:func\nIppathzoneFindPuffb = 0x1A9050; // type:func\nPostPufftLoad = 0x1A9090; // type:func\nInitPuffv = 0x1A9108; // type:func\nAddPuffvOidLand = 0x1A9140; // type:func\nPostPuffvLoad = 0x1A9168; // type:func\nInitSprize = 0x1A9250; // type:func\nLoadSprizeFromBrx = 0x1A9288; // type:func\nBindSprize = 0x1A9380; // type:func\nPostSprizeLoad = 0x1A9430; // type:func\nUpdateSprize = 0x1A9508; // type:func\nCollectSprize = 0x1A96D0; // type:func\nEmitSprizeExplosion = 0x1A9798; // type:func\nPcsFromSprize = 0x1A97D8; // type:func\nAddSprizeAseg = 0x1A9820; // type:func\nHandleSprizeMessage = 0x1A9840; // type:func\nFIgnoreSprizeIntersection = 0x1A9900; // type:func\nInitScprize = 0x1A9960; // type:func\nCloneScprize = 0x1A99A8; // type:func\nPcsFromScprize = 0x1A99E8; // type:func\nCollectScprize = 0x1A9A50; // type:func\nCollectLifetkn = 0x1A9A98; // type:func\nLoadLockFromBrx = 0x1A9B40; // type:func\nPostLockLoad = 0x1A9B88; // type:func\nLoadLockgFromBrx = 0x1A9BD0; // type:func\nPostLockgLoad = 0x1A9C18; // type:func\nSetLockgIndex = 0x1A9DC8; // type:func\nAddLockgLock = 0x1A9DE0; // type:func\nTriggerLockg = 0x1A9E08; // type:func\nInitClue = 0x1A9F58; // type:func\nLoadClueFromBrx = 0x1A9F98; // type:func\nCloneClue = 0x1AA070; // type:func\nPostClueLoad = 0x1AA0B0; // type:func\nOnClueSmack = 0x1AA1D0; // type:func\nCollectClue = 0x1AA330; // type:func\nBreakClue = 0x1AA408; // type:func\nCollectClueSilent = 0x1AA430; // type:func\nImpactClue = 0x1AA540; // type:func\nFAbsorbClueWkr = 0x1AA568; // type:func\nRenderClueAll = 0x1AA608; // type:func\nCollectAllClues = 0x1AA830; // type:func\nSetGrfvault = 0x1AA8F0; // type:func\nOpenVaultCheat = 0x1AA900; // type:func\nToggleGrfvault = 0x1AA938; // type:func\nInitVault = 0x1AA950; // type:func\nPostTmblLoad = 0x1AA988; // type:func\nPostVaultLoad = 0x1AAA08; // type:func\nOnVaultActive = 0x1AAC28; // type:func\nUpdateVaultActive = 0x1AAD80; // type:func\nHandleVaultMessage = 0x1AB2F0; // type:func\nAddVaultGoadDialog = 0x1AB478; // type:func\nOpenVault = 0x1AB4B0; // type:func\nOnRailAdd = 0x1AB6E8; // type:func\nOnRailRemove = 0x1AB730; // type:func\nCloneRail = 0x1AB778; // type:func\nInitRat = 0x1AB7C8; // type:func\nLoadRatFromBrx = 0x1AB840; // type:func\nPostRatLoad = 0x1AB960; // type:func\nOnRatAdd = 0x1AB9D0; // type:func\nOnRatRemove = 0x1ABA18; // type:func\nCloneRat = 0x1ABA60; // type:func\nPresetRatAccel = 0x1ABAB0; // type:func\nUpdateRat = 0x1ABBB8; // type:func\nAdjustRatNewXp = 0x1AC3D8; // type:func\nAdjustRatXpVelocity = 0x1AC458; // type:func\nRenderRatAll = 0x1AC508; // type:func\nFAbsorbRatWkr = 0x1AC6D8; // type:func\nChooseRatFleeTarget = 0x1AC758; // type:func\nHideRat = 0x1AC978; // type:func\nSetRatRats = 0x1ACB08; // type:func\nGetRatParams = 0x1ACD68; // type:func\nOnRatholeAdd = 0x1ACDD0; // type:func\nOnRatholeRemove = 0x1ACE18; // type:func\nInitRchm = 0x1ACE60; // type:func\nLoadRchmFromBrx = 0x1ACE98; // type:func\nPostRchmLoad = 0x1AD1B8; // type:func\nReblendRchm = 0x1AD4D8; // type:func\nBuildRchmCoefficients = 0x1AD728; // type:func\nConvertRchmIposToRclIoLhub = 0x1AD8A8; // type:func\nIposConvertRchmRclIoLhub = 0x1AD940; // type:func\nSetRchmNaturalCoefficients = 0x1AD970; // type:func\nSetRchmCenterCoefficients = 0x1AD980; // type:func\nRenderRchmGrid = 0x1AD998; // type:func\nPredictRchmTargetPos = 0x1ADE60; // type:func\nPredictRchmTargetLocalPos = 0x1ADED8; // type:func\nPtwrMapRchmSafe = 0x1ADF90; // type:func\nFindRchmClosestPoint = 0x1AE118; // type:func\nFChooseJtReachTarget = 0x1AE300; // type:func\nTrackJtTarget = 0x1AE768; // type:func\nTrackJtPipe = 0x1AE810; // type:func\nSubmitRpl = 0x1AE908; // type:func\nNCmpPrplReverseZ = 0x1AE978; // type:func\nCprplPartitionArpl = 0x1AE9C8; // type:func\nRenderSw = 0x1AEBE0; // type:func\nEnsureRenderGlobals = 0x1AEE80; // type:func\nEnsureCameraGlobals = 0x1AEF78; // type:func\nEnsureScreenCleared = 0x1AEFB8; // type:func\nSetupRpDynamicTexture = 0x1AF0B8; // type:func\nSetupRpBackground = 0x1AF0F0; // type:func\nSetupRpBlotContext = 0x1AF198; // type:func\nSetupRpGlob = 0x1AF1F8; // type:func\nSetupRpBlip = 0x1AF260; // type:func\nSetupRpWorldMap = 0x1AF2C8; // type:func\nDrawSw = 0x1AF358; // type:func\nFillScreenRect = 0x1AF498; // type:func\nStartupRender = 0x1AF668; // type:func\nPripgNew = 0x1AF898; // type:func\nInitRipg = 0x1AF910; // type:func\nSetRipgEmitb = 0x1AF9B8; // type:func\nOnRipgRemove = 0x1AF9C8; // type:func\nProjectRipgTransform = 0x1AFA98; // type:func\nUpdateRipgBounds = 0x1AFC90; // type:func\nUpdateRipg = 0x1AFC98; // type:func\nBounceRipgRips = 0x1AFE08; // type:func\nRenderRipgSelf = 0x1B0128; // type:func\nPvtripFromRipt = 0x1B01E8; // type:func\nPripNewRipg = 0x1B0358; // type:func\nInitRip = 0x1B0438; // type:func\nRemoveRip = 0x1B04F8; // type:func\nAddRipRef = 0x1B0540; // type:func\nReleaseRip = 0x1B0550; // type:func\nTouchRip = 0x1B0618; // type:func\nForceRipFade = 0x1B0640; // type:func\nFBounceRip = 0x1B0698; // type:func\nProjectRipTransform = 0x1B0D08; // type:func\nUpdateRip = 0x1B0EF8; // type:func\nFRenderRipPosMat = 0x1B0FD0; // type:func\nRenderRip = 0x1B1230; // type:func\nSubscribeRipObject = 0x1B12D8; // type:func\nSubscribeRipStruct = 0x1B1310; // type:func\nUnsubscribeRipStruct = 0x1B1350; // type:func\nInitDroplet = 0x1B1390; // type:func\nTouchDroplet = 0x1B13E0; // type:func\nInitBublet = 0x1B14C0; // type:func\nProjectBubletTransform = 0x1B1538; // type:func\nTouchBublet = 0x1B1748; // type:func\nInitRipple = 0x1B1770; // type:func\nInitPuff = 0x1B17E0; // type:func\nInitDablet = 0x1B1838; // type:func\nInitFlake = 0x1B1890; // type:func\nUpdateFlake = 0x1B18D8; // type:func\nRenderFlake = 0x1B19B8; // type:func\nTouchFlake = 0x1B1AC8; // type:func\nInitSpark = 0x1B1AF0; // type:func\nRenderSpark = 0x1B1B58; // type:func\nInitBurst = 0x1B1C80; // type:func\nInitTrail = 0x1B1D48; // type:func\nOnTrailRemove = 0x1B1E30; // type:func\nSetTrailTrls = 0x1B1E58; // type:func\nDetachTrail = 0x1B1FD0; // type:func\nProjectTrailTransform = 0x1B2128; // type:func\nRenderTrail = 0x1B22B0; // type:func\nHandleTrailMessage = 0x1B24C8; // type:func\nInitFireball = 0x1B2548; // type:func\nUpdateFireball = 0x1B2620; // type:func\nInitSmokecloud = 0x1B26D8; // type:func\nInitSmoketrail = 0x1B2760; // type:func\nInitDebris = 0x1B2838; // type:func\nInitSmack = 0x1B2888; // type:func\nProjectSmackTransform = 0x1B2970; // type:func\nRenderSmack = 0x1B2A10; // type:func\nUpdateSmack = 0x1B2BD0; // type:func\nInitOrbit = 0x1B2C30; // type:func\nProjectOrbitTransform = 0x1B2C80; // type:func\nUpdateOrbit = 0x1B2E10; // type:func\nRenderOrbit = 0x1B2FF8; // type:func\nInitRay = 0x1B3078; // type:func\nInitRose = 0x1B30C8; // type:func\nProjectRoseTransform = 0x1B3110; // type:func\nUpdateRose = 0x1B3118; // type:func\nRenderRose = 0x1B3260; // type:func\nSetRoseRoses = 0x1B3AA0; // type:func\nSgnCmpHp = 0x1B3BC8; // type:func\nChpBuildConvexHullScreen = 0x1B3BF0; // type:func\nChpBuildConvexHullXY = 0x1B3D48; // type:func\nPostFlyingEmit = 0x1B3FC8; // type:func\nRenderFlying = 0x1B3FD8; // type:func\nCreateStuck = 0x1B4040; // type:func\nFBounceFlying = 0x1B42E0; // type:func\nUpdateStuck = 0x1B43D0; // type:func\nRenderStuck = 0x1B4430; // type:func\nPostLeafEmit = 0x1B44C0; // type:func\nProjectLeafTransform = 0x1B4598; // type:func\nFBounceLeaf = 0x1B47F8; // type:func\nFFilterFlameObjects = 0x1B48D0; // type:func\nPostFlameEmit = 0x1B4900; // type:func\nPostBulletEmit = 0x1B4B30; // type:func\nRenderBullet = 0x1B4B90; // type:func\nFBounceBullet = 0x1B4C88; // type:func\nPostShrapnelEmit = 0x1B4E50; // type:func\nFBounceShrapnel = 0x1B4F88; // type:func\nRenderShrapnel = 0x1B5010; // type:func\nInitGlint = 0x1B5068; // type:func\nRenderGlint = 0x1B50D0; // type:func\nInitMatch = 0x1B5440; // type:func\nLaunchMatch = 0x1B54A0; // type:func\nProjectMatchTransform = 0x1B55F8; // type:func\nUpdateMatch = 0x1B57D0; // type:func\nRenderMatch = 0x1B5880; // type:func\nPostRemitEmit = 0x1B58C0; // type:func\nUpdateRemit = 0x1B5918; // type:func\nInitRov = 0x1B59E8; // type:func\nLoadRovFromBrx = 0x1B5A30; // type:func\nPostRovLoad = 0x1B5A78; // type:func\nUpdateRovActive = 0x1B5BA0; // type:func\nUpdateRov = 0x1B5CD8; // type:func\nReadRovJoystick = 0x1B5F30; // type:func\nRovsNextRov = 0x1B5FE0; // type:func\nSetRovRovs = 0x1B6070; // type:func\nRovtsNextRov = 0x1B62A0; // type:func\nSetRovRovts = 0x1B6310; // type:func\nHandleRovMessage = 0x1B6428; // type:func\nPresetRovAccel = 0x1B6568; // type:func\nAdjustRovXpVelocity = 0x1B65D0; // type:func\nAdjustRovNewXp = 0x1B6658; // type:func\nPropagateRovForce = 0x1B66B8; // type:func\nFIsRovSoundBase = 0x1B67D0; // type:func\nGetRovParams = 0x1B67D8; // type:func\nInitRob = 0x1B6840; // type:func\nSetRobCollectible = 0x1B69A0; // type:func\nSetRobHarvester = 0x1B69A8; // type:func\nSetRobVehicle = 0x1B69B0; // type:func\nSetRobPrize = 0x1B69B8; // type:func\nAddRobSpawnTunnel = 0x1B69C0; // type:func\nRobkCur = 0x1B69E0; // type:func\nBindRob = 0x1B6A08; // type:func\nPostRobLoad = 0x1B6CC8; // type:func\nUpdateRob = 0x1B6E00; // type:func\nRobsNextRob = 0x1B6F38; // type:func\nSetRobRobs = 0x1B7080; // type:func\nAddRobRoc = 0x1B7320; // type:func\nAddRobRoh = 0x1B7760; // type:func\nAdjustRobDifficulty = 0x1B7A10; // type:func\nDestroyedRobRoc = 0x1B7DE8; // type:func\nSpawnedRobRoh = 0x1B7F30; // type:func\nGrabbedRobRoh = 0x1B7FA0; // type:func\nDroppedRobRoh = 0x1B8070; // type:func\nReturnedRobRoh = 0x1B8100; // type:func\nExitedRobRoh = 0x1B8128; // type:func\nKilledRobRoh = 0x1B82E8; // type:func\nFChooseRobRoc = 0x1B8440; // type:func\nTakeRobRoc = 0x1B8530; // type:func\nFChooseRobRoh = 0x1B8638; // type:func\nFChooseRobReturnPoint = 0x1B8740; // type:func\nChooseRobWanderLocation = 0x1B8828; // type:func\nProddCurRob = 0x1B88C8; // type:func\nGetRobParams = 0x1B88E0; // type:func\nInitRoh = 0x1B8948; // type:func\nLoadRohFromBrx = 0x1B89B8; // type:func\nCloneRoh = 0x1B8A18; // type:func\nPostRohLoad = 0x1B8A68; // type:func\nUpdateRoh = 0x1B8AB8; // type:func\nMoveRohToTarget = 0x1B8CB8; // type:func\nRohsNextRoh = 0x1B8F58; // type:func\nSetRohRohs = 0x1B9178; // type:func\nFAbsorbRohWkr = 0x1B93A0; // type:func\nProcContactRoh = 0x1B94E0; // type:func\nGetRohParams = 0x1B9550; // type:func\nInitRoc = 0x1B95B8; // type:func\nLoadRocFromBrx = 0x1B9648; // type:func\nCloneRoc = 0x1B96A8; // type:func\nPostRocLoad = 0x1B96F8; // type:func\nUpdateRoc = 0x1B97A8; // type:func\nPresetRocAccel = 0x1B98E0; // type:func\nAdjustRocNewXp = 0x1B9958; // type:func\nFAbsorbRocWkr = 0x1B9978; // type:func\nRocsNextRoc = 0x1B9B00; // type:func\nSetRocRocs = 0x1B9B60; // type:func\nGetRocParams = 0x1B9C18; // type:func\nInitRost = 0x1B9C80; // type:func\nLoadRostFromBrx = 0x1B9CB8; // type:func\nCloneRost = 0x1B9D00; // type:func\nPostRostLoad = 0x1B9D50; // type:func\nUpdateRost = 0x1B9DF0; // type:func\nRostsNextRost = 0x1B9E58; // type:func\nSetRostRosts = 0x1B9E60; // type:func\nGetRostParams = 0x1B9ED8; // type:func\nInitRop = 0x1B9F38; // type:func\nLoadRopFromBrx = 0x1B9F90; // type:func\nPostRopLoad = 0x1B9FF0; // type:func\nUpdateRop = 0x1BA070; // type:func\nSetRopRops = 0x1BA230; // type:func\nRopsNextRop = 0x1BA348; // type:func\nInitRope = 0x1BA3C8; // type:func\nPostRopeLoad = 0x1BA420; // type:func\nSMinimizeRope = 0x1BA4F0; // type:func\nDrawRope = 0x1BA570; // type:func\nRenderRopeAll = 0x1BABB8; // type:func\nInitRumble = 0x1BAC80; // type:func\nUpdateRumble = 0x1BACF8; // type:func\nTriggerRumbleRumk = 0x1BAE78; // type:func\nTriggerRumbleRumpat = 0x1BAEB0; // type:func\nSetRumbleRums = 0x1BAF18; // type:func\nStopRumbleActuators = 0x1BAFD0; // type:func\nInitRwm = 0x1BB008; // type:func\nAddRwmRwc = 0x1BB120; // type:func\nInitRwmCallback = 0x1BB150; // type:func\nPostRwmLoad = 0x1BB318; // type:func\nPrwcFindRwm = 0x1BB498; // type:func\nEnableRwmRwc = 0x1BB500; // type:func\nDisableRwmRwc = 0x1BB538; // type:func\nResizeRwmRwc = 0x1BB568; // type:func\nFIsRwmAmmo = 0x1BB5B0; // type:func\nFAvailableRwmAmmo = 0x1BB630; // type:func\nCycleRwmCache = 0x1BB6C8; // type:func\nReloadRwm = 0x1BB7F0; // type:func\nFEnsureRwmLoaded = 0x1BB910; // type:func\nFFireRwm = 0x1BB958; // type:func\nClearRwmFireInfo = 0x1BC1B8; // type:func\nClearRwmTargetInfo = 0x1BC210; // type:func\nClearRwmAimConstraints = 0x1BC278; // type:func\nGetRwfiPosMat = 0x1BC2A8; // type:func\nGetRwtiPos = 0x1BC390; // type:func\nGetRwacPan = 0x1BC518; // type:func\nGetRwacTilt = 0x1BC5A0; // type:func\nStartupSampler = 0x1BC620; // type:func\nCSampler__Startup = 0x1BC648; // type:func\nCSampler__Update = 0x1BC710; // type:func\nCSampler__OnMovieFinished = 0x1BC848; // type:func\nCSampler__Shutdown = 0x1BC8A0; // type:func\nSolveAloSpline = 0x1BC978; // type:func\nStartupScreen = 0x1BD378; // type:func\nPostBlotsLoad = 0x1BD610; // type:func\nUpdateBlots = 0x1BD688; // type:func\nForceHideBlots = 0x1BD720; // type:func\nDrawBrightnessBar = 0x1BD780; // type:func\nDrawPlayerSuck = 0x1BD898; // type:func\nResetBlots = 0x1BDB60; // type:func\nRenderBlots = 0x1BDBB0; // type:func\nDrawBlots = 0x1BDC18; // type:func\nInitBlot = 0x1BDCC0; // type:func\nPostBlotLoad = 0x1BDD40; // type:func\nUpdateBlot = 0x1BDD70; // type:func\nSetBlotAchzDraw = 0x1BDFD0; // type:func\nSetBlotFontScale = 0x1BE0B8; // type:func\nDrawBlot = 0x1BE0C0; // type:func\nDrawBlotRect = 0x1BE200; // type:func\nDtAppearBlot = 0x1BE2C8; // type:func\nDtVisibleBlot = 0x1BE2D0; // type:func\nDtDisappearBlot = 0x1BE2D8; // type:func\nSetBlotDtAppear = 0x1BE2E0; // type:func\nSetBlotDtVisible = 0x1BE2E8; // type:func\nSetBlotDtDisappear = 0x1BE2F0; // type:func\nOnBlotReset = 0x1BE2F8; // type:func\nShowBlot = 0x1BE320; // type:func\nHideBlot = 0x1BE388; // type:func\nSetBlotBlots = 0x1BE3C8; // type:func\nFIncludeBlotForPeg = 0x1BE500; // type:func\nResizeBlot = 0x1BE558; // type:func\nRepositionBlot = 0x1BE5A0; // type:func\nRepositionBlotDependents = 0x1BE910; // type:func\nSetBlotClock = 0x1BE9C0; // type:func\nPostCtrLoad = 0x1BE9F0; // type:func\nUpdateCtr = 0x1BEAE8; // type:func\nDrawCtr = 0x1BEC58; // type:func\nRebuildCtrAchzDraw = 0x1BEFE8; // type:func\nDtVisibleCtr = 0x1BF240; // type:func\nPostTimerLoad = 0x1BF268; // type:func\nUpdateTimer = 0x1BF2D8; // type:func\nDrawTimer = 0x1BF398; // type:func\nSetTimer = 0x1BF560; // type:func\nSetTimerSpeed = 0x1BF600; // type:func\nSetTimerThreshold = 0x1BF608; // type:func\nSetTimerExpire = 0x1BF618; // type:func\nStartTimer = 0x1BF628; // type:func\nStopTimer = 0x1BF650; // type:func\nRebuildTimerAchzDraw = 0x1BF680; // type:func\nSetTimerTimers = 0x1BFB80; // type:func\nDtVisibleTrunkctr = 0x1BFBA0; // type:func\nDtVisibleCrusherctr = 0x1BFBB0; // type:func\nDtVisiblePuffchargectr = 0x1BFBC0; // type:func\nPostBossctrLoad = 0x1BFBD0; // type:func\nDrawBossctr = 0x1BFC88; // type:func\nPostNoteLoad = 0x1C0068; // type:func\nSetNoteAchzDraw = 0x1C00D8; // type:func\nDrawNote = 0x1C01D0; // type:func\nPostTitleLoad = 0x1C03A0; // type:func\nSetTitleAchzDraw = 0x1C0420; // type:func\nSetTitleBlots = 0x1C0488; // type:func\nFIncludeTitleForPeg = 0x1C04E8; // type:func\nDrawTitle = 0x1C0540; // type:func\nPostTotalsLoad = 0x1C0870; // type:func\nFormatTotalsGrfls = 0x1C0928; // type:func\nSetTotalsGrfls = 0x1C0A28; // type:func\nSetTotalsBlots = 0x1C0A90; // type:func\nDrawTotals = 0x1C0AF0; // type:func\nPostCallLoad = 0x1C0BE8; // type:func\nDrawCall = 0x1C0C58; // type:func\nToggleLetterbox = 0x1C0E40; // type:func\nDrawLetterbox = 0x1C0E88; // type:func\nPostScoresLoad = 0x1C1010; // type:func\nUpdateScores = 0x1C1060; // type:func\nDrawScores = 0x1C1140; // type:func\nPostLogoLoad = 0x1C1280; // type:func\nDrawLogo = 0x1C1358; // type:func\nPostAttractLoad = 0x1C1598; // type:func\nSetAttractAchzDraw = 0x1C1648; // type:func\nSetAttractBlots = 0x1C1708; // type:func\nUpdateAttract = 0x1C17B0; // type:func\nDrawAttract = 0x1C1830; // type:func\nDrawLineScreen = 0x1C1998; // type:func\n__static_initialization_and_destruction_013 = 0x1C1B08; // type:func\n_GLOBAL_$I$g_lifectr = 0x1C1CF8; // type:func\nInitSensor = 0x1C1D20; // type:func\nGetSensorParams = 0x1C1D58; // type:func\nSetSensorAlarm = 0x1C1DC0; // type:func\nSetSensorSensors = 0x1C1DC8; // type:func\nFCheckSensorObject = 0x1C1E68; // type:func\nFIgnoreSensorObject = 0x1C1F58; // type:func\nFOnlySensorTriggerObject = 0x1C2028; // type:func\nPauseSensor = 0x1C2098; // type:func\nUpdateSensor = 0x1C20F8; // type:func\nAddSensorTriggerObject = 0x1C2160; // type:func\nAddSensorNoTriggerObject = 0x1C2188; // type:func\nAddSensorTriggerClass = 0x1C21B0; // type:func\nAddSensorNoTriggerClass = 0x1C21D8; // type:func\nInitLasen = 0x1C2200; // type:func\nLoadLasenFromBrx = 0x1C2238; // type:func\nBindLasen = 0x1C2280; // type:func\nPostLasenLoad = 0x1C2570; // type:func\nUpdateBusyLasenSenseTimes = 0x1C26E8; // type:func\nUpdateLasen = 0x1C27A8; // type:func\nFreezeLasen = 0x1C2998; // type:func\nRenderLasenSelf = 0x1C2A28; // type:func\nGetLasenParams = 0x1C2D40; // type:func\nFFilterLasen = 0x1C2DA8; // type:func\nSenseLasen = 0x1C2E20; // type:func\nEnableLasen = 0x1C33A8; // type:func\nDisableLasen = 0x1C33E0; // type:func\nOnLasenAlarmTriggered = 0x1C3420; // type:func\nSetLasenSensors = 0x1C3470; // type:func\nSCalcLasenShapeExtent = 0x1C3650; // type:func\nRetractLasen = 0x1C3760; // type:func\nExtendLasen = 0x1C3778; // type:func\nInitCamsen = 0x1C3790; // type:func\nPostCamsenLoad = 0x1C37C8; // type:func\nUpdateCamsen = 0x1C3888; // type:func\nRenderCamsenSelf = 0x1C3B60; // type:func\nFIgnoreCamsenIntersection = 0x1C3F28; // type:func\nGetCamsenParams = 0x1C3F30; // type:func\nFFilterCamsen = 0x1C3F98; // type:func\nSenseCamsen = 0x1C4030; // type:func\nEnableCamsen = 0x1C4310; // type:func\nDisableCamsen = 0x1C4348; // type:func\nOnCamsenAlarmTriggered = 0x1C43D8; // type:func\nSetCamsenSensors = 0x1C4428; // type:func\nSetCamsenCsdts = 0x1C44F0; // type:func\nInitPrsen = 0x1C45E0; // type:func\nPostPrsenLoad = 0x1C4630; // type:func\nUpdatePrsen = 0x1C46D0; // type:func\nGetPrsenParams = 0x1C48E0; // type:func\nSensePrsen = 0x1C4948; // type:func\nEnablePrsen = 0x1C4B00; // type:func\nDisablePrsen = 0x1C4B38; // type:func\nOnPrsenAlarmTriggered = 0x1C4BC8; // type:func\nSetPrsenSensors = 0x1C4C40; // type:func\nUpdatePrsenLoopShader = 0x1C4DE8; // type:func\nInitShadow = 0x1C5020; // type:func\nPostShadowLoad = 0x1C5090; // type:func\nInvalidateShadowVifs = 0x1C5170; // type:func\nRebuildShadowRegion = 0x1C5178; // type:func\nSetShadowShader = 0x1C5280; // type:func\nFShadowRadiusSet = 0x1C52D0; // type:func\nSetShadowNearRadius = 0x1C5308; // type:func\nSetShadowFarRadius = 0x1C5348; // type:func\nSetShadowCastPosition = 0x1C5388; // type:func\nSetShadowCastNormal = 0x1C5490; // type:func\nSetShadowNearCast = 0x1C5598; // type:func\nSetShadowFarCast = 0x1C55D8; // type:func\nSetShadowConeAngle = 0x1C5618; // type:func\nSetShadowFrustrumUp = 0x1C5680; // type:func\nFShadowValid = 0x1C56B0; // type:func\nFFilterFastShadows = 0x1C5738; // type:func\nUpdateShadow = 0x1C5760; // type:func\nRebuildShadowVifs = 0x1C59B0; // type:func\nDrawShadow = 0x1C5D08; // type:func\nFShadowIntersectsSphere = 0x1C5DC0; // type:func\nFindSwShadows = 0x1C5E58; // type:func\nInitShape = 0x1C5F10; // type:func\nRenderShape = 0x1C5F58; // type:func\nLoadShapeFromBrx = 0x1C6020; // type:func\nSetShapeParent = 0x1C60A0; // type:func\nTex0FromTexIframeCtk = 0x1C6198; // type:func\nPackTexGifs = 0x1C61F0; // type:func\nLoadClutFromBrx = 0x1C6380; // type:func\nLoadColorTablesFromBrx = 0x1C63E0; // type:func\nLoadBmpFromBrx = 0x1C6508; // type:func\nLoadBitmapsFromBrx = 0x1C6560; // type:func\nLoadFontsFromBrx = 0x1C6680; // type:func\nLoadTexFromBrx = 0x1C6808; // type:func\nLoadShadersFromBrx = 0x1C6978; // type:func\nUploadPermShaders = 0x1C6E10; // type:func\nPropagateShaders = 0x1C6E58; // type:func\nFillShaders = 0x1C6F10; // type:func\nUnloadShaders = 0x1C7D40; // type:func\nConvertRgbToHsv = 0x1C7E10; // type:func\nConvertHsvToRgb = 0x1C7FB8; // type:func\nConvertUserHsvToUserRgb = 0x1C8210; // type:func\nConvertUserRgbToUserHsv = 0x1C8298; // type:func\nPshdFindShader = 0x1C8328; // type:func\nSetSaiIframe = 0x1C8380; // type:func\nSetSaiDuDv = 0x1C83F0; // type:func\nPropagateSais = 0x1C8460; // type:func\nUpdateShaders = 0x1C8530; // type:func\nCbFromSaak = 0x1C85E8; // type:func\nPvtsaaFromSaak = 0x1C8648; // type:func\nPsaaLoadFromBrx = 0x1C86D8; // type:func\nInitSaa = 0x1C8790; // type:func\nPostSaaLoad = 0x1C87C0; // type:func\nFUpdatableSaa = 0x1C8800; // type:func\nUCompleteSaa = 0x1C8830; // type:func\nPsaiFromSaaShd = 0x1C8840; // type:func\nInitLoop = 0x1C8860; // type:func\nPostLoopLoad = 0x1C88C8; // type:func\nUpdateLoop = 0x1C8940; // type:func\nUCompleteLoop = 0x1C8A40; // type:func\nInitPingpong = 0x1C8A70; // type:func\nPostPingpongLoad = 0x1C8AD8; // type:func\nUpdatePingpong = 0x1C8B58; // type:func\nUCompletePingpong = 0x1C8C70; // type:func\nInitShuffle = 0x1C8CD8; // type:func\nUpdateShuffle = 0x1C8D20; // type:func\nInitHologram = 0x1C8DD8; // type:func\nPostHologramLoad = 0x1C8E90; // type:func\nNotifyHologramRender = 0x1C8EF0; // type:func\nInitScroller = 0x1C8FA8; // type:func\nUpdateScroller = 0x1C9028; // type:func\nUCompleteScroller = 0x1C90D0; // type:func\nSetScrollerMasterSpeeds = 0x1C9150; // type:func\nInitCircler = 0x1C9160; // type:func\nUpdateCircler = 0x1C91D0; // type:func\nUCompleteCircler = 0x1C9270; // type:func\nInitLooker = 0x1C92C0; // type:func\nSetLookerSgvr = 0x1C9360; // type:func\nSetVecPosad = 0x1C9380; // type:func\nSetUvPuvqd = 0x1C93A0; // type:func\nNotifyLookerRender = 0x1C93B8; // type:func\nPostSkyLoad = 0x1C9990; // type:func\nUpdateSky = 0x1C99D0; // type:func\nFUN_001c9a20 = 0x1C9A20; // type:func\n_InitSlotheap = 0x1C9A30; // type:func\nCreateSlotheapSw = 0x1C9A88; // type:func\nCreateSlotheapSwAlign64 = 0x1C9AF8; // type:func\nPvAllocSlotheapUnsafe = 0x1C9B78; // type:func\nPvAllocSlotheapImpl = 0x1C9BA0; // type:func\nPvAllocSlotheapClearImpl = 0x1C9BC8; // type:func\nFreeSlotheapPv = 0x1C9C20; // type:func\nLoadSmFromBrx = 0x1C9C50; // type:func\nPostSmLoad = 0x1C9F38; // type:func\nPostSmLoadCallback = 0x1C9F90; // type:func\nPsmaApplySm = 0x1CA038; // type:func\nPsmaFindSm = 0x1CA168; // type:func\nIsmsFindSmOptional = 0x1CA1A0; // type:func\nIsmsFindSmRequired = 0x1CA1D8; // type:func\nOidFromSmIsms = 0x1CA208; // type:func\nRetractSma = 0x1CA220; // type:func\nSetSmaGoal = 0x1CA2F0; // type:func\nGetSmaGoal = 0x1CA398; // type:func\nGetSmaCur = 0x1CA3C8; // type:func\nGetSmaNext = 0x1CA3F8; // type:func\nSetSmaSvt = 0x1CA428; // type:func\nSeekSma = 0x1CA458; // type:func\nChooseSmaTransition = 0x1CA4E8; // type:func\nEndSmaTransition = 0x1CAB28; // type:func\nHandleSmaMessage = 0x1CAB70; // type:func\nSkipSma = 0x1CABC8; // type:func\nSendSmaMessage = 0x1CAC78; // type:func\nNotifySmaSpliceOnEnterState = 0x1CACF8; // type:func\nInitSmartguard = 0x1CADA0; // type:func\nPostSmartguardLoadFlashlight = 0x1CAE30; // type:func\nUseSmartguardFlashlightTarget = 0x1CAF78; // type:func\nPostSmartguardLoad = 0x1CAFD0; // type:func\nFFilterSmartguardDetect = 0x1CB030; // type:func\nFDetectSmartguard = 0x1CB078; // type:func\nUpdateSmartguard = 0x1CB480; // type:func\nUpdateSmartguardFlashlight = 0x1CB4C0; // type:func\nOnSmartguardEnteringSgs = 0x1CB6E0; // type:func\nFCanSmartguardAttack = 0x1CB778; // type:func\nSgasGetSmartguard = 0x1CB858; // type:func\nHandleSmartguardMessage = 0x1CB8B8; // type:func\nFreezeSmartguard = 0x1CB920; // type:func\nInitSo = 0x1CB970; // type:func\nOnSoAdd = 0x1CBAF8; // type:func\nOnSoRemove = 0x1CBC18; // type:func\nEnableSoPhys = 0x1CBD10; // type:func\nGetSoParams = 0x1CBDE8; // type:func\nDisplaceSo = 0x1CBE50; // type:func\nImpactSo = 0x1CC0E0; // type:func\nPivotSo = 0x1CC2C0; // type:func\nExtendSoBounds = 0x1CC5B0; // type:func\nUpdateSoBounds = 0x1CC6D0; // type:func\nUpdateGeomWorld = 0x1CC9B0; // type:func\nUpdateSoXfWorldHierarchy = 0x1CCAF0; // type:func\nUpdateSoXfWorld = 0x1CCB60; // type:func\nFIgnoreSoIntersection = 0x1CCBC8; // type:func\nUpdateSoImpacts = 0x1CCC08; // type:func\nUProjectVector = 0x1CCD10; // type:func\nAdjustSoXpLocal = 0x1CCD70; // type:func\nCalculateSoAngularEffectWorld = 0x1CD1F0; // type:func\nAccelSoTowardPosSpring = 0x1CD260; // type:func\nAccelSoTowardMatSpring = 0x1CD3B8; // type:func\nPresetSoAccel = 0x1CD560; // type:func\nDrawGeom = 0x1CD618; // type:func\nRenderSoSelf = 0x1CD700; // type:func\nUpdateSo = 0x1CD780; // type:func\nSetSoMass = 0x1CD7A8; // type:func\nAdjustSoMomint = 0x1CD7E0; // type:func\nDiscardSoXps = 0x1CD8A0; // type:func\nUpdateSoPosWorldPrev = 0x1CD920; // type:func\nTranslateSoToPos = 0x1CD930; // type:func\nRotateSoToMat = 0x1CDA90; // type:func\nTranslateSoToPosSafe = 0x1CDB10; // type:func\nSetSoVelocityVec = 0x1CDC00; // type:func\nSetSoAngularVelocityVec = 0x1CDCC0; // type:func\nAddSoAcceleration = 0x1CDD90; // type:func\nAddSoAngularAcceleration = 0x1CDDA8; // type:func\nSetSoConstraints = 0x1CDDC0; // type:func\nSetSoParent = 0x1CDE38; // type:func\nApplySoProxy = 0x1CDF88; // type:func\nAccelSoTowardMatSmooth = 0x1CE028; // type:func\nGetSoCpdefi = 0x1CE280; // type:func\nFIsSoTouching = 0x1CE310; // type:func\nPsoFirstSoTouching = 0x1CE3E0; // type:func\nCloneSo = 0x1CE4C0; // type:func\nApplySoConstraintWorld = 0x1CE6B0; // type:func\nApplyConstr = 0x1CE7F8; // type:func\nApplySoConstraintLocal = 0x1CE8C8; // type:func\nAddSoXa = 0x1CE8F8; // type:func\nRemoveSoXa = 0x1CE928; // type:func\nAddSoWaterAcceleration = 0x1CE990; // type:func\nAddSoExternalAccelerations = 0x1CF098; // type:func\nLoadSoFromBrx = 0x1CF0A0; // type:func\nSetSoSphere = 0x1CF538; // type:func\nSetSoNoInteract = 0x1CF558; // type:func\nConstrFromCnstr = 0x1CF588; // type:func\nSetSoCnstrForce = 0x1CF5B8; // type:func\nSetSoCnstrTorque = 0x1CF638; // type:func\nSetSoCameraStyle = 0x1CF6B8; // type:func\nSetSoIgnoreLocked = 0x1CF6E8; // type:func\nSetSoIceable = 0x1CF720; // type:func\nSetSoMtlk = 0x1CF758; // type:func\nSetSoEdgeGrab = 0x1CF760; // type:func\nSendSoMessage = 0x1CF790; // type:func\nPxpFindSoGround = 0x1CF818; // type:func\nSetSoNoGravity = 0x1CF900; // type:func\nSetSoNoXpsAll = 0x1CF938; // type:func\nSetSoNoXpsSelf = 0x1CF968; // type:func\nSetSoNoXpsCenter = 0x1CF998; // type:func\nRebuildSoPhysHook = 0x1CF9C8; // type:func\nPsoFindSoPhysHook = 0x1CFA70; // type:func\nRecalcSoLocked = 0x1CFAB0; // type:func\nFGetSoContactList = 0x1CFC50; // type:func\nGetSoContacts = 0x1CFD60; // type:func\nFSoInStsoList = 0x1CFED0; // type:func\nGenerateSoSpliceTouchingEvents = 0x1CFF00; // type:func\nFInflictSoZap = 0x1D0190; // type:func\nEnsureSoLvo = 0x1D0198; // type:func\nProjectSoLvo = 0x1D0448; // type:func\nProjectSoTransform = 0x1D0618; // type:func\nApplySoImpulse = 0x1D0680; // type:func\nCalculateSoTrajectoryApex = 0x1D0828; // type:func\nFAbsorbSoWkr = 0x1D08F0; // type:func\nCloneSoPhys = 0x1D0940; // type:func\nRenumberSo = 0x1D0B00; // type:func\nCalculateSoEffect = 0x1D0B98; // type:func\nPropagateSoForce = 0x1D0BC8; // type:func\nDistributeSoEffects = 0x1D0D38; // type:func\nSolveSwGroup = 0x1D10D0; // type:func\nCpxpBuildXpArray = 0x1D19C8; // type:func\nBuildContactGroup = 0x1D1AE8; // type:func\nSplitSoFreeze = 0x1D1C00; // type:func\nSortSwGroup = 0x1D1CF8; // type:func\nSplitSwGroup = 0x1D1EF0; // type:func\nSolveSw = 0x1D21E0; // type:func\nSwapEntries = 0x1D2588; // type:func\nHeapSort = 0x1D25C8; // type:func\nUnloadMusic = 0x1D2718; // type:func\nSbpEnsureBank = 0x1D2760; // type:func\nSbpEnsureBank1 = 0x1D29D8; // type:func\nNewSfx = 0x1D2A10; // type:func\nFContinuousSound = 0x1D2AA8; // type:func\nSetVagUnpaused = 0x1D2B20; // type:func\nPreloadVag = 0x1D2B30; // type:func\nFPauseForVag = 0x1D2C28; // type:func\nFVagPlaying = 0x1D2C78; // type:func\nStopVag = 0x1D2CA0; // type:func\nPauseVag = 0x1D2D28; // type:func\nContinueVag = 0x1D2D58; // type:func\nKillMusic = 0x1D2D88; // type:func\nPreloadMusidSongComplete = 0x1D2DE0; // type:func\nPreloadMusidSong = 0x1D2E38; // type:func\nStartMusidSong = 0x1D2FA8; // type:func\nPauseMusic = 0x1D30B8; // type:func\nContinueMusic = 0x1D30E0; // type:func\nPexcAlloc = 0x1D3110; // type:func\nRemoveExc = 0x1D3188; // type:func\nKillExcitement = 0x1D31E8; // type:func\nPexcSetExcitement = 0x1D32B0; // type:func\nSetIexcCurHigh = 0x1D3358; // type:func\nFBlockHyst = 0x1D3420; // type:func\nUnsetExcitement = 0x1D3440; // type:func\nUnsetExcitementHyst = 0x1D3508; // type:func\nStartupSound = 0x1D3570; // type:func\nFAmbientsPaused = 0x1D36C0; // type:func\nCalculateVolPan = 0x1D36D0; // type:func\nSDistEarZoom = 0x1D37B0; // type:func\nSDistEarNormal = 0x1D3868; // type:func\nPposEar = 0x1D38A0; // type:func\nSetDoppler = 0x1D3900; // type:func\nPfneardistGet = 0x1D3A70; // type:func\nSDistEar = 0x1D3AE0; // type:func\nCalculateDistVolPan = 0x1D3B30; // type:func\nPambAlloc = 0x1D3BD8; // type:func\nDropPamb = 0x1D3C50; // type:func\nRemoveAmb = 0x1D3C60; // type:func\nStopSound = 0x1D3CD0; // type:func\nSetPambFrq = 0x1D3D58; // type:func\nRefreshPambVolPan = 0x1D3E40; // type:func\nSetPambVol = 0x1D3EA8; // type:func\nFillPamb = 0x1D3EE8; // type:func\nActivatePamb = 0x1D40C8; // type:func\nScheduleNextIntermittentSound = 0x1D41E0; // type:func\nStartSound = 0x1D42E8; // type:func\nSoundStoppedCB = 0x1D45F0; // type:func\nHandleWipeVolumes = 0x1D4628; // type:func\nUpdateSounds = 0x1D4698; // type:func\nSetMvgkRvol = 0x1D4CD8; // type:func\nSetMvgkUvol = 0x1D4D10; // type:func\nUvolGetMvgk = 0x1D4D48; // type:func\nRvolGetMvgk = 0x1D4D80; // type:func\nKillSoundSystem = 0x1D4DC8; // type:func\nKillSounds = 0x1D4E58; // type:func\nPushSwReverb = 0x1D4F18; // type:func\nPopSwReverb = 0x1D4FC8; // type:func\nSetSwDefaultReverb = 0x1D5060; // type:func\nSetSwIntermittentSound = 0x1D50E8; // type:func\nSetSwIntermittentVolPct = 0x1D5150; // type:func\nSetSwIntermittentRepeat = 0x1D51A0; // type:func\nStartSwIntermittentSounds = 0x1D51D0; // type:func\nSetAMRegister = 0x1D52B8; // type:func\nHsNextFootFall = 0x1D5300; // type:func\nNextSneakyFootstep = 0x1D54D8; // type:func\nInitSpeaker = 0x1D5578; // type:func\nPostSpeakerLoad = 0x1D5640; // type:func\nSetSpeakerSmIdle = 0x1D5690; // type:func\nGetSpeakerParams = 0x1D5720; // type:func\nOnSpireAdd = 0x1D5778; // type:func\nOnSpireRemove = 0x1D57C0; // type:func\nCloneSpire = 0x1D5808; // type:func\nLoadSwSpliceFromBrx = 0x1D5858; // type:func\nPframeFromIsplice = 0x1D5C78; // type:func\nRefEvalModule = 0x1D5CD8; // type:func\nPeopidFind = 0x1D5E00; // type:func\nRefGetObjectList = 0x1D5E70; // type:func\nRefGetPeopid = 0x1D5F40; // type:func\nFAppendSpliceListElement = 0x1D6450; // type:func\nFSpliceListElementExists = 0x1D6528; // type:func\nRefSetPvsFromSplice = 0x1D6678; // type:func\nRefSetArgListFromPvs = 0x1D6930; // type:func\nRefSetPeopid = 0x1D6A38; // type:func\nRefGetOption = 0x1D6D40; // type:func\nRefSetOption = 0x1D6E08; // type:func\nRefAddOption = 0x1D6EA0; // type:func\nRefEnsureOption = 0x1D6F18; // type:func\nRefSetArgsFromSplice = 0x1D6FD0; // type:func\nLoadSprBuf = 0x1D7058; // type:func\nSaveSprBuf = 0x1D71E8; // type:func\n__static_initialization_and_destruction_014 = 0x1D73F8; // type:func\n_GLOBAL_$I$g_asprbuf = 0x1D7620; // type:func\nUpdateSqtrm = 0x1D7648; // type:func\nRenderSqtrm = 0x1D7C88; // type:func\nDrawSqtrm = 0x1D7D50; // type:func\nLoadSquishFromBrx = 0x1D8068; // type:func\nUpdateSquish = 0x1D8158; // type:func\nRenderSquishSelf = 0x1D8250; // type:func\nAdjustSquishNewXp = 0x1D8608; // type:func\nNotifySquishImpact = 0x1D8618; // type:func\nInitStep = 0x1D87A8; // type:func\nPostStepLoad = 0x1D8850; // type:func\nLimitStepHands = 0x1D88F0; // type:func\nRetractStepExtremity = 0x1D8990; // type:func\nRenderStepSelf = 0x1D8C90; // type:func\nReadStepJoystick = 0x1D8DB0; // type:func\nUpdateStepFootfall = 0x1D8E50; // type:func\nUpdateStepPhys = 0x1D9028; // type:func\nSetStepPhys = 0x1D9170; // type:func\nUpdateStep = 0x1D92E8; // type:func\nCtTorqueStep = 0x1D9328; // type:func\nPropagateStepForce = 0x1D9330; // type:func\nRotateStepToMat = 0x1D93D0; // type:func\nCloneStepPhys = 0x1D9438; // type:func\nPresetStepAccel = 0x1D9580; // type:func\nPresetStepAccelBase = 0x1D95C0; // type:func\nFCheckStepXpBase = 0x1D96E8; // type:func\nAdjustStepNewXp = 0x1D97D8; // type:func\nAdjustStepDz = 0x1D9828; // type:func\nAdjustStepDzBase = 0x1D9850; // type:func\nUpdateStepMatTarget = 0x1D9858; // type:func\nAdjustStepXpVelocity = 0x1D9890; // type:func\nUpdateStepXfWorld = 0x1D98F0; // type:func\nAdjustStepXpVelocityBase = 0x1D99A0; // type:func\nAdjustStepXps = 0x1D9CB0; // type:func\nAddStepCustomXps = 0x1DA0E8; // type:func\nAddStepCustomXpsBase = 0x1DA110; // type:func\nFixStepAngularVelocity = 0x1DA270; // type:func\nPredictStepPosition = 0x1DA2E0; // type:func\nPredictStepRotation = 0x1DA308; // type:func\nSetStepSpinRatio = 0x1DA3B8; // type:func\nSetStepGravityRatio = 0x1DA410; // type:func\nGetStepParams = 0x1DA488; // type:func\nGetActaddPositionGoal = 0x1DA4C8; // type:func\nGetActaddRotationGoal = 0x1DA5D8; // type:func\nSetJtJtcs = 0x1DA7A0; // type:func\nUpdateJtCane = 0x1DADC8; // type:func\nUpdateJtActiveCane = 0x1DAE78; // type:func\nChooseJtAttackTarget = 0x1DB028; // type:func\nChooseJtSweepTarget = 0x1DB2C8; // type:func\nChooseJtRushTarget = 0x1DB438; // type:func\nChooseJtSmashTarget = 0x1DB4C0; // type:func\nInitStepguard = 0x1DB548; // type:func\nLoadStepguardFromBrx = 0x1DB720; // type:func\nCloneStepguard = 0x1DB788; // type:func\nBindStepguard = 0x1DB7E8; // type:func\nPostStepguardLoadCallback = 0x1DB8A0; // type:func\nPostStepguardLoad = 0x1DB8C8; // type:func\nFIgnoreStepguardIntersection = 0x1DBB08; // type:func\nOnStepguardAdd = 0x1DBB98; // type:func\nOnStepguardRemove = 0x1DBBE0; // type:func\nPresetStepguardAccel = 0x1DBC88; // type:func\nDradEnemyStepguard = 0x1DC1D0; // type:func\nSetStepguardTargetHeading = 0x1DC268; // type:func\nUpdateStepguardAI = 0x1DC2D0; // type:func\nUpdateStepguardDrive = 0x1DC340; // type:func\nUpdateStepguard = 0x1DC420; // type:func\nSgsNextStepguardAI = 0x1DC598; // type:func\nSetStepguardGoal = 0x1DC9C0; // type:func\nFReachedStepguardGoal = 0x1DCA70; // type:func\nFFilterStepguardJump = 0x1DCA98; // type:func\nMoveStepguardToGoal = 0x1DCB50; // type:func\nLookStepguardAtGoal = 0x1DD178; // type:func\nUpdateStepguardGoal = 0x1DD1D0; // type:func\nOnStepguardWaypointActive = 0x1DD360; // type:func\nUpdateStepguardSgs = 0x1DD430; // type:func\nSetStepguardSgs = 0x1DD558; // type:func\nSetStepguardSgsExternal = 0x1DD610; // type:func\nOnStepguardExitingSgs = 0x1DD648; // type:func\nOnStepguardEnteringSgs = 0x1DD830; // type:func\nSggsGetStepguard = 0x1DDD60; // type:func\nFAbsorbStepguardWkr = 0x1DDD80; // type:func\nFTakeStepguardDamage = 0x1DE050; // type:func\nHandleStepguardGrfsgsc = 0x1DE100; // type:func\nDoStepguardFreefallJump = 0x1DE1B0; // type:func\nDoStepguardFreefallLanding = 0x1DE3C8; // type:func\nHandleStepguardMessage = 0x1DE430; // type:func\nSgasGetStepguard = 0x1DE9F8; // type:func\nFCanStepguardAttack = 0x1DEA00; // type:func\nRenderStepguardSelf = 0x1DEB90; // type:func\nFValidSgs = 0x1DEDA8; // type:func\nUseStepguardAnimation = 0x1DEDB0; // type:func\nUseStepguardAnimationImmediate = 0x1DEE08; // type:func\nUseStepguardDeathAnimation = 0x1DEE90; // type:func\nPasegFindStepguard = 0x1DEEC8; // type:func\nLoadStepguardAnimations = 0x1DEF40; // type:func\nUseStepguardExpl = 0x1DF010; // type:func\nUseStepguardRwm = 0x1DF020; // type:func\nUseStepguardPhys = 0x1DF030; // type:func\nLoadStepguardPhys = 0x1DF088; // type:func\nAddStepguardEffect = 0x1DF120; // type:func\nSetStepguardPathzone = 0x1DF158; // type:func\nPsoEnemyStepguard = 0x1DF1D0; // type:func\nSetStepguardEnemyObject = 0x1DF2A0; // type:func\nRebindStepguardEnemy = 0x1DF2B0; // type:func\nAdjustStepguardNewXp = 0x1DF3D0; // type:func\nAdjustStepguardDz = 0x1DF450; // type:func\nSetStepguardAttackAngleMax = 0x1DF4E0; // type:func\nAddStepguardAlarm = 0x1DF4F8; // type:func\nMatchStepguardAnimationPhase = 0x1DF520; // type:func\nAddStepguardCustomXps = 0x1DF558; // type:func\nApplyStepguardThrow = 0x1DF668; // type:func\nUpdateStepguardEffect = 0x1DF698; // type:func\nSetStepguardPatrolAnimation = 0x1DFA98; // type:func\nFInflictStepguardZap = 0x1DFB48; // type:func\nFDetectStepguard = 0x1DFB50; // type:func\nFCheckStepguardEnemyHidden = 0x1DFB58; // type:func\nPsggNew = 0x1DFD00; // type:func\nInitSgg = 0x1DFD70; // type:func\nAddSggGuard = 0x1DFDA8; // type:func\nAddSggGuardName = 0x1DFE10; // type:func\nAddSggSearchXfmName = 0x1DFE38; // type:func\nRemoveSggGuard = 0x1DFE60; // type:func\nBindSgg = 0x1DFF18; // type:func\nPostSggLoadCallback = 0x1E0050; // type:func\nEnsureSggCallback = 0x1E0288; // type:func\nPsoEnemySgg = 0x1E02E8; // type:func\nUpdateSggCallback = 0x1E0310; // type:func\nSggsNextSgg = 0x1E0390; // type:func\nFDetectSgg = 0x1E04D8; // type:func\nFAbandonSggSearch = 0x1E0580; // type:func\nEnsureSggAlarm = 0x1E0648; // type:func\nTriggerSggAlarms = 0x1E0698; // type:func\nSetSggSggs = 0x1E0718; // type:func\nAssignSggSearchPoints = 0x1E09A8; // type:func\nPostJtLoadSwing = 0x1E0D00; // type:func\nAnticipateJtForce = 0x1E0D90; // type:func\nCalculateJtHangAccel = 0x1E1150; // type:func\nPresetJtAccelHang = 0x1E1928; // type:func\nAddJtExternalAccelerations = 0x1E1A40; // type:func\nUpdateJtActiveHang = 0x1E1A90; // type:func\nCheckJtUnhook = 0x1E20D0; // type:func\nUpdateJtHookOx = 0x1E2200; // type:func\nAddJtHookXps = 0x1E22A0; // type:func\nGetJtHangHeading = 0x1E2588; // type:func\nUpdateJtIkHang = 0x1E25E0; // type:func\nJtbsChooseJtHide = 0x1E2840; // type:func\nMeasureJtJumpToTarget = 0x1E2C38; // type:func\nGetJtRailLanding = 0x1E2EC0; // type:func\nGMeasureJumpRail = 0x1E30D0; // type:func\nGMeasureJumpHshape = 0x1E3150; // type:func\nFFindJtObstruction = 0x1E31C0; // type:func\nJtbsChooseJtLanding = 0x1E32B0; // type:func\nUpdateJtActiveHide = 0x1E3A10; // type:func\nMatchJtXmgRail = 0x1E44D8; // type:func\nUpdateJtHide = 0x1E4610; // type:func\nUpdateJtInternalXpsHide = 0x1E4918; // type:func\nSetJtHfdk = 0x1E4C38; // type:func\nResetJtDynamicTunnel = 0x1E4C98; // type:func\nPresetJtAccelHide = 0x1E4D08; // type:func\nPostJtLoadPipe = 0x1E4EB8; // type:func\nGetJtPipeGoalMat = 0x1E5018; // type:func\nPresetJtAccelPipe = 0x1E5410; // type:func\nUpdateJtActivePipe = 0x1E5560; // type:func\nUpdateJtInternalXpsPipe = 0x1E5C00; // type:func\nSetJtJtpdk = 0x1E5EE0; // type:func\nPlaceJtOnPipe = 0x1E5F58; // type:func\nSetFsp = 0x1E6118; // type:func\nUpdateJtActivePowerUp = 0x1E6238; // type:func\nIRotatePowerUp = 0x1E6560; // type:func\nPostStepLoadRun = 0x1E6630; // type:func\nCalculateBlrunV = 0x1E6950; // type:func\nProjectStepRunPlant = 0x1E69A8; // type:func\nFIntersectStepRunPlant = 0x1E6AC8; // type:func\nFReblendAbl2D = 0x1E6BF8; // type:func\nAdjustStepRun = 0x1E6DA0; // type:func\nSetStepRunTarget = 0x1E70C8; // type:func\nPostJtLoadSidestep = 0x1E7190; // type:func\nAdjustJtSidestep = 0x1E73B0; // type:func\nSetJtSidestepTarget = 0x1E7708; // type:func\nPostJtLoadSki = 0x1E78C0; // type:func\nUpdateJtActiveSki = 0x1E7A70; // type:func\nProjectJtTransformSki = 0x1E8830; // type:func\nEmitJtSkiParticles = 0x1E89A0; // type:func\nAddJtSpeedBoost = 0x1E8E28; // type:func\nPostJtLoadZap = 0x1E8E38; // type:func\nPresetJtAccelZap = 0x1E8EF0; // type:func\nUpdateJtZap = 0x1E90D8; // type:func\nPzqeAppendJt = 0x1E91A0; // type:func\nPopJtZqe = 0x1E9208; // type:func\nFTakeJtDamage = 0x1E9508; // type:func\nFInvulnerableJt = 0x1E9818; // type:func\nOnJtDead = 0x1E98F0; // type:func\nSgnCmpSpkn = 0x1E9990; // type:func\nDrawHaloSpks = 0x1E99B8; // type:func\nDrawJtHaloElectric = 0x1EA398; // type:func\nDrawJtHaloFire = 0x1EA4A8; // type:func\nRenderJtSelfZap = 0x1EA5D0; // type:func\nJthsCurrentJt = 0x1EA8B0; // type:func\nUseJtCharm = 0x1EA8E0; // type:func\nUpdateJtWater = 0x1EA998; // type:func\nFFindJtWaterSurface = 0x1EAD20; // type:func\nAddJtWaterAcceleration = 0x1EAE30; // type:func\nInitZpr = 0x1EAFF8; // type:func\nOSTRM__OSTRM = 0x1EB050; // type:func\nOSTRM__OSTRM1 = 0x1EB070; // type:func\nOSTRM__~OSTRM = 0x1EB098; // type:func\nOSTRM__CbWrite = 0x1EB0E8; // type:func\nOSTRM__Flush = 0x1EB248; // type:func\nInitSuv = 0x1EB368; // type:func\nPostSuvLoad = 0x1EB418; // type:func\nPresetSuvAccel = 0x1EB6B0; // type:func\nGExcludeAlm = 0x1EC240; // type:func\nUpdateSuvBalance = 0x1EC358; // type:func\nDsGetTrackRelative = 0x1EC550; // type:func\nFIsSuvAheadOf = 0x1EC598; // type:func\nUpdateSuvLine = 0x1EC628; // type:func\nUpdateSuvHeading = 0x1ECA78; // type:func\nUpdateSuvWheels = 0x1ECC48; // type:func\nUpdateSuvExpls = 0x1ECD10; // type:func\nBoostSuv = 0x1ED1C0; // type:func\nUpdateSuvVolumes = 0x1ED208; // type:func\nRampTo = 0x1ED5F8; // type:func\nSetSuvTargetFrq = 0x1ED670; // type:func\nSetSuvTargetVol = 0x1ED6D0; // type:func\nUpdateSuvSounds = 0x1ED730; // type:func\nUpdateSuvPuncher = 0x1EDC48; // type:func\nUpdateSuv = 0x1EDE58; // type:func\nUpdateSuvActive = 0x1EDF88; // type:func\nUpdateSuvInternalXps = 0x1EE470; // type:func\nAddSuvCustomXps = 0x1EE480; // type:func\nAdjustSuvNewXp = 0x1EE7B8; // type:func\nUpdateSuvInfluences = 0x1EE8B8; // type:func\nRenderSuvSelf = 0x1EEB18; // type:func\nUpdateSuvBounds = 0x1EED58; // type:func\nCollectSuvPrize = 0x1EEE10; // type:func\nUpdateSuvShapes = 0x1EEE98; // type:func\nUpdateSuvXfWorld = 0x1EEF88; // type:func\nGetSuvCpdefi = 0x1EEFC8; // type:func\nOnSuvActive = 0x1EEFF0; // type:func\nHandleSuvMessage = 0x1EF058; // type:func\nSetSuvTrack = 0x1EF108; // type:func\nSetSuvLine = 0x1EF238; // type:func\nAddSuvBoostOpportunity = 0x1EF280; // type:func\nAddSuvBoostCollect = 0x1EF2C0; // type:func\nAddSuvCheckPoint = 0x1EF300; // type:func\nAddSuvFeature = 0x1EF3E0; // type:func\nSetSuvSuvs = 0x1EF430; // type:func\nResetSuv = 0x1EF498; // type:func\nVecCombo = 0x1EF770; // type:func\nInitSwDlHash = 0x1EF790; // type:func\nInitSw = 0x1EF7F0; // type:func\nDeleteSw = 0x1EFBA0; // type:func\nSetupBulkDataFromBrx = 0x1EFCC8; // type:func\nLoadBulkDataFromBrx = 0x1EFDF8; // type:func\nSetSwGravity = 0x1EFE60; // type:func\nFOverflowSwLo = 0x1EFE90; // type:func\nPxaAllocSw = 0x1EFEC0; // type:func\nFreeSwXaList = 0x1EFF10; // type:func\nPmqAllocSw = 0x1EFF70; // type:func\nFreeSwMqList = 0x1EFFC0; // type:func\nEnsureSwCallback = 0x1F0020; // type:func\nPostSwCallback = 0x1F0090; // type:func\nClearSwCallbacks = 0x1F0110; // type:func\nProcessSwCallbacks = 0x1F0220; // type:func\nProcessSwSpliceScheduledCallbacks = 0x1F02B0; // type:func\nPstsoAllocSw = 0x1F0540; // type:func\nFreeSwStsoList = 0x1F0590; // type:func\nAddSwProxySource = 0x1F05F8; // type:func\nPloGetSwProxySource = 0x1F06C0; // type:func\nIntersectSwBoundingBox = 0x1F06F0; // type:func\nIntersectSwBoundingSphere = 0x1F0990; // type:func\nRemoveOxa = 0x1F0BD8; // type:func\nInitSwAoxa = 0x1F0C08; // type:func\nAddOxa = 0x1F0C80; // type:func\nPoxaAllocSw = 0x1F0CA0; // type:func\nFreeSwPoxa = 0x1F0D08; // type:func\nCreateSwDefaultLights = 0x1F0EC8; // type:func\nLoadNameTableFromBrx = 0x1F1310; // type:func\nLoadWorldTableFromBrx = 0x1F1458; // type:func\nCreateSwPrizes = 0x1F1510; // type:func\nLoadSwFromBrx = 0x1F1698; // type:func\nFClipLineHomogeneous = 0x1F1AC0; // type:func\nDrawLineWorld = 0x1F1C88; // type:func\nDrawAxesWorld = 0x1F1E10; // type:func\nDrawBezWorld = 0x1F1F68; // type:func\nGetSwParams = 0x1F2030; // type:func\nSetSwIllum = 0x1F2060; // type:func\nSetSwIllumShadow = 0x1F2078; // type:func\nSetSwExcitement = 0x1F2090; // type:func\nFLevelSwVisited = 0x1F2100; // type:func\nFLevelSwPrimary = 0x1F2128; // type:func\nFLevelSwSecondary = 0x1F2150; // type:func\nFLevelSwTertiary = 0x1F2178; // type:func\nSetSwPlayerSuck = 0x1F21A0; // type:func\nGetSwPlayerSuck = 0x1F21D8; // type:func\nIncrementSwHandsOff = 0x1F21F0; // type:func\nDecrementSwHandsOff = 0x1F2228; // type:func\nIsSwVagPlaying = 0x1F2260; // type:func\nSetSwDarken = 0x1F2290; // type:func\nSetSwDarkenSmooth = 0x1F22A0; // type:func\nCancelSwDialogPlaying = 0x1F22A8; // type:func\nInitTail = 0x1F22F0; // type:func\nPostTailLoad = 0x1F2330; // type:func\nUpdateTailConstraints = 0x1F24D8; // type:func\nMatchTailOtherObject = 0x1F2DF8; // type:func\nInitTank = 0x1F2E30; // type:func\nPostTankLoad = 0x1F2EB8; // type:func\nUpdateTank = 0x1F2FF0; // type:func\nUseTankCharm = 0x1F3220; // type:func\nUpdateTankActive = 0x1F3270; // type:func\nOnTankActive = 0x1F3A58; // type:func\nRenderTankAll = 0x1F3A98; // type:func\nImpactTank = 0x1F3DE8; // type:func\nFInvulnerableTank = 0x1F3E70; // type:func\nApplyTankThrow = 0x1F3EB8; // type:func\nFTakeTankDamage = 0x1F3FC0; // type:func\nAdjustTankXps = 0x1F4330; // type:func\nAdjustTankNewXp = 0x1F44E8; // type:func\nHandleTankMessage = 0x1F45B0; // type:func\nJthsCurrentTank = 0x1F4708; // type:func\nSetTankTanks = 0x1F4718; // type:func\nStartupTarget = 0x1F4948; // type:func\nResetTargetList = 0x1F4978; // type:func\nInitTarget = 0x1F49A0; // type:func\nOnTargetAdd = 0x1F49E0; // type:func\nOnTargetRemove = 0x1F4A28; // type:func\nCloneTarget = 0x1F4A70; // type:func\nRenderTarget = 0x1F4AC0; // type:func\nCchParsePchzInt = 0x1F4B90; // type:func\nCchParsePchzTft = 0x1F4C18; // type:func\nWriteTftPchz = 0x1F4F88; // type:func\nFNegTftUl = 0x1F50F8; // type:func\nUnRadixFromChConversion = 0x1F51D8; // type:func\nCchAchFromUl = 0x1F5238; // type:func\nWriteTftUl = 0x1F5330; // type:func\nExpFirstFromG = 0x1F5690; // type:func\nChDigitFromG = 0x1F5770; // type:func\nCchAchFromDouble = 0x1F5870; // type:func\nWriteTftDouble = 0x1F5BE0; // type:func\nWriteTft = 0x1F5E80; // type:func\nCchOstrmPrintf = 0x1F62C8; // type:func\nvprintf = 0x1F6410; // type:func\nprintf = 0x1F6488; // type:func\nvsprintf = 0x1F64D8; // type:func\nsprintf = 0x1F6568; // type:func\n_vsnprintf = 0x1F65B8; // type:func\n_snprintf = 0x1F6670; // type:func\nstrlen = 0x1F66C0; // type:func\nstrcpy = 0x1F66F8; // type:func\nstrcat = 0x1F6750; // type:func\nstrchr = 0x1F67C0; // type:func\nUpperizePchz = 0x1F6800; // type:func\nPchzDupSwCchImpl = 0x1F6850; // type:func\nSemaCreate = 0x1F68C0; // type:func\nResetSema = 0x1F6920; // type:func\nInitCritSect = 0x1F69A0; // type:func\nEnterCritSect = 0x1F69E0; // type:func\nLeaveCritSect = 0x1F6A50; // type:func\nStartupThread = 0x1F6A98; // type:func\nPtnfnFromTn = 0x1F6B40; // type:func\nGetTnfnNose = 0x1F6B58; // type:func\nInitTn = 0x1F6C58; // type:func\nOnTnRemove = 0x1F6CF8; // type:func\nLoadTnFromBrx = 0x1F6D60; // type:func\nPostTnLoad = 0x1F6EB0; // type:func\nSetTnTns = 0x1F6ED8; // type:func\nUpdateTnCallback = 0x1F7100; // type:func\nUpdateTn = 0x1F7340; // type:func\nRenderTnSelf = 0x1F73A8; // type:func\nFreezeTn = 0x1F7478; // type:func\nSetTnFocusRatio = 0x1F74C8; // type:func\nCalculateTnCrv = 0x1F74E0; // type:func\nCalculateTnPos = 0x1F76F0; // type:func\nGetTnParams = 0x1F7990; // type:func\nActivateCptn = 0x1F79F8; // type:func\nDeactivateCptn = 0x1F7B98; // type:func\nSetCptn = 0x1F7BA0; // type:func\nRevokeCptn = 0x1F7BA8; // type:func\nUpdateCptn = 0x1F7BB0; // type:func\nLoadTbspFromBrx = 0x1F8E00; // type:func\nFCheckTbspPoint = 0x1F8FC0; // type:func\nCTransition__CTransition = 0x1F9038; // type:func\nCTransition__Set = 0x1F9060; // type:func\nCTransition__Execute = 0x1F9088; // type:func\nResetWorld = 0x1F9608; // type:func\nLoadBrxWorld = 0x1F96D8; // type:func\n__static_initialization_and_destruction_015 = 0x1F9700; // type:func\n_GLOBAL_$I$g_transition = 0x1F9738; // type:func\nPostTurretLoad = 0x1F9760; // type:func\nUpdateTurret = 0x1F9888; // type:func\nUpdateTurretActive = 0x1F9930; // type:func\nOnTurretActive = 0x1F9A40; // type:func\nFFilterTurret = 0x1F9BA0; // type:func\nUpdateTurretAim = 0x1F9C60; // type:func\nFireTurret = 0x1F9F98; // type:func\nHandleTurretMessage = 0x1FA028; // type:func\nFIgnoreTurretIntersection = 0x1FA0F8; // type:func\nCollectTurretPrize = 0x1FA160; // type:func\nGetTurretDiapi = 0x1FA1A8; // type:func\nInitTv = 0x1FA1B8; // type:func\nPostTvLoad = 0x1FA4F8; // type:func\nGetTvItvbMinMax = 0x1FA630; // type:func\nDrawTvArea = 0x1FA670; // type:func\nDrawTvBands = 0x1FA9F8; // type:func\nDrawTvOutline = 0x1FB070; // type:func\nDrawTv = 0x1FB848; // type:func\nSetTvTvs = 0x1FB900; // type:func\nAcceptTvSpeaker = 0x1FB920; // type:func\nSetTvTvgs = 0x1FB9B0; // type:func\nSetTvBlots = 0x1FBAF8; // type:func\nUpdateTv = 0x1FBBF8; // type:func\nRenderTv = 0x1FC0E0; // type:func\nPreTvContext = 0x1FC5A8; // type:func\nPostTvContext = 0x1FC948; // type:func\nSetTvSpeaker = 0x1FCCC8; // type:func\nSetTvReplace = 0x1FCDE0; // type:func\nOnTvReset = 0x1FCE30; // type:func\n__static_initialization_and_destruction_016 = 0x1FCE70; // type:func\n_GLOBAL_$I$RGBA_Distortion = 0x1FCEA8; // type:func\nPostUbvLoad = 0x1FCED0; // type:func\nUpdateUbv = 0x1FD000; // type:func\nSetUbvUbvs = 0x1FD160; // type:func\nPostUbpLoad = 0x1FD6A0; // type:func\nUpdateUbp = 0x1FD710; // type:func\nSetUbpUbps = 0x1FD7A8; // type:func\nCaptureUbpBomb = 0x1FDB28; // type:func\nDetonateUbpBomb = 0x1FDCC0; // type:func\nNotifyUbpImpact = 0x1FDD00; // type:func\nRenderUbpAll = 0x1FDD98; // type:func\nFIgnoreUbpIntersection = 0x1FDDC0; // type:func\nInitUbg = 0x1FDE00; // type:func\nPostUbgLoad = 0x1FDE80; // type:func\nPsoPadUbgClosest = 0x1FDF48; // type:func\nOnUbgEnteringSgs = 0x1FDFA8; // type:func\nSgsNextUbgAI = 0x1FE2D8; // type:func\nFDetectUbg = 0x1FE338; // type:func\nFCanUbgAttack = 0x1FE358; // type:func\nDoUbgFreefallJump = 0x1FE390; // type:func\nDoUbgFreefallLanding = 0x1FE3D8; // type:func\nUpdateUbgGoal = 0x1FE4B8; // type:func\nUpdateUbgSgs = 0x1FE588; // type:func\nFIgnoreUbgIntersection = 0x1FE638; // type:func\nStartupUi = 0x1FE690; // type:func\nInitUi = 0x1FE6B8; // type:func\nPostUiLoad = 0x1FE700; // type:func\nUpdateUi = 0x1FE728; // type:func\nPushUiActiveBlot = 0x1FEC28; // type:func\nPopUiActiveBlot = 0x1FECD0; // type:func\nDrawUiSplash = 0x1FED88; // type:func\nDrawUiSelf = 0x1FF218; // type:func\nDrawUi = 0x1FF248; // type:func\nRenderUi = 0x1FF280; // type:func\nResetUi = 0x1FF2A8; // type:func\nSetUiUis = 0x1FF320; // type:func\nSetUiUPause = 0x1FF4D8; // type:func\nFDebugmenuActive = 0x1FF580; // type:func\nUpdateSwObjects = 0x1FF5B8; // type:func\nUpdateSwPosWorldPrev = 0x1FF800; // type:func\nUpdateSwRealClock = 0x1FF8B8; // type:func\nUpdateSwDarkening = 0x1FFAB0; // type:func\nUpdateSw = 0x1FFB20; // type:func\nFUN_001ffdf0 = 0x1FFDF0; // type:func\nRadNormalize = 0x1FFEF8; // type:func\nGLimitAbs = 0x1FFF78; // type:func\nGSmooth = 0x1FFFB0; // type:func\nGSmoothA = 0x200120; // type:func\nRadSmooth = 0x200230; // type:func\nRadSmoothA = 0x2002B8; // type:func\nPosSmooth = 0x200350; // type:func\nSmoothMatrix = 0x200458; // type:func\nNRandInRange = 0x2005D0; // type:func\nGRandInRange = 0x200648; // type:func\nGRandGaussian = 0x2006B8; // type:func\nFFloatsNear = 0x2007F0; // type:func\nCSolveQuadratic = 0x200828; // type:func\nPrescaleClq = 0x2008B8; // type:func\nCalculateSinCos = 0x200910; // type:func\nGTrunc = 0x200A00; // type:func\nGTrunc1 = 0x200AB8; // type:func\nGModPositive = 0x200B70; // type:func\nFitClq = 0x200BB0; // type:func\nFCheckLm = 0x200BE8; // type:func\nFCheckAlm = 0x200C18; // type:func\nGLimitLm = 0x200CA0; // type:func\nSgnCompareG = 0x200CD0; // type:func\nForce = 0x200D08; // type:func\nMinimizeRange = 0x200D10; // type:func\nSetVectorCylind = 0x201008; // type:func\nSetVectorSphere = 0x201070; // type:func\nSProjectVector = 0x201108; // type:func\nGetNormalVectors = 0x201150; // type:func\nGetNormalVector = 0x201210; // type:func\nRadBetweenVectors = 0x2012D8; // type:func\nFindClosestPointBetweenLines = 0x201460; // type:func\nFindClosestPointBetweenLineSegments = 0x2015E8; // type:func\nCalculateVectorPanTilt = 0x201798; // type:func\nConvertDeulToW = 0x201840; // type:func\nFCalculateMuzzleVelocity = 0x201908; // type:func\nFCalculateMuzzleVelocitySpeed = 0x201AC8; // type:func\nFCalculateMuzzleVelocityAngle = 0x201C40; // type:func\nLimitVectorLength = 0x201C68; // type:func\nDMAI__DMAI = 0x201CD0; // type:func\nDMAI__EnsureQw = 0x201CF8; // type:func\nDMAI__FDone = 0x201E68; // type:func\nDMAI__AdvancePrplsCur = 0x201EB8; // type:func\nDMAI__GetBulk = 0x201EC0; // type:func\nDMAI__Skip = 0x201F28; // type:func\nDMAI__UnNext = 0x201F88; // type:func\nDMAI__UsNext = 0x202008; // type:func\nDMAI__BNext = 0x202080; // type:func\nDMAI__Align = 0x2020E8; // type:func\nVIFE__VIFE = 0x202150; // type:func\nVIFE__Emulate = 0x202190; // type:func\nVIFE__Mask = 0x202768; // type:func\nVIFE__EmulateUnpack = 0x2027E8; // type:func\nVIFE__EmulateClip = 0x202E10; // type:func\nVIFE__EmulateXgkick = 0x202EF0; // type:func\nVIFE__Nop = 0x203018; // type:func\nVIFE__NopCel = 0x203020; // type:func\nVIFE__SetupRgl = 0x203028; // type:func\nVIFE__SetupRglCel = 0x203080; // type:func\nVIFE__CopyRgl = 0x2030A8; // type:func\nVIFE__CopyRglCel = 0x203150; // type:func\nVIFE__DrawP0 = 0x203178; // type:func\nVIFE__DrawP12 = 0x203250; // type:func\nVIFE__DrawP12Force = 0x203278; // type:func\nVIFE__PostNidRgba = 0x2033D8; // type:func\nVIFE__ClearLightingToF32 = 0x203468; // type:func\nVIFE__ConvertLightingU8ToF32 = 0x203540; // type:func\nVIFE__AddDirectionLightAsF32 = 0x203700; // type:func\nVIFE__AddPositionLightAsF32 = 0x203908; // type:func\nVIFE__AddFrustrumLightAsF32 = 0x203BD0; // type:func\nVIFE__AddQuickLightAsF32 = 0x204038; // type:func\nVIFE__AddDirectionLightAsQuickF32 = 0x2043E0; // type:func\nVIFE__AddPositionLightAsQuickF32 = 0x204408; // type:func\nVIFE__AddFrustrumLightAsQuickF32 = 0x204518; // type:func\nVIFE__ConvertLightingF32ToU8 = 0x204768; // type:func\nVIFE__ProcessPrelit = 0x204A80; // type:func\nVIFE__ProcessPrelitClip = 0x204AA8; // type:func\nVIFE__ProcessThreeWayClip = 0x204DA8; // type:func\nVIFE__ProcessThreeWay = 0x205098; // type:func\nVIFE__ProcessVolume = 0x2050C0; // type:func\nVIFE__DrawVolume = 0x2050E8; // type:func\nVIFE__FadeAmbientP0 = 0x205308; // type:func\nVIFE__FadeDiffuseP12 = 0x2054C8; // type:func\nVIFE__CopySaturateP12 = 0x205638; // type:func\nVIFE__CullThreeWay = 0x2057B0; // type:func\nVIFE__CullPrelit = 0x2058B8; // type:func\nVIFE__ToggleCullPrelit = 0x2059C0; // type:func\nVIFE__PvtxpCullFan = 0x205A30; // type:func\nVIFE__PvtxpClipFanToPlane = 0x205AE0; // type:func\nVIFE__PvtxpClipFanToFrustrum = 0x205E08; // type:func\nVIFE__ClipThreeWay = 0x2064F0; // type:func\nVIFE__ClipPrelit = 0x206678; // type:func\nVIFE__DrawPrelit = 0x206AD0; // type:func\nVIFE__DrawShadow = 0x206B90; // type:func\nVIFE__DrawBlipesFixed = 0x206EF8; // type:func\nVIFE__DrawBlipesFlying = 0x2075D8; // type:func\nVIFE__DrawBlipesRolling = 0x207ED0; // type:func\nVIFE__DrawCelBorders = 0x208720; // type:func\nVIFE__ApplyBonesHelper = 0x208AE8; // type:func\nVIFE__ApplyBonesPos = 0x208C30; // type:func\nVIFE__ApplyBonesNormal = 0x208CA0; // type:func\nVIFE__ApplyPoseHelperRsgl = 0x208F68; // type:func\nVIFE__ApplyPoseHelper = 0x208FD8; // type:func\nVIFE__ApplyPosePos = 0x209088; // type:func\nVIFE__ApplyPoseNormal = 0x2090B8; // type:func\nVIFE__ApplyPoseSubcel = 0x2090E0; // type:func\nVIFE__PostPoseNormals = 0x209148; // type:func\nVIFE__AnimateUVs = 0x209340; // type:func\nVIFE__ApplyWarpHelper = 0x2093B8; // type:func\nVIFE__ApplyWarp_Plus0 = 0x2094D8; // type:func\nVIFE__ApplyWarp_Plus2 = 0x209500; // type:func\nVIFE__ApplyWarp_Plus3 = 0x209528; // type:func\nVIFE__EmulateMscal = 0x209550; // type:func\nVIFS__VIFS = 0x209660; // type:func\nVIFS__Align = 0x2096B8; // type:func\nVIFS__AddVifBaseOffset = 0x209708; // type:func\nVIFS__AddVifMscal = 0x209740; // type:func\nVIFS__AddVifMscalf = 0x209770; // type:func\nVIFS__AddVifFlush = 0x2097A0; // type:func\nVIFS__AddVifFlusha = 0x2097B8; // type:func\nVIFS__AddVifFlushe = 0x2097D0; // type:func\nVIFS__AddVifStcycl = 0x2097E8; // type:func\nVIFS__AddVifStrow = 0x209810; // type:func\nVIFS__AddVifStmask = 0x209878; // type:func\nVIFS__CbUnpackSetup = 0x2098B0; // type:func\nVIFS__UnpackHelper = 0x209918; // type:func\nVIFS__AddVifUnpack = 0x2099C0; // type:func\nVIFS__AddVifUnpackRefs = 0x209A78; // type:func\nVIFS__AddVifDirect = 0x209B48; // type:func\nVIFS__AddVifDirectRefs = 0x209BD8; // type:func\nVIFS__AddVifGifs = 0x209C68; // type:func\nInitVismap = 0x209CA0; // type:func\nLoadVismapFromBrx = 0x209CD8; // type:func\nGrfzonOneHop = 0x209DB0; // type:func\nClipVbspSphereOneHop = 0x209E20; // type:func\nClipVismapSphereOneHop = 0x209F78; // type:func\nClipVismapPointNoHop = 0x209FC8; // type:func\nInitWater = 0x20A078; // type:func\nPostWaterLoad = 0x20A108; // type:func\nCalculateWaterCurrent = 0x20A1C8; // type:func\nUpdateSwXaList = 0x20A440; // type:func\nUpdateWater = 0x20A598; // type:func\nAddWaterExternalAccelerations = 0x20A9D8; // type:func\nHandleWaterMessage = 0x20AA08; // type:func\nUpdateWaterMergeGroup = 0x20AB80; // type:func\nUGetWaterSubmerged = 0x20AC28; // type:func\nUpdateWaterBounds = 0x20ADA8; // type:func\nFInflictWaterZap = 0x20AE50; // type:func\nPzpdEnsureWater = 0x20AE78; // type:func\nInitWaypoint = 0x20AE80; // type:func\nPostWaypointLoad = 0x20AEB8; // type:func\nSetWaypointRsmg = 0x20AF28; // type:func\nUpdateWaypoint = 0x20AF68; // type:func\nSetWaypointWps = 0x20AF70; // type:func\nHandleWaypointMessage = 0x20B048; // type:func\nPwpsgNew = 0x20B0C0; // type:func\nAddWpsgWaypoint = 0x20B0F8; // type:func\nRemoveWpsgWaypoint = 0x20B120; // type:func\nUpdateWpsgCallback = 0x20B1C0; // type:func\nEnsureWpsgCallback = 0x20B350; // type:func\nwibuInit = 0x20B3A0; // type:func\nwibuGetFirstSerial = 0x20B460; // type:func\nInitWipe = 0x20B4F0; // type:func\nUpdateWipe = 0x20B520; // type:func\nDrawWipe = 0x20B720; // type:func\nActivateWipe = 0x20B7F0; // type:func\nSetWipeButtonTrans = 0x20B8C0; // type:func\nFCatchWipeButtonTrans = 0x20B8F0; // type:func\nSetWipeWipes = 0x20B9F8; // type:func\nWipeToWorldWarp = 0x20BCE0; // type:func\nPostWmLoad = 0x20BD20; // type:func\nBindWm = 0x20BD70; // type:func\nRefreshWmMoveStats = 0x20BEB8; // type:func\nThrowWmDisplayState = 0x20BF70; // type:func\nCatchWmDisplayState = 0x20BF88; // type:func\nUpdateWm = 0x20C1A0; // type:func\nRenderWmAll = 0x20C578; // type:func\nHandleWmMessage = 0x20C5E8; // type:func\nSetWmWms = 0x20C6F0; // type:func\nShowWm = 0x20CBE0; // type:func\nHideWm = 0x20CC60; // type:func\nMoveWm = 0x20CC98; // type:func\nGetWmWorldPosScreen = 0x20CE00; // type:func\nSetWmCursor = 0x20CF08; // type:func\nPostWmcLoad = 0x20CFC0; // type:func\nUpdateWmcActive = 0x20D060; // type:func\nOnWmcActive = 0x20D340; // type:func\nDrawWmFan = 0x20D4B0; // type:func\nDrawWmc = 0x20D750; // type:func\n__static_initialization_and_destruction_017 = 0x20DD28; // type:func\n_GLOBAL_$I$U_WmFadedLevels = 0x20DDF0; // type:func\nInitWr = 0x20DE18; // type:func\nGetWrParams = 0x20DE60; // type:func\nHandleWrMessage = 0x20DFD8; // type:func\nApplyWrGlob = 0x20DFF8; // type:func\nUpdateWrStateVectors = 0x20E0A0; // type:func\nWarpWrTransform = 0x20E788; // type:func\nGetWrBounds = 0x20E9E8; // type:func\nUNoise = 0x20EAA0; // type:func\nUNoise1 = 0x20EAF8; // type:func\nUBias = 0x20EBE0; // type:func\nGFromOnz = 0x20EC10; // type:func\nUpdateWrMatrixes = 0x20ECD8; // type:func\nAddWrCircleWarp = 0x20EFF0; // type:func\nAddWrBendWarp = 0x20F070; // type:func\nPwreGetWrCur = 0x20F0E0; // type:func\nPwreGetWrCircle = 0x20F118; // type:func\nPwreGetWrBend = 0x20F140; // type:func\nSetWrWavelength = 0x20F168; // type:func\nGetWrWavelength = 0x20F1C0; // type:func\nAddOnzOnze = 0x20F218; // type:func\nAddWrBendNoise = 0x20F250; // type:func\nAddWrSwivelNoise = 0x20F2C8; // type:func\nInitXfm = 0x20F340; // type:func\nLoadXfmFromBrx = 0x20F390; // type:func\nSetXfmParent = 0x20F3F8; // type:func\nApplyXfmProxy = 0x20F470; // type:func\nGetXfmParams = 0x20F4D8; // type:func\nConvertXfmLocalToWorld = 0x20F508; // type:func\nConvertXfmWorldToLocal = 0x20F568; // type:func\nGetXfmPos = 0x20F600; // type:func\nGetXfmMat = 0x20F638; // type:func\nPwarpFromOid = 0x20F670; // type:func\nLoadWarpFromBrx = 0x20F790; // type:func\nCloneWarp = 0x20F950; // type:func\nPostWarpLoad = 0x20FA08; // type:func\nGetWarpParams = 0x20FAA0; // type:func\nTriggerWarp = 0x20FB08; // type:func\nAddWarpShowWhenDifficult = 0x20FFD0; // type:func\nSetWarpRsmg = 0x20FFF8; // type:func\nTeleportSwPlayer = 0x210038; // type:func\nPexitDefault = 0x2100C0; // type:func\nTriggerDefaultExit = 0x210158; // type:func\nLoadExitFromBrx = 0x2101F8; // type:func\nPostExitLoad = 0x210390; // type:func\nSetExitExits = 0x210498; // type:func\nTriggerExit = 0x210678; // type:func\nWipeExit = 0x210838; // type:func\nUpdateExit = 0x210900; // type:func\nGetExitParams = 0x210BE0; // type:func\nInitCamera = 0x210C48; // type:func\nPostCameraLoad = 0x210C80; // type:func\nEnableCamera = 0x210D18; // type:func\nInitTzp = 0x210DA8; // type:func\nPostTzpLoad = 0x210E20; // type:func\nUpdateTzp = 0x210E60; // type:func\nCloneTzp = 0x211020; // type:func\nRenderTzpAll = 0x211050; // type:func\nFInflictTzpZap = 0x2110F0; // type:func\nPzpdEnsureTzp = 0x211118; // type:func\nInitVolzp = 0x211120; // type:func\nUpdateVolzp = 0x211180; // type:func\nInitZpd = 0x211498; // type:func\nPostZpdLoad = 0x2114B0; // type:func\nApplyZpdThrow = 0x211600; // type:func\nInflictZpdZap = 0x211B40; // type:func\nAddZpdZapObject = 0x211BB0; // type:func\nAddZpdZapLo = 0x211BD8; // type:func\nRemoveZpdZapLo = 0x211CB0; // type:func\nmemcmp = 0x211D4C; // type:func\nmemcpy = 0x211DE0; // type:func\nmemmove = 0x211E90; // type:func\nmemset = 0x211F94; // type:func\nqsort = 0x212058; // type:func\nsrand = 0x212A80; // type:func\nrand = 0x212A90; // type:func\nstrcasecmp = 0x212AC0; // type:func\nSetGsCrt = 0x212B90; // type:func\n_Exit = 0x212BA0; // type:func\n_LoadExecPS2 = 0x212BB0; // type:func\nAddIntcHandler = 0x212BE0; // type:func\nRemoveIntcHandler = 0x212BF0; // type:func\nAddDmacHandler = 0x212C00; // type:func\nAddDmacHandler2 = 0x212C10; // type:func\nRemoveDmacHandler = 0x212C20; // type:func\n_EnableIntc = 0x212C30; // type:func\n_DisableIntc = 0x212C40; // type:func\n_EnableDmac = 0x212C50; // type:func\n_DisableDmac = 0x212C60; // type:func\nSetAlarm = 0x212C70; // type:func\nCreateThread = 0x212CA0; // type:func\nStartThread = 0x212CB0; // type:func\nExitDeleteThread = 0x212CC0; // type:func\nChangeThreadPriority = 0x212CE0; // type:func\niChangeThreadPriority = 0x212CF0; // type:func\nRotateThreadReadyQueue = 0x212D00; // type:func\nGetThreadId = 0x212D20; // type:func\nReferThreadStatus = 0x212D30; // type:func\nWakeupThread = 0x212D50; // type:func\n_iWakeupThread = 0x212D60; // type:func\nSuspendThread = 0x212D80; // type:func\niResumeThread = 0x212D90; // type:func\nCreateSema = 0x212DB0; // type:func\nDeleteSema = 0x212DC0; // type:func\nSignalSema = 0x212DD0; // type:func\niSignalSema = 0x212DE0; // type:func\nWaitSema = 0x212DF0; // type:func\nPollSema = 0x212E00; // type:func\nReferSemaStatus = 0x212E20; // type:func\nSetOsdConfigParam = 0x212E30; // type:func\nGetOsdConfigParam = 0x212E40; // type:func\nFlushCache = 0x212EC0; // type:func\nsceSifStopDma = 0x212EE0; // type:func\nGsGetIMR = 0x212F00; // type:func\nGsPutIMR = 0x212F10; // type:func\nsceSifDmaStat = 0x212F30; // type:func\nsceSifSetDma = 0x212F40; // type:func\nisceSifSetDma = 0x212F50; // type:func\nsceSifSetDChain = 0x212F60; // type:func\nisceSifSetDChain = 0x212F70; // type:func\nsceSifSetReg = 0x212F80; // type:func\nsceSifGetReg = 0x212F90; // type:func\nDeci2Call = 0x212FB0; // type:func\nGetMemorySize = 0x212FC0; // type:func\n_InitTLB = 0x212FD0; // type:func\nDisableIntc = 0x212FE0; // type:func\nEnableIntc = 0x213048; // type:func\nDisableDmac = 0x2130B0; // type:func\nEnableDmac = 0x213118; // type:func\nsetup = 0x213180; // type:func\nCopy = 0x213190; // type:func\nkCopy = 0x2131A0; // type:func\nGetEntryAddress = 0x2131D8; // type:func\nInitAlarm1 = 0x2131E8; // type:func\ntopThread = 0x2132C0; // type:func\nInitThread = 0x213398; // type:func\niWakeupThread = 0x213470; // type:func\nkputchar = 0x213510; // type:func\ndeci2Putchar = 0x213548; // type:func\nserialPutchar = 0x2135F8; // type:func\nftoi = 0x213630; // type:func\nprintfloat = 0x2136C0; // type:func\n_printf = 0x213828; // type:func\nkprintf = 0x213DF0; // type:func\nscePrintf = 0x213E28; // type:func\n_set_sreg = 0x213E88; // type:func\n_change_addr = 0x213EA8; // type:func\nsceSifGetSreg = 0x213EB8; // type:func\nsceSifInitCmd = 0x213EE0; // type:func\nsceSifExitCmd = 0x214160; // type:func\nsceSifAddCmdHandler = 0x214198; // type:func\nsceSifRemoveCmdHandler = 0x2141C8; // type:func\n_sceSifSendCmd = 0x2141F0; // type:func\nsceSifSendCmd = 0x214328; // type:func\nisceSifSendCmd = 0x214368; // type:func\n_sceSifCmdIntrHdlr = 0x2143A8; // type:func\nsceSifWriteBackDCache = 0x2144D0; // type:func\nsceSifInitRpc = 0x214580; // type:func\nsceSifExitRpc = 0x214720; // type:func\n_sceRpcGetPacket = 0x214748; // type:func\n_sceRpcFreePacket = 0x2147F0; // type:func\n_sceRpcGetFPacket = 0x214810; // type:func\n_request_end = 0x214840; // type:func\n_request_rdata = 0x2148F8; // type:func\n_search_svdata = 0x214958; // type:func\n_request_bind = 0x2149A8; // type:func\nsceSifBindRpc = 0x214A58; // type:func\n_request_call = 0x214B98; // type:func\nsceSifCallRpc = 0x214C28; // type:func\nsceSifCheckStatRpc = 0x214E18; // type:func\n_sceFsIobSemaMK = 0x214E70; // type:func\nget_iob = 0x214ED0; // type:func\n_sceFs_Rcv_Intr = 0x214F40; // type:func\n_sceFsSemInit = 0x215300; // type:func\n_sceFsWaitS = 0x215350; // type:func\n_sceFsSigSema = 0x215380; // type:func\n_sceFs_Poff_Intr = 0x215390; // type:func\nsceFsInit = 0x2153C0; // type:func\nsceFsReset = 0x215590; // type:func\nsceClose = 0x2155D0; // type:func\nsceRead = 0x215750; // type:func\nsceWrite = 0x2159C0; // type:func\nsceIoctl = 0x215C80; // type:func\n_lf_bind = 0x216028; // type:func\n_lf_version = 0x216128; // type:func\nsceSifLoadFileReset = 0x2161B8; // type:func\n_sceSifLoadModule = 0x216200; // type:func\nsceSifLoadModule = 0x216428; // type:func\nsceSifResetIop = 0x216470; // type:func\nsceSifSyncIop = 0x2165B0; // type:func\nsceSifRebootIop = 0x2165E8; // type:func\nDIntr = 0x2166F8; // type:func\nEIntr = 0x216740; // type:func\nsupplement_crt0 = 0x216758; // type:func\nkFindAddress = 0x2167A0; // type:func\nFindAddress = 0x2167D8; // type:func\nGetSystemCallTableEntry = 0x2167E8; // type:func\nsetup1 = 0x216828; // type:func\n_InitSys = 0x216840; // type:func\nsetup2 = 0x216880; // type:func\nCopy1 = 0x216890; // type:func\nkCopy1 = 0x2168A0; // type:func\nGetEntryAddress1 = 0x2168D8; // type:func\nPatchIsNeeded = 0x2168E8; // type:func\nInitExecPS2 = 0x216950; // type:func\nTerminateLibrary = 0x216A00; // type:func\nLoadExecPS2 = 0x216A10; // type:func\nExit = 0x216A58; // type:func\nsceResetttyinit = 0x216A80; // type:func\ngetpid = 0x216AB8; // type:func\nkill = 0x216AC0; // type:func\nkputs = 0x216B20; // type:func\nCopy2 = 0x216B78; // type:func\nkCopy2 = 0x216B88; // type:func\nGetEntryAddress2 = 0x216BC0; // type:func\nsetup3 = 0x216BD0; // type:func\nInitTLBFunctions = 0x216BE0; // type:func\n_SetTLBEntry = 0x216C98; // type:func\nInitTLB = 0x216CA8; // type:func\nInitTLB32MB = 0x216CE8; // type:func\n_kExitTLBHandler = 0x216F40; // type:func\n__do_global_ctors = 0x217068; // type:func\n__main = 0x217118; // type:func\n__divdi3 = 0x217138; // type:func\n__fixunsdfdi = 0x217828; // type:func\n__floatdidf = 0x217918; // type:func\n__floatdisf = 0x2179B0; // type:func\n__moddi3 = 0x217A90; // type:func\n__pure_virtual = 0x2180F8; // type:func\n__udivdi3 = 0x218100; // type:func\n__umoddi3 = 0x2186D0; // type:func\n__pack_d = 0x218C10; // type:func\n__unpack_d = 0x218D40; // type:func\n_fpadd_parts = 0x218DE0; // type:func\ndpadd = 0x219020; // type:func\ndpsub = 0x219078; // type:func\ndpmul = 0x2190E0; // type:func\ndpdiv = 0x219388; // type:func\n__fpcmp_parts_d = 0x2194F0; // type:func\ndpcmp = 0x219608; // type:func\nlitodp = 0x219658; // type:func\ndptoli = 0x219710; // type:func\ndptoul = 0x2197A8; // type:func\n__make_dp = 0x219848; // type:func\ndptofp = 0x219878; // type:func\n__pack_f = 0x2198D0; // type:func\n__unpack_f = 0x2199E0; // type:func\n__make_fp = 0x219AA0; // type:func\nfptodp = 0x219AD0; // type:func\n__builtin_vec_new = 0x219B10; // type:func\n__default_terminate = 0x219B88; // type:func\n__terminate = 0x219B98; // type:func\n__throw_type_match = 0x219BC0; // type:func\n__empty = 0x219BF0; // type:func\nnew_eh_context = 0x219BF8; // type:func\n__get_eh_context = 0x219C50; // type:func\n__get_eh_info = 0x219C78; // type:func\neh_context_initialize = 0x219CA0; // type:func\neh_context_static = 0x219CC8; // type:func\n__get_dynamic_handler_chain = 0x219D30; // type:func\n__sjthrow = 0x219D58; // type:func\n__sjpopnthrow = 0x219ED0; // type:func\n__eh_rtime_match = 0x219FE8; // type:func\n__get_eh_table_version = 0x21A030; // type:func\n__get_eh_table_language = 0x21A038; // type:func\nold_find_exception_handler = 0x21A040; // type:func\nfind_exception_handler = 0x21A118; // type:func\nget_reg_addr = 0x21A260; // type:func\ncopy_reg = 0x21A2E8; // type:func\nnext_stack_level = 0x21A368; // type:func\n__unwinding_cleanup = 0x21A3F8; // type:func\nthrow_helper = 0x21A400; // type:func\n__throw = 0x21A730; // type:func\n__rethrow = 0x21A910; // type:func\n__muldi3 = 0x21AAF8; // type:func\nterminate = 0x21AB58; // type:func\n__default_unexpected = 0x21AB70; // type:func\nset_terminate = 0x21AB80; // type:func\nset_unexpected = 0x21AB90; // type:func\nunexpected = 0x21ABA0; // type:func\n__cp_exception_info = 0x21ABB8; // type:func\n__cp_eh_info = 0x21ABE0; // type:func\n__start_cp_handler = 0x21AC00; // type:func\n__eh_alloc = 0x21AC38; // type:func\n__eh_free = 0x21AC60; // type:func\n__cplus_type_matcher = 0x21AC80; // type:func\n__cp_push_exception = 0x21ACF0; // type:func\n__cp_pop_exception = 0x21AD80; // type:func\n__uncatch_exception = 0x21AE48; // type:func\n__check_eh_spec = 0x21AE78; // type:func\n__throw_bad_cast = 0x21B030; // type:func\n__throw_bad_typeid = 0x21B0B0; // type:func\nuncaught_exception = 0x21B130; // type:func\nexception__what = 0x21B168; // type:func\nbad_exception__~bad_exception = 0x21B190; // type:func\nbad_exception__bad_exception = 0x21B1C0; // type:func\nbad_exception_type_info_function = 0x21B1D8; // type:func\nexception__~exception = 0x21B228; // type:func\nexception__exception = 0x21B258; // type:func\nexception_type_info_function = 0x21B270; // type:func\ndecode_uleb128 = 0x21B2B0; // type:func\ndecode_sleb128 = 0x21B2F8; // type:func\nfde_merge = 0x21B348; // type:func\nend_fde_sort = 0x21B448; // type:func\ncount_fdes = 0x21B6B0; // type:func\nadd_fdes = 0x21B6F8; // type:func\nframe_init = 0x21B780; // type:func\nfind_fde = 0x21B8C0; // type:func\nextract_cie_info = 0x21B9A8; // type:func\nexecute_cfa_insn = 0x21BAB0; // type:func\n__register_frame_info_table = 0x21BE48; // type:func\n__deregister_frame_info = 0x21BE70; // type:func\n__frame_state_for = 0x21BEE8; // type:func\nfde_split = 0x21C0C0; // type:func\nset_new_handler = 0x21C238; // type:func\n[] = 0x21C248; // type:func\noperator.new = 0x21C250; // type:func\nbad_alloc__what = 0x21C258; // type:func\nbad_alloc_type_info_function = 0x21C268; // type:func\nbad_alloc__~bad_alloc = 0x21C2B8; // type:func\ntype_info__~type_info = 0x21C2E8; // type:func\ntype_info__operatorEQEQ = 0x21C318; // type:func\n__rtti_class = 0x21C358; // type:func\n__rtti_si = 0x21C380; // type:func\n__rtti_user = 0x21C3A0; // type:func\n__user_type_info__dcast = 0x21C3C0; // type:func\n__si_type_info__dcast = 0x21C3F0; // type:func\n__class_type_info__dcast = 0x21C488; // type:func\n__class_type_info____class_type_info = 0x21C660; // type:func\n__class_type_info_type_info_function = 0x21C680; // type:func\n__class_type_info__~__class_type_info = 0x21C6D0; // type:func\n__si_type_info____si_type_info = 0x21C6F0; // type:func\n__si_type_info_type_info_function = 0x21C710; // type:func\n__si_type_info__~__si_type_info = 0x21C760; // type:func\n__user_type_info____user_type_info = 0x21C780; // type:func\n__user_type_info_type_info_function = 0x21C798; // type:func\n__user_type_info__~__user_type_info = 0x21C7E8; // type:func\nbad_typeid__~bad_typeid = 0x21C808; // type:func\nbad_typeid__bad_typeid = 0x21C838; // type:func\nbad_typeid_type_info_function = 0x21C850; // type:func\nbad_cast__~bad_cast = 0x21C8A0; // type:func\nbad_cast__bad_cast = 0x21C8D0; // type:func\nbad_cast_type_info_function = 0x21C8E8; // type:func\ntype_info__operator!EQ = 0x21C938; // type:func\ntype_info__name = 0x21C958; // type:func\ntype_info__type_info = 0x21C960; // type:func\ntype_info_type_info_function = 0x21C978; // type:func\ntype_info__before = 0x21C9B8; // type:func\n__throw_type_match_rtti = 0x21C9E0; // type:func\n__is_pointer = 0x21CEA8; // type:func\n__rtti_ptr = 0x21CEF8; // type:func\n__rtti_attr = 0x21CF18; // type:func\n__rtti_func = 0x21CF40; // type:func\n__rtti_ptmf = 0x21CF60; // type:func\n__rtti_ptmd = 0x21CF80; // type:func\n__rtti_array = 0x21CFA0; // type:func\n__dynamic_cast = 0x21CFC0; // type:func\nvoid_type_info_function = 0x21D070; // type:func\nlong_long_type_info_function = 0x21D0A8; // type:func\nlong_type_info_function = 0x21D0E0; // type:func\nint_type_info_function = 0x21D118; // type:func\nshort_type_info_function = 0x21D150; // type:func\nbool_type_info_function = 0x21D188; // type:func\nchar_type_info_function = 0x21D1C0; // type:func\nwchar_t_type_info_function = 0x21D1F8; // type:func\nlong_double_type_info_function = 0x21D230; // type:func\ndouble_type_info_function = 0x21D268; // type:func\nfloat_type_info_function = 0x21D2A0; // type:func\nunsigned_int_type_info_function = 0x21D2D8; // type:func\nunsigned_long_type_info_function = 0x21D310; // type:func\nunsigned_long_long_type_info_function = 0x21D348; // type:func\nunsigned_short_type_info_function = 0x21D380; // type:func\nunsigned_char_type_info_function = 0x21D3B8; // type:func\nsigned_char_type_info_function = 0x21D3F0; // type:func\n__array_type_info_type_info_function = 0x21D428; // type:func\n__array_type_info__~__array_type_info = 0x21D478; // type:func\n__ptmd_type_info_type_info_function = 0x21D498; // type:func\n__ptmd_type_info__~__ptmd_type_info = 0x21D4E8; // type:func\n__ptmf_type_info_type_info_function = 0x21D508; // type:func\n__ptmf_type_info__~__ptmf_type_info = 0x21D558; // type:func\n__func_type_info_type_info_function = 0x21D578; // type:func\n__func_type_info__~__func_type_info = 0x21D5C8; // type:func\n__builtin_type_info_type_info_function = 0x21D5E8; // type:func\n__builtin_type_info__~__builtin_type_info = 0x21D638; // type:func\n__attr_type_info_type_info_function = 0x21D658; // type:func\n__attr_type_info__~__attr_type_info = 0x21D6A8; // type:func\n__pointer_type_info_type_info_function = 0x21D6C8; // type:func\n__pointer_type_info__~__pointer_type_info = 0x21D718; // type:func\nabort = 0x21D738; // type:func\n__errno = 0x21D758; // type:func\n_init_signal_r = 0x21D768; // type:func\n_raise_r = 0x21D7E0; // type:func\nraise = 0x21D8D0; // type:func\n_kill_r = 0x21D908; // type:func\n_getpid_r = 0x21D968; // type:func\nstrcmp = 0x21D984; // type:func\nstrncpy = 0x21DAC8; // type:func\nsnputs = 0x21DC90; // type:func\nsceGsResetPath = 0x21DE20; // type:func\nsceGsSyncPath = 0x21DEC0; // type:func\nsimpleatoi.3 = 0x21DF50; // type:func\nsceDemoStart = 0x21DFC0; // type:func\nsceDemoEnd = 0x21E0F0; // type:func\nsceGsResetGraph = 0x21E140; // type:func\nsceGsGetGParam = 0x21E2D0; // type:func\nsceGsSetDefDispEnv = 0x21E2E0; // type:func\nsceGsPutDispEnv = 0x21E550; // type:func\nsceGsPutDrawEnv = 0x21E610; // type:func\nsceGsSetDefDBuff = 0x21E6F8; // type:func\nsceGsSwapDBuff = 0x21E990; // type:func\nsceGsPutIMR = 0x21E9F0; // type:func\nsceGsSetHalfOffset = 0x21EA30; // type:func\nsceGsGetIMR = 0x21EAB8; // type:func\nsceGszbufaddr = 0x21EAD8; // type:func\nsceGsSetDefDrawEnv = 0x21EBA0; // type:func\nsceGsSetDefClear = 0x21ED88; // type:func\nmemclr = 0x21EE90; // type:func\nsceDmaGetChan = 0x21EEC8; // type:func\nsceDmaReset = 0x21EEF0; // type:func\nsceDmaPutEnv = 0x21EFD0; // type:func\nsceDmaSend = 0x21F1A8; // type:func\nsceDmaRecv = 0x21F290; // type:func\nsceDmaSync = 0x21F360; // type:func\nCB_DelayTh = 0x21F430; // type:func\nsceCdDelayThread = 0x21F458; // type:func\n_sceCd_cd_callback = 0x21F4C8; // type:func\n_sceCd_cd_read_intr = 0x21F578; // type:func\ncmd_sem_init = 0x21F618; // type:func\ncdvd_exit = 0x21F6B0; // type:func\n_sceCd_Poff_Intr = 0x21F738; // type:func\nPowerOffCB = 0x21F778; // type:func\nsceCdSearchFile = 0x21F7E0; // type:func\n_sceCd_ncmd_prechk = 0x21FAE0; // type:func\nsceCdNcmdDiskReady = 0x21FC50; // type:func\nsceCdSync = 0x21FCE8; // type:func\nsceCdSyncS = 0x21FD88; // type:func\n_sceCd_scmd_prechk = 0x21FDF8; // type:func\nsceCdInit = 0x21FF68; // type:func\nsceCdDiskReady = 0x220248; // type:func\nsceCdMmode = 0x220440; // type:func\nsceCdGetReadPos = 0x220508; // type:func\nsceCdRead = 0x220538; // type:func\nsceCdGetDiskType = 0x220718; // type:func\nsceCdGetError = 0x2207B0; // type:func\nsceCdBreak = 0x220848; // type:func\n_send_to_iop = 0x220900; // type:func\nscePadInit = 0x220A18; // type:func\nscePadInit2 = 0x220B58; // type:func\nscePadEnd = 0x220BF8; // type:func\nscePadPortOpen = 0x220C78; // type:func\nscePadGetDmaStr = 0x220E60; // type:func\nscePadRead = 0x220EC0; // type:func\nscePadGetState = 0x220F40; // type:func\nscePadSetReqState = 0x220FC0; // type:func\nscePadGetReqState = 0x221028; // type:func\nscePadInfoAct = 0x221080; // type:func\nscePadInfoMode = 0x2211A8; // type:func\nscePadSetMainMode = 0x2212E0; // type:func\nscePadSetActDirect = 0x221398; // type:func\nscePadSetActAlign = 0x221458; // type:func\nscePadGetButtonMask = 0x221530; // type:func\nscePadSetButtonInfo = 0x2215E8; // type:func\nscePadInfoPressMode = 0x221698; // type:func\nscePadEnterPressMode = 0x2216F8; // type:func\nscePadGetModVersion = 0x221768; // type:func\n_sceSDC = 0x2217D0; // type:func\nSyncDCache = 0x221878; // type:func\natanf = 0x221918; // type:func\ncosf = 0x221BC0; // type:func\nfabsf = 0x221CA8; // type:func\nfloorf = 0x221CC8; // type:func\nsinf = 0x221DB0; // type:func\ntanf = 0x221EA0; // type:func\nacosf = 0x221F28; // type:func\nasinf = 0x222028; // type:func\natan2f = 0x222128; // type:func\nfmodf = 0x222250; // type:func\nlogf = 0x222390; // type:func\nlog10f = 0x2224D8; // type:func\npowf = 0x222628; // type:func\n__ieee754_acosf = 0x222B30; // type:func\n__ieee754_asinf = 0x222F60; // type:func\n__ieee754_atan2f = 0x223300; // type:func\n__ieee754_fmodf = 0x2235E8; // type:func\n__ieee754_logf = 0x223838; // type:func\n__ieee754_log10f = 0x223B60; // type:func\n__ieee754_powf = 0x223C90; // type:func\n__ieee754_rem_pio2f = 0x224520; // type:func\n__ieee754_sqrtf = 0x224900; // type:func\n__kernel_cosf = 0x224A38; // type:func\n__kernel_rem_pio2f = 0x224B90; // type:func\n__kernel_sinf = 0x2254E0; // type:func\n__kernel_tanf = 0x2255E8; // type:func\nmatherr = 0x225880; // type:func\nrint = 0x2258A8; // type:func\nfinitef = 0x225AA8; // type:func\nisnanf = 0x225AD0; // type:func\nscalbnf = 0x225AF8; // type:func\ncopysignf = 0x225C58; // type:func\n_type2id = 0x225C88; // type:func\nsceMpegDemuxPssRing = 0x225D18; // type:func\nsceMpegDemuxPss = 0x226010; // type:func\nsceMpegAddStrCallback = 0x226030; // type:func\n_pack_header = 0x226128; // type:func\n_system_header = 0x226278; // type:func\n_PES_packet = 0x2262E8; // type:func\nsceMpegInit = 0x226898; // type:func\nsceMpegCreate = 0x226938; // type:func\nsceMpegDelete = 0x226B40; // type:func\nsceMpegGetPicture = 0x226B50; // type:func\nsceMpegIsEnd = 0x226BA8; // type:func\nsceMpegReset = 0x226BB8; // type:func\nsceMpegClearRefBuff = 0x226C08; // type:func\nsceMpegAddCallback = 0x226C60; // type:func\n_dispatchMpegCallback = 0x226C88; // type:func\n_dispatchMpegCbNodata = 0x226CD8; // type:func\n_alalcInit = 0x226D38; // type:func\n_alalcSetDynamic = 0x226D50; // type:func\n_alalcFree = 0x226D60; // type:func\n_alalcAlloc = 0x226D70; // type:func\n_getpic = 0x226DE0; // type:func\n_decodeOrSkipFrame = 0x226F50; // type:func\n_decodeOrSkip = 0x227068; // type:func\n_decodeOrSkipField = 0x2270B0; // type:func\n_sceMpegFlush = 0x227210; // type:func\n_initSeqAgain = 0x227278; // type:func\n_lastFrame = 0x227288; // type:func\n_clearOnce = 0x227308; // type:func\n_clearEach = 0x227368; // type:func\n_ErrMessage = 0x227428; // type:func\n_Error1 = 0x227438; // type:func\n_Error = 0x227470; // type:func\n_RefImageInit = 0x2274C8; // type:func\n_sequenceHeader = 0x2274E8; // type:func\n_initSeq = 0x227610; // type:func\n_initRefImages = 0x2278B8; // type:func\n_setDefaultQM = 0x227998; // type:func\n_sequenceExtension = 0x227A70; // type:func\n_sequenceDisplayExtension = 0x227BA0; // type:func\n_sequenceScalableExtension = 0x227C30; // type:func\n_unknown_extension = 0x227C40; // type:func\n_pictureSpatialScalableExtension = 0x227C50; // type:func\n_pictureTemporalScalableExtension = 0x227C60; // type:func\n_defStopDMA = 0x227C70; // type:func\n_defRestartDMA = 0x227C80; // type:func\n_motionComp0 = 0x227C90; // type:func\n_getAllRefs = 0x227EE0; // type:func\n_getRef0 = 0x2285E8; // type:func\n_doMC = 0x228A08; // type:func\n_rix_000 = 0x228C28; // type:func\n_ri0_000 = 0x228CA0; // type:func\n_rix_001 = 0x228D38; // type:func\n_ri0_001 = 0x228DF0; // type:func\n_rix_010 = 0x228EC0; // type:func\n_ri0_010 = 0x228F70; // type:func\n_rix_011 = 0x229028; // type:func\n_ri0_011 = 0x229120; // type:func\n_rix_100 = 0x229220; // type:func\n_ri0_100 = 0x2292C0; // type:func\n_rix_101 = 0x229370; // type:func\n_ri0_101 = 0x229450; // type:func\n_rix_110 = 0x229538; // type:func\n_ri0_110 = 0x229610; // type:func\n_rix_111 = 0x2296E0; // type:func\n_ri0_111 = 0x229800; // type:func\n_copyAddRefImage = 0x229918; // type:func\n_copyRefImage = 0x229978; // type:func\n_ipuSetMPEG1 = 0x2299D8; // type:func\n_waitBdecOut = 0x229A00; // type:func\n_dmVector = 0x229BF0; // type:func\n_dualPrimeVector = 0x229C10; // type:func\n_mbAddressIncrement = 0x229D98; // type:func\n_pictureData0 = 0x229EA8; // type:func\n_sliceA0 = 0x229FB0; // type:func\n_slice0 = 0x22A0E0; // type:func\n_skipMB0 = 0x22A2D0; // type:func\n_decMB0 = 0x22A390; // type:func\n_decode_motion_vector = 0x22A838; // type:func\n_motionVectors = 0x22A8C0; // type:func\n_motionVector = 0x22AA60; // type:func\n_sendIpuCommand = 0x22ABB0; // type:func\n_waitIpuIdle = 0x22ABE0; // type:func\n_waitIpuIdle64 = 0x22AC88; // type:func\n_ipuVdec = 0x22AD38; // type:func\n_peepBit = 0x22AEB0; // type:func\n_flushBuf = 0x22AFB8; // type:func\n_nextBit = 0x22B0A8; // type:func\n_nextStartCode = 0x22B1F8; // type:func\n_sliceB = 0x22B278; // type:func\n_nextHeader = 0x22B2E0; // type:func\n_pictureHeader = 0x22B3F0; // type:func\n_extensionAndUserData = 0x22B4B8; // type:func\n_pictureCodingExtension = 0x22B5E0; // type:func\n_extrainfo = 0x22B7D0; // type:func\n_updateTempTackData = 0x22B818; // type:func\n_groupOfPicturesHeader = 0x22B890; // type:func\n_quantMatrixExtension = 0x22B930; // type:func\n_pictureDisplayExtension = 0x22B9F8; // type:func\n_copyrightExtension = 0x22BAF0; // type:func\n_decPicture = 0x22BB80; // type:func\n_outputFrame = 0x22BC50; // type:func\n_updateRefImage = 0x22BCE0; // type:func\n_isOutSizeOK = 0x22BF98; // type:func\n_cpr8 = 0x22C038; // type:func\n_markOutput = 0x22C2A8; // type:func\n_getPtsDtsFlags = 0x22C2D0; // type:func\n_dispRefImage = 0x22C460; // type:func\n_dispRefImageField = 0x22C570; // type:func\ndmaRefImage = 0x22C728; // type:func\nreceiveDataFromIPU = 0x22C880; // type:func\n_doCSC = 0x22C8F0; // type:func\n_ch3dmaCSC = 0x22CA08; // type:func\n_doCSC2 = 0x22CB80; // type:func\n_ch4dma = 0x22CD30; // type:func\n_csc_storeRefImage = 0x22CE38; // type:func\n_sysbitInit = 0x22D0B0; // type:func\n_sysbitNext = 0x22D0E8; // type:func\n_sysbitFlush = 0x22D108; // type:func\n_sysbitGet = 0x22D1A0; // type:func\n_sysbitMarker = 0x22D1F0; // type:func\n_sysbitJump = 0x22D238; // type:func\n_sysbitPtr = 0x22D290; // type:func\nsetD3_CHCR = 0x22D2C0; // type:func\nsetD4_CHCR = 0x22D328; // type:func\nsceIpuStopDMA = 0x22D390; // type:func\nsceIpuRestartDMA = 0x22D478; // type:func\nsceIpuSync = 0x22D5C8; // type:func\nsetD4_CHCR1 = 0x22D630; // type:func\nsceIpuInit = 0x22D698; // type:func\nsn_reg_frame = 0x22D8D0; // type:func\nsn_dereg_frame = 0x22D8E8; // type:func\n_GLOBAL_$F$terminate = 0x28E164; // type:func\ntype_info___GLOBAL_$F$before = 0x28E9A8; // type:func\nFUN_002946e8 = 0x2946E8; // type:func\nFUN_00294748 = 0x294748; // type:func\nFUN_00294888 = 0x294888; // type:func\nFUN_002956a0 = 0x2956A0; // type:func\nFUN_00297a78 = 0x297A78; // type:func\n"
  },
  {
    "path": "config/symbol_addrs_old.txt",
    "content": "_start = 0x100008; // type:func\n_exit = 0x1000B8; // type:func\nRefThunkLoREMOVEFnUser = 0x100178; // type:func\nRefThunkLoREMOVEFn = 0x100218; // type:func\nFUN_001002c0 = 0x1002C0; // type:func\nFUN_00100368 = 0x100368; // type:func\nFUN_00100438 = 0x100438; // type:func\nFUN_001004f0 = 0x1004F0; // type:func\nFUN_001005a0 = 0x1005A0; // type:func\nFUN_00100650 = 0x100650; // type:func\nFUN_00100720 = 0x100720; // type:func\nFUN_001007f0 = 0x1007F0; // type:func\nFUN_001008b8 = 0x1008B8; // type:func\nFUN_00100998 = 0x100998; // type:func\nFUN_00100a78 = 0x100A78; // type:func\nFUN_00100b48 = 0x100B48; // type:func\nFUN_00100c28 = 0x100C28; // type:func\nFUN_00100cc8 = 0x100CC8; // type:func\nFUN_00100d68 = 0x100D68; // type:func\nFUN_00100e08 = 0x100E08; // type:func\nFUN_00100ee0 = 0x100EE0; // type:func\nFUN_00100fa8 = 0x100FA8; // type:func\nFUN_00101058 = 0x101058; // type:func\nFUN_00101168 = 0x101168; // type:func\nFUN_00101208 = 0x101208; // type:func\nFUN_001012b8 = 0x1012B8; // type:func\nFUN_00101368 = 0x101368; // type:func\nFUN_00101418 = 0x101418; // type:func\nFUN_001014c8 = 0x1014C8; // type:func\nFUN_00101568 = 0x101568; // type:func\nFUN_00101620 = 0x101620; // type:func\nFUN_001016f0 = 0x1016F0; // type:func\nFUN_001017a0 = 0x1017A0; // type:func\nFUN_00101860 = 0x101860; // type:func\nFUN_00101950 = 0x101950; // type:func\nFUN_001019f0 = 0x1019F0; // type:func\nFUN_00101a90 = 0x101A90; // type:func\nFUN_00101b80 = 0x101B80; // type:func\nFUN_00101c88 = 0x101C88; // type:func\nFUN_00101d38 = 0x101D38; // type:func\nFUN_00101e10 = 0x101E10; // type:func\nFUN_00101eb0 = 0x101EB0; // type:func\nFUN_00101f60 = 0x101F60; // type:func\nFUN_00102030 = 0x102030; // type:func\nFUN_001020d0 = 0x1020D0; // type:func\nFUN_00102178 = 0x102178; // type:func\nFUN_00102268 = 0x102268; // type:func\nFUN_00102358 = 0x102358; // type:func\nFUN_001023f8 = 0x1023F8; // type:func\nRefThunkAlarmTRIGGER = 0x1024B0; // type:func\nFUN_00102560 = 0x102560; // type:func\nFUN_00102650 = 0x102650; // type:func\nFUN_00102710 = 0x102710; // type:func\nFUN_001027c0 = 0x1027C0; // type:func\nFUN_00102870 = 0x102870; // type:func\nFUN_00102920 = 0x102920; // type:func\nFUN_001029d0 = 0x1029D0; // type:func\nFUN_00102a70 = 0x102A70; // type:func\nFUN_00102b10 = 0x102B10; // type:func\nFUN_00102c28 = 0x102C28; // type:func\nFUN_00102d40 = 0x102D40; // type:func\nFUN_00102de0 = 0x102DE0; // type:func\nFUN_00102f10 = 0x102F10; // type:func\nFUN_00102fb0 = 0x102FB0; // type:func\nFUN_001030e0 = 0x1030E0; // type:func\nFUN_001031c0 = 0x1031C0; // type:func\nFUN_00103260 = 0x103260; // type:func\nFUN_00103350 = 0x103350; // type:func\nFUN_00103420 = 0x103420; // type:func\nFUN_001034f0 = 0x1034F0; // type:func\nFUN_00103590 = 0x103590; // type:func\nFUN_00103640 = 0x103640; // type:func\nFUN_001036f0 = 0x1036F0; // type:func\nFUN_001037a0 = 0x1037A0; // type:func\nFUN_00103850 = 0x103850; // type:func\nFUN_00103900 = 0x103900; // type:func\nFUN_001039b0 = 0x1039B0; // type:func\nFUN_00103a60 = 0x103A60; // type:func\nFUN_00103b40 = 0x103B40; // type:func\nFUN_00103c10 = 0x103C10; // type:func\nFUN_00103cc0 = 0x103CC0; // type:func\nFUN_00103d70 = 0x103D70; // type:func\nFUN_00103e10 = 0x103E10; // type:func\nFUN_00103eb0 = 0x103EB0; // type:func\nFUN_00103f80 = 0x103F80; // type:func\nFUN_00104020 = 0x104020; // type:func\nFUN_001040c0 = 0x1040C0; // type:func\nFUN_00104170 = 0x104170; // type:func\nFUN_00104220 = 0x104220; // type:func\nFUN_001042f0 = 0x1042F0; // type:func\nFUN_001043a0 = 0x1043A0; // type:func\nFUN_00104470 = 0x104470; // type:func\nFUN_00104510 = 0x104510; // type:func\nFUN_001045b0 = 0x1045B0; // type:func\nFUN_00104660 = 0x104660; // type:func\nFUN_00104710 = 0x104710; // type:func\nFUN_001047c0 = 0x1047C0; // type:func\nFUN_00104860 = 0x104860; // type:func\nFUN_00104900 = 0x104900; // type:func\nFUN_001049d8 = 0x1049D8; // type:func\nFUN_00104a78 = 0x104A78; // type:func\nFUN_00104b18 = 0x104B18; // type:func\nFUN_00104c00 = 0x104C00; // type:func\nFUN_00104ca0 = 0x104CA0; // type:func\nFUN_00104d40 = 0x104D40; // type:func\nFUN_00104de0 = 0x104DE0; // type:func\nFUN_00104e80 = 0x104E80; // type:func\nFUN_00104f50 = 0x104F50; // type:func\nFUN_00105020 = 0x105020; // type:func\nFUN_001050d0 = 0x1050D0; // type:func\nFUN_001051c0 = 0x1051C0; // type:func\nFUN_00105290 = 0x105290; // type:func\nFUN_00105360 = 0x105360; // type:func\nFUN_00105430 = 0x105430; // type:func\nFUN_00105500 = 0x105500; // type:func\nFUN_001055a8 = 0x1055A8; // type:func\nFUN_00105658 = 0x105658; // type:func\nFUN_00105728 = 0x105728; // type:func\nFUN_001057d8 = 0x1057D8; // type:func\nFUN_00105878 = 0x105878; // type:func\nFUN_00105960 = 0x105960; // type:func\nFUN_00105a00 = 0x105A00; // type:func\nFUN_00105ab0 = 0x105AB0; // type:func\nFUN_00105b60 = 0x105B60; // type:func\nFUN_00105c10 = 0x105C10; // type:func\nFUN_00105cc0 = 0x105CC0; // type:func\nFUN_00105d60 = 0x105D60; // type:func\nFUN_00105e10 = 0x105E10; // type:func\nFUN_00105ec0 = 0x105EC0; // type:func\nFUN_00105f70 = 0x105F70; // type:func\nFUN_00106048 = 0x106048; // type:func\nFUN_00106120 = 0x106120; // type:func\nOnEnterTurretTrigger = 0x1061C0; // type:func\nFUN_00106270 = 0x106270; // type:func\nFUN_00106320 = 0x106320; // type:func\nFUN_001063d0 = 0x1063D0; // type:func\nFUN_001064c0 = 0x1064C0; // type:func\nFUN_00106560 = 0x106560; // type:func\nFUN_00106600 = 0x106600; // type:func\nFUN_001066f0 = 0x1066F0; // type:func\nFUN_001067a0 = 0x1067A0; // type:func\nFUN_00106850 = 0x106850; // type:func\nFUN_00106920 = 0x106920; // type:func\nFUN_001069c0 = 0x1069C0; // type:func\nFUN_00106a70 = 0x106A70; // type:func\nFUN_00106b10 = 0x106B10; // type:func\nFUN_00106bb0 = 0x106BB0; // type:func\nFUN_00106c50 = 0x106C50; // type:func\nFUN_00106cf0 = 0x106CF0; // type:func\nFUN_00106d90 = 0x106D90; // type:func\nFUN_00106e60 = 0x106E60; // type:func\nFUN_00106f00 = 0x106F00; // type:func\nFUN_00106fa0 = 0x106FA0; // type:func\nFUN_00107040 = 0x107040; // type:func\nFUN_001070e0 = 0x1070E0; // type:func\nFUN_00107180 = 0x107180; // type:func\nFUN_00107268 = 0x107268; // type:func\nFUN_00107350 = 0x107350; // type:func\nFUN_001073f0 = 0x1073F0; // type:func\nFUN_001074c0 = 0x1074C0; // type:func\nFUN_00107570 = 0x107570; // type:func\nFUN_00107678 = 0x107678; // type:func\nFUN_00107718 = 0x107718; // type:func\nFUN_001077d8 = 0x1077D8; // type:func\nFUN_00107898 = 0x107898; // type:func\nFUN_00107948 = 0x107948; // type:func\nFUN_00107a10 = 0x107A10; // type:func\nFUN_00107ab0 = 0x107AB0; // type:func\nFUN_00107b60 = 0x107B60; // type:func\nFUN_00107c00 = 0x107C00; // type:func\nFUN_00107cb0 = 0x107CB0; // type:func\nFUN_00107d60 = 0x107D60; // type:func\nFUN_00107e10 = 0x107E10; // type:func\nFUN_00107ec0 = 0x107EC0; // type:func\nFUN_00107f70 = 0x107F70; // type:func\nFUN_00108038 = 0x108038; // type:func\nFUN_00108128 = 0x108128; // type:func\nFUN_00108208 = 0x108208; // type:func\nFUN_001082e8 = 0x1082E8; // type:func\nFUN_001083c8 = 0x1083C8; // type:func\nFUN_00108498 = 0x108498; // type:func\nFUN_00108548 = 0x108548; // type:func\nFUN_001085e8 = 0x1085E8; // type:func\nFUN_00108688 = 0x108688; // type:func\nFUN_00108728 = 0x108728; // type:func\nFUN_001087d8 = 0x1087D8; // type:func\nFUN_00108878 = 0x108878; // type:func\nFUN_00108928 = 0x108928; // type:func\nFUN_001089c8 = 0x1089C8; // type:func\nFUN_00108a98 = 0x108A98; // type:func\nFUN_00108b48 = 0x108B48; // type:func\nFUN_00108be8 = 0x108BE8; // type:func\nFUN_00108cc8 = 0x108CC8; // type:func\nFUN_00108da8 = 0x108DA8; // type:func\nFUN_00108e70 = 0x108E70; // type:func\nFUN_00108f38 = 0x108F38; // type:func\nFUN_00109000 = 0x109000; // type:func\nFUN_001090c8 = 0x1090C8; // type:func\nFUN_001091a8 = 0x1091A8; // type:func\nFUN_00109258 = 0x109258; // type:func\nFUN_00109308 = 0x109308; // type:func\nFUN_001093b8 = 0x1093B8; // type:func\nBuildEopids = 0x109488; // type:func\nFUN_00112698 = 0x112698; // type:func\nFUN_00112968 = 0x112968; // type:func\nFUN_00112c38 = 0x112C38; // type:func\nFUN_00113240 = 0x113240; // type:func\nRefOpPrint = 0x113730; // type:func\nFUN_00113780 = 0x113780; // type:func\nFUN_001137d0 = 0x1137D0; // type:func\nFUN_00113820 = 0x113820; // type:func\nFUN_00113888 = 0x113888; // type:func\nFUN_001139e8 = 0x1139E8; // type:func\nFUN_00113a18 = 0x113A18; // type:func\nFUN_00113a48 = 0x113A48; // type:func\nFUN_00113a78 = 0x113A78; // type:func\nRefOpEqv = 0x113AA8; // type:func\nFUN_00113b60 = 0x113B60; // type:func\nFUN_00113e48 = 0x113E48; // type:func\nFUN_00113e78 = 0x113E78; // type:func\nFUN_00113ee0 = 0x113EE0; // type:func\nFUN_00113f48 = 0x113F48; // type:func\nFUN_00113fb0 = 0x113FB0; // type:func\nFUN_00114018 = 0x114018; // type:func\nFUN_00114080 = 0x114080; // type:func\nFUN_001140e8 = 0x1140E8; // type:func\nFUN_00114150 = 0x114150; // type:func\nFUN_001141b8 = 0x1141B8; // type:func\nFUN_00114220 = 0x114220; // type:func\nFUN_00114288 = 0x114288; // type:func\nFUN_00114300 = 0x114300; // type:func\nFUN_00114360 = 0x114360; // type:func\nFUN_001143c8 = 0x1143C8; // type:func\nFUN_00114438 = 0x114438; // type:func\nFUN_001144a0 = 0x1144A0; // type:func\nFUN_00114518 = 0x114518; // type:func\nFUN_001145c8 = 0x1145C8; // type:func\nRefOpCons = 0x114638; // type:func\nFUN_001146e0 = 0x1146E0; // type:func\nFUN_00114740 = 0x114740; // type:func\nRefOpSetCadr = 0x1147B8; // type:func\nFUN_00114858 = 0x114858; // type:func\nFUN_00114888 = 0x114888; // type:func\nRefOpLength = 0x1148B8; // type:func\nFUN_00114950 = 0x114950; // type:func\nFUN_001149f0 = 0x1149F0; // type:func\nFUN_00114b80 = 0x114B80; // type:func\nRefOpAppend = 0x114BB0; // type:func\nFUN_00114d18 = 0x114D18; // type:func\nFUN_00114f48 = 0x114F48; // type:func\nFUN_001151c0 = 0x1151C0; // type:func\nFUN_00115398 = 0x115398; // type:func\nFUN_00115440 = 0x115440; // type:func\nFUN_00115510 = 0x115510; // type:func\nFUN_001156b0 = 0x1156B0; // type:func\nFUN_00115710 = 0x115710; // type:func\nFUN_001157e0 = 0x1157E0; // type:func\nFUN_001158b8 = 0x1158B8; // type:func\nFUN_001159b8 = 0x1159B8; // type:func\nFUN_00115b78 = 0x115B78; // type:func\nFUN_00115c00 = 0x115C00; // type:func\nRefUfo = 0x115CA0; // type:func\nFUN_00115d48 = 0x115D48; // type:func\nFUN_00115d78 = 0x115D78; // type:func\nFUN_00115da8 = 0x115DA8; // type:func\nFUN_00115dd8 = 0x115DD8; // type:func\nFUN_00115e08 = 0x115E08; // type:func\nFUN_00115e38 = 0x115E38; // type:func\nFUN_00115e68 = 0x115E68; // type:func\nFUN_00115e98 = 0x115E98; // type:func\nFUN_00115ec8 = 0x115EC8; // type:func\nFUN_00115f70 = 0x115F70; // type:func\nFUN_00115ff8 = 0x115FF8; // type:func\nFUN_00116080 = 0x116080; // type:func\nFUN_00116108 = 0x116108; // type:func\nFUN_001161f8 = 0x1161F8; // type:func\nRefOpVectorNormalize = 0x1162D0; // type:func\nFUN_00116400 = 0x116400; // type:func\nFUN_00116490 = 0x116490; // type:func\nRefOpVectorBallisticVelocity = 0x116520; // type:func\nRefOpVectorRadianNormal = 0x116600; // type:func\nRefOpMatrixTranspose = 0x1166C0; // type:func\nRefOpMatrixInvert = 0x116740; // type:func\nFUN_001167c0 = 0x1167C0; // type:func\nFUN_00116840 = 0x116840; // type:func\nFUN_00116978 = 0x116978; // type:func\nFUN_001169e8 = 0x1169E8; // type:func\nFUN_00116a88 = 0x116A88; // type:func\nFUN_00116b08 = 0x116B08; // type:func\nFUN_00116bc8 = 0x116BC8; // type:func\nFUN_00116c80 = 0x116C80; // type:func\nFUN_00116d20 = 0x116D20; // type:func\nRefOpClqEvaluateLm = 0x116DC8; // type:func\nFUN_00116ea8 = 0x116EA8; // type:func\nFUN_00116fe8 = 0x116FE8; // type:func\nFUN_00117080 = 0x117080; // type:func\nFUN_00117118 = 0x117118; // type:func\nFUN_00117180 = 0x117180; // type:func\nFUN_001171f0 = 0x1171F0; // type:func\nFUN_00117260 = 0x117260; // type:func\nFUN_001172c8 = 0x1172C8; // type:func\nFUN_00117360 = 0x117360; // type:func\nFUN_00117478 = 0x117478; // type:func\nFUN_00117598 = 0x117598; // type:func\nFUN_00117610 = 0x117610; // type:func\nRefOpScheduleCallback = 0x117668; // type:func\nFUN_00117880 = 0x117880; // type:func\nFUN_00117910 = 0x117910; // type:func\nFUN_00117a30 = 0x117A30; // type:func\nFUN_00117a60 = 0x117A60; // type:func\nFUN_00117a90 = 0x117A90; // type:func\nFUN_00117ac0 = 0x117AC0; // type:func\nRefPairFromAplo = 0x117AF0; // type:func\nFUN_00117bc8 = 0x117BC8; // type:func\nFUN_00117c48 = 0x117C48; // type:func\nFUN_00117d00 = 0x117D00; // type:func\nFUN_00117d78 = 0x117D78; // type:func\nFUN_00117e20 = 0x117E20; // type:func\nFUN_00117e78 = 0x117E78; // type:func\nFUN_00117ed0 = 0x117ED0; // type:func\nFUN_00117f28 = 0x117F28; // type:func\nRefOpFindObjectsInBoundingBox = 0x117FE0; // type:func\nFUN_001180c0 = 0x1180C0; // type:func\nRefOpHitTestObjectsImpl = 0x118198; // type:func\nFUN_001183b8 = 0x1183B8; // type:func\nFUN_00118458 = 0x118458; // type:func\nFUN_001184f8 = 0x1184F8; // type:func\nFUN_00118580 = 0x118580; // type:func\nFUN_00118608 = 0x118608; // type:func\nFUN_00118698 = 0x118698; // type:func\nRefOpStartSound = 0x118720; // type:func\nFUN_001187e8 = 0x1187E8; // type:func\nFUN_00118850 = 0x118850; // type:func\nFUN_001188f0 = 0x1188F0; // type:func\nRefOpPredictAnimationEffect = 0x118988; // type:func\nVU_FLOAT__VU_FLOAT = 0x118CF0; // type:func\nVU_VECTOR__VU_VECTOR = 0x118D10; // type:func\nVECTOR__operatorEQ = 0x118D20; // type:func\nVECTOR__operatorSTAR = 0x118D30; // type:func\nFUN_00118d48 = 0x118D48; // type:func\nFUN_00118db8 = 0x118DB8; // type:func\nFUN_00118e80 = 0x118E80; // type:func\nRefEvalAssert = 0x118F48; // type:func\nRefEvalIf = 0x119030; // type:func\nRefEvalOr = 0x119128; // type:func\nRefEvalAnd = 0x119218; // type:func\nRefEvalCond = 0x119310; // type:func\nRefEvalCase = 0x1194A8; // type:func\nRefEvalLet = 0x1196C8; // type:func\nFUN_00119878 = 0x119878; // type:func\nRefEvalLambda = 0x119970; // type:func\nRefEvalLambdaBody = 0x119A58; // type:func\nRefEvalBegin = 0x119AF8; // type:func\nRefEvalApply = 0x119BB0; // type:func\nRefEvalImport = 0x119FA0; // type:func\nRefEval = 0x11A080; // type:func\nCFrame__SetSingleParent = 0x11A328; // type:func\nCFrame__AddParent = 0x11A338; // type:func\nFUN_0011a358 = 0x11A358; // type:func\nFUN_0011a400 = 0x11A400; // type:func\nCFrame__FFindBinding = 0x11A498; // type:func\nCFrame__PrefFindBinding = 0x11A4D8; // type:func\nFUN_0011a5b0 = 0x11A5B0; // type:func\nFUN_0011a630 = 0x11A630; // type:func\nCGc__CGc = 0x11A678; // type:func\nCGC__~CGc = 0x11A680; // type:func\nCGc__Startup = 0x11A6A8; // type:func\nCGc__Shutdown = 0x11A6B8; // type:func\nCGc__AddRootFrame = 0x11A6C0; // type:func\nFUN_0011a708 = 0x11A708; // type:func\nFUN_0011a728 = 0x11A728; // type:func\nFUN_0011a748 = 0x11A748; // type:func\nFUN_0011a770 = 0x11A770; // type:func\nFUN_0011a790 = 0x11A790; // type:func\nFUN_0011a7b8 = 0x11A7B8; // type:func\nFUN_0011a7d8 = 0x11A7D8; // type:func\nCGc__UpdateRecyclable = 0x11A800; // type:func\nCGc__MarkLiveObjects = 0x11A850; // type:func\nCGc__Collect = 0x11AB58; // type:func\nFUN_0011adf8 = 0x11ADF8; // type:func\nFUN_0011ae38 = 0x11AE38; // type:func\nFUN_0011ae58 = 0x11AE58; // type:func\nPmethodNew = 0x11AE78; // type:func\nFUN_0011aeb8 = 0x11AEB8; // type:func\nFUN_0011af28 = 0x11AF28; // type:func\nFUN_0011af78 = 0x11AF78; // type:func\nCProc__CloneTo = 0x11AF98; // type:func\nFUN_0011afc8 = 0x11AFC8; // type:func\nCRef__CRef = 0x11B008; // type:func\nCRef__CRef_copy = 0x11B018; // type:func\nCRef__~CRef = 0x11B060; // type:func\nCRref__operatorEQ = 0x11B0A8; // type:func\nCRef__operatorEQEQ = 0x11B0F8; // type:func\nFUN_0011b258 = 0x11B258; // type:func\nCRef__Decref = 0x11B418; // type:func\nCRef__Incref = 0x11B4A8; // type:func\nCRef__FUN_0011b538 = 0x11B538; // type:func\nCRef__SetS32 = 0x11B570; // type:func\nCRef__SetF32 = 0x11B5B0; // type:func\nCRef__SetBool = 0x11B5F0; // type:func\nFUN_0011b640 = 0x11B640; // type:func\nFUN_0011b680 = 0x11B680; // type:func\nFUN_0011b6c0 = 0x11B6C0; // type:func\nFUN_0011b700 = 0x11B700; // type:func\nCRef__SetVector = 0x11B740; // type:func\nFUN_0011b788 = 0x11B788; // type:func\nCRef__SetClq = 0x11B7D0; // type:func\nCRef__SetLm = 0x11B818; // type:func\nFUN_0011b860 = 0x11B860; // type:func\nFUN_0011b8a8 = 0x11B8A8; // type:func\nFUN_0011b8e8 = 0x11B8E8; // type:func\nFUN_0011b928 = 0x11B928; // type:func\nCRef__RefCoerceF32 = 0x11B9A8; // type:func\nPpairSerializeIn = 0x11BA28; // type:func\nCSidebag__RefAddBinding = 0x11BD28; // type:func\nCSidebag__RefSetBinding = 0x11BDD0; // type:func\nFUN_0011be90 = 0x11BE90; // type:func\nFUN_0011bee0 = 0x11BEE0; // type:func\nFUN_0011bf30 = 0x11BF30; // type:func\nStartupSplice = 0x11BF70; // type:func\nShutdownSplice = 0x11C040; // type:func\nFUN_0011c0a8 = 0x11C0A8; // type:func\nFUN_0011c0e8 = 0x11C0E8; // type:func\nFUN_0011c108 = 0x11C108; // type:func\nCSplotheap__Startup = 0x11C128; // type:func\nCSplotheap__Shutdown = 0x11C1D0; // type:func\nCSplotheap__PvAllocUnsafe = 0x11C1D8; // type:func\nFUN_0011c240 = 0x11C240; // type:func\nCSplotheap__PsplotLookup = 0x11C288; // type:func\nCSplotheap__UpdateRecyclable = 0x11C2A0; // type:func\nCSplotheap__UnmarkAll = 0x11C2B0; // type:func\nFUN_0011c2e8 = 0x11C2E8; // type:func\nPvFromPsplot = 0x11C3B8; // type:func\nPsplotFromPv = 0x11C3C0; // type:func\nFUN_0011c3c8 = 0x11C3C8; // type:func\nFUN_0011c3f0 = 0x11C3F0; // type:func\nFUN_0011c418 = 0x11C418; // type:func\nFUN_0011c498 = 0x11C498; // type:func\nFUN_0011c4e8 = 0x11C4E8; // type:func\nPvectorNew = 0x11C508; // type:func\nIncrefVector = 0x11C580; // type:func\nDecrefVector = 0x11C5B0; // type:func\nFUN_0011c618 = 0x11C618; // type:func\nFUN_0011c690 = 0x11C690; // type:func\nDecrefMatrix = 0x11C6C0; // type:func\nFUN_0011c720 = 0x11C720; // type:func\nPclqNew = 0x11C748; // type:func\nFUN_0011c7c0 = 0x11C7C0; // type:func\nDecrefClq = 0x11C7F0; // type:func\nPlmNew = 0x11C858; // type:func\nIncrefClq = 0x11C8D0; // type:func\nDecrefLm = 0x11C900; // type:func\nFUN_0011c968 = 0x11C968; // type:func\nIncrefSmp = 0x11C9E0; // type:func\nDefrefSmp = 0x11CA20; // type:func\nStartupSpliceStructuredTypeFactories = 0x11CA90; // type:func\nShutdownSpliceStructuredTypeFactories = 0x11CBB0; // type:func\nsnd_StartSoundSystem = 0x11CBB8; // type:func\nsnd_FlushSoundCommands = 0x11CE30; // type:func\nwait_for_sif_rpc_done_3QMARK = 0x11D078; // type:func\nsnd_PrepareReturnBuffer = 0x11D110; // type:func\nFUN_0011d140 = 0x11D140; // type:func\nFUN_0011d2a8 = 0x11D2A8; // type:func\nsnd_ResolveBankXREFS = 0x11D420; // type:func\nsnd_UnloadBank = 0x11D450; // type:func\nsnd_SetMasterVolume = 0x11D480; // type:func\nFUN_0011d4b8 = 0x11D4B8; // type:func\nFUN_0011d4e0 = 0x11D4E0; // type:func\nFUN_0011d520 = 0x11D520; // type:func\nFUN_0011d558 = 0x11D558; // type:func\nsnd_PlaySoundVolPanPMPB = 0x11D598; // type:func\nsndStopSound = 0x11D600; // type:func\nFUN_0011d640 = 0x11D640; // type:func\nFUN_0011d670 = 0x11D670; // type:func\nFUN_0011d6a8 = 0x11D6A8; // type:func\nsnd_ContinueAllSoundsInGroup = 0x11D6D8; // type:func\nsnd_SoundIsStillPlaying = 0x11D708; // type:func\nFUN_0011d730 = 0x11D730; // type:func\nFUN_0011d760 = 0x11D760; // type:func\nFUN_0011d798 = 0x11D798; // type:func\nFUN_0011d7d8 = 0x11D7D8; // type:func\nFUN_0011d810 = 0x11D810; // type:func\nFUN_0011d860 = 0x11D860; // type:func\nFUN_0011d8b0 = 0x11D8B0; // type:func\nFUN_0011d8f0 = 0x11D8F0; // type:func\nsnd_SetGlobalExcite = 0x11D928; // type:func\nsnd_SendIOPCommandAndWait = 0x11D968; // type:func\nsnd_SendIOPCommandNoWait = 0x11DB00; // type:func\nFUN_0011ddd8 = 0x11DDD8; // type:func\nsnd_SendCurrentBatch = 0x11DE18; // type:func\nFUN_0011df58 = 0x11DF58; // type:func\nsnd_StopAllStreams = 0x11E010; // type:func\nFUN_0011e048 = 0x11E048; // type:func\nFUN_0011e0b0 = 0x11E0B0; // type:func\nsnd_IsVAGStreamBuffered_CB = 0x11E0E0; // type:func\nsnd_StreamSafeCheckCDIdle = 0x11E110; // type:func\nsnd_StreamSafeCdRead = 0x11E138; // type:func\nsnd_StreamSafeCdSync = 0x11E1F8; // type:func\nsnd_StreamSafeCdBreak = 0x11E2A0; // type:func\nFUN_0011e2e8 = 0x11E2E8; // type:func\nFUN_0011e328 = 0x11E328; // type:func\nFUN_0011e360 = 0x11E360; // type:func\nFUN_0011e3a0 = 0x11E3A0; // type:func\nFUN_0011e428 = 0x11E428; // type:func\nsnd_ResetMovieSound = 0x11E460; // type:func\nsnd_CloseMovieSound = 0x11E498; // type:func\nFUN_0011e4c0 = 0x11E4C0; // type:func\nFUN_0011e4f8 = 0x11E4F8; // type:func\nsnd_GetDopplerPitchMod = 0x11E538; // type:func\nStartupBrx = 0x11E560; // type:func\nPloNew = 0x11E580; // type:func\nLoadOptionFromBrx = 0x11E680; // type:func\nLoadOptionsFromBrx = 0x11EC40; // type:func\nIploFromStockOid = 0x11ECA0; // type:func\nLoadSwObjectsFromBrx = 0x11ECB8; // type:func\nSetLoDefaults = 0x11EDA8; // type:func\nFindKey = 0x11EE70; // type:func\nLoadAcgbFromBrx = 0x11EFC8; // type:func\nFUN_0011f0c8 = 0x11F0C8; // type:func\nFUN_0011f180 = 0x11F180; // type:func\nLoadAcgbwFromBrx = 0x11F210; // type:func\nFUN_0011f320 = 0x11F320; // type:func\nFUN_0011f3e8 = 0x11F3E8; // type:func\nFUN_0011f478 = 0x11F478; // type:func\nLoadAcglFromBrx = 0x11F568; // type:func\nFUN_0011f620 = 0x11F620; // type:func\nEvaluateApacg = 0x11F6B0; // type:func\nLoadApacgFromBrx = 0x11F798; // type:func\nGetApacgTimes = 0x11F850; // type:func\nFUN_0011f9f8 = 0x11F9F8; // type:func\nLoadAkvbFromBrx = 0x11FA88; // type:func\nGetAkvbTimes = 0x11FB98; // type:func\nFUN_0011fc20 = 0x11FC20; // type:func\nLoadAcpcFromBrx = 0x11FC90; // type:func\nFUN_0011fdb8 = 0x11FDB8; // type:func\nFUN_0011fdd8 = 0x11FDD8; // type:func\nLoadAcpbFromBrx = 0x11FE40; // type:func\nFUN_0011fed8 = 0x11FED8; // type:func\nFUN_0011ff08 = 0x11FF08; // type:func\nLoadAcrcFromBrx = 0x11FFD8; // type:func\nFUN_00120110 = 0x120110; // type:func\nFUN_00120130 = 0x120130; // type:func\nFUN_001201d0 = 0x1201D0; // type:func\nLoadAcrbFromBrx = 0x1201F0; // type:func\nGetAcrbTimes = 0x1202C0; // type:func\nEvaluateAcsc = 0x1202F0; // type:func\nLoadAcscFromBrx = 0x120360; // type:func\nFUN_00120388 = 0x120388; // type:func\nFUN_001203a8 = 0x1203A8; // type:func\nLoadAcsbFromBrx = 0x120418; // type:func\nGetAcsbTimes = 0x120440; // type:func\nEvaluateAcpbl = 0x120470; // type:func\nEvaluateAcrbl = 0x120700; // type:func\nEvaluateAcgblt = 0x120AA8; // type:func\nEvaluateAcgblp = 0x120D58; // type:func\nFUN_00120fb0 = 0x120FB0; // type:func\nFUN_00121050 = 0x121050; // type:func\nFUN_001210f0 = 0x1210F0; // type:func\nPacgNew = 0x121160; // type:func\nFUN_00121228 = 0x121228; // type:func\nFUN_00121280 = 0x121280; // type:func\nFUN_001212d8 = 0x1212D8; // type:func\nInitAct = 0x121338; // type:func\nFUN_00121358 = 0x121358; // type:func\nGetActPositionGoal = 0x1214B8; // type:func\nGetActRotationGoal = 0x121508; // type:func\nFUN_00121568 = 0x121568; // type:func\nGetActScale = 0x121580; // type:func\nCalculateActDefaultAck = 0x1215C0; // type:func\nSnapAct = 0x121648; // type:func\nCalculateAloPositionSpring = 0x121760; // type:func\nProjectActPosition = 0x1218C0; // type:func\nCalculateAloRotationSpring = 0x121C48; // type:func\nProjectActRotation = 0x121DE0; // type:func\nProjectActPose = 0x122488; // type:func\nPredictAloPosition = 0x122550; // type:func\nFUN_001225d0 = 0x1225D0; // type:func\nAdaptAct = 0x1226D8; // type:func\nInitActval = 0x122708; // type:func\nGetActvalPositionGoal = 0x1227B0; // type:func\nGetActvalRotationGoal = 0x1227F0; // type:func\nInitActref = 0x122890; // type:func\nGetActrefPositionGoal = 0x122920; // type:func\nGetActrefRotationGoal = 0x122968; // type:func\nFUN_00122a18 = 0x122A18; // type:func\nFUN_00122a80 = 0x122A80; // type:func\nFUN_00122b30 = 0x122B30; // type:func\nFUN_00122c48 = 0x122C48; // type:func\nFUN_00122cb0 = 0x122CB0; // type:func\nFUN_00122da0 = 0x122DA0; // type:func\nFUN_00122de0 = 0x122DE0; // type:func\nFUN_00122f28 = 0x122F28; // type:func\nFUN_00122f88 = 0x122F88; // type:func\nFUN_00122fe0 = 0x122FE0; // type:func\nFUN_00123120 = 0x123120; // type:func\nFUN_00123270 = 0x123270; // type:func\nFUN_001232e8 = 0x1232E8; // type:func\nGGetActsegPoseGoal = 0x123358; // type:func\nBreakAlbrk = 0x1233C0; // type:func\nSetAlbrkAlarm = 0x123400; // type:func\nInitAlarm = 0x123408; // type:func\nPostAlarmLoad = 0x123448; // type:func\nCloneAlarm = 0x123540; // type:func\nUpdateAlarm = 0x123578; // type:func\nPostAlarmLoadCallbackHookup = 0x1236C8; // type:func\nSetAlarmAlarms = 0x123888; // type:func\nTriggerAlarm = 0x123AB0; // type:func\nDisableAlarmAlbrk = 0x123B18; // type:func\nEnableAlarmSensors = 0x123B28; // type:func\nDisableAlarmSensors = 0x123BB0; // type:func\nNotifyAlarmSensorsOnTrigger = 0x123C20; // type:func\nSetAlarmRsmg = 0x123D08; // type:func\nFGetAlarmSensorList = 0x123D40; // type:func\nFIsZeroV = 0x123DC0; // type:func\nFIsZeroW = 0x123E00; // type:func\nFIsZeroDv = 0x123E48; // type:func\nFIsZeroDw = 0x123E88; // type:func\nInitAlo = 0x123ED0; // type:func\nAddAloHierarchy = 0x124050; // type:func\nOnAloAdd = 0x1240F8; // type:func\nRemoveAloHierarchy = 0x124338; // type:func\nOnAloRemove = 0x1243E0; // type:func\nUpdateAloOrig = 0x124540; // type:func\nSetAloParent = 0x1245A8; // type:func\nApplyAloProxy = 0x124868; // type:func\nBindAlo = 0x1249A8; // type:func\nPostAloLoad = 0x124A48; // type:func\nPostAloLoadCallback = 0x124CC0; // type:func\nSnipAloObjects = 0x124DF8; // type:func\nUpdateAloHierarchy = 0x124EE8; // type:func\nUpdateAlo = 0x124FC0; // type:func\nInvalidateAloLighting = 0x1250C8; // type:func\nUpdateAloXfWorld = 0x125108; // type:func\nUpdateAloXfWorldHierarchy = 0x125138; // type:func\nupdate_entity_position = 0x125440; // type:func\nFUN_00125750 = 0x125750; // type:func\nFUN_001259d8 = 0x1259D8; // type:func\nDupAloRo = 0x125B70; // type:func\nFUN_00125bf0 = 0x125BF0; // type:func\nFUN_00125c90 = 0x125C90; // type:func\nRenderAloSelf = 0x1261C0; // type:func\nFUN_00126270 = 0x126270; // type:func\nRenderAloLine = 0x1268B8; // type:func\nFUN_00126a48 = 0x126A48; // type:func\nUpdateAloThrob = 0x126AC8; // type:func\nFUN_00126bc0 = 0x126BC0; // type:func\nFUN_00126c58 = 0x126C58; // type:func\nFUN_00126cb8 = 0x126CB8; // type:func\nFUN_00126d60 = 0x126D60; // type:func\nFUN_00126de8 = 0x126DE8; // type:func\nCloneAloHeirarchy = 0x126F78; // type:func\nCloneLockg = 0x127048; // type:func\nHandleAloMessage = 0x127378; // type:func\nFUN_001273f0 = 0x1273F0; // type:func\nFUN_001274f8 = 0x1274F8; // type:func\nFUN_00127558 = 0x127558; // type:func\nFUN_00127590 = 0x127590; // type:func\nFUN_001275f0 = 0x1275F0; // type:func\nSetAloVelocityLocal = 0x127628; // type:func\nGetAloVelocityLocal = 0x127678; // type:func\nFUN_001276c0 = 0x1276C0; // type:func\nCalculateAloMovement = 0x1278A8; // type:func\nFUN_00127b20 = 0x127B20; // type:func\nFUN_00127e60 = 0x127E60; // type:func\nConvertAloPos = 0x128018; // type:func\nConvertAloVec = 0x1280C0; // type:func\nConvertAloMat = 0x128150; // type:func\nFDrivenAlo = 0x128230; // type:func\nRetractAloDrive = 0x128278; // type:func\nConvertAloMovement = 0x128330; // type:func\nCalculateAloDrive = 0x128598; // type:func\nFUN_001288f0 = 0x1288F0; // type:func\nFUN_00128998 = 0x128998; // type:func\nLoadAloFromBrx = 0x1289C0; // type:func\nLoadAloAloxFromBrx = 0x128C10; // type:func\nBindAloAlox = 0x128DB8; // type:func\nUnadjustAloRotation = 0x128FD0; // type:func\nFUN_00129108 = 0x129108; // type:func\nFUN_001291d0 = 0x1291D0; // type:func\nFUN_00129228 = 0x129228; // type:func\nFUN_00129288 = 0x129288; // type:func\nFUN_001292b8 = 0x1292B8; // type:func\nFUN_001292e8 = 0x1292E8; // type:func\nFUN_00129318 = 0x129318; // type:func\nFUN_00129348 = 0x129348; // type:func\nFUN_00129378 = 0x129378; // type:func\nFUN_001293a8 = 0x1293A8; // type:func\nFUN_001293d8 = 0x1293D8; // type:func\nFUN_00129400 = 0x129400; // type:func\nFUN_00129480 = 0x129480; // type:func\nFUN_001294b0 = 0x1294B0; // type:func\nFUN_001294e0 = 0x1294E0; // type:func\nFUN_00129510 = 0x129510; // type:func\nFUN_00129540 = 0x129540; // type:func\nFUN_00129598 = 0x129598; // type:func\nFUN_001295c8 = 0x1295C8; // type:func\nFUN_00129648 = 0x129648; // type:func\nFUN_001296e0 = 0x1296E0; // type:func\nFUN_00129730 = 0x129730; // type:func\nRecacheAloActList = 0x129780; // type:func\nFUN_001299e0 = 0x1299E0; // type:func\nResortAloActList = 0x129A58; // type:func\nFUN_00129b98 = 0x129B98; // type:func\nFUN_00129c20 = 0x129C20; // type:func\nPasegaFindAloNearest = 0x129CA8; // type:func\nFUN_00129d00 = 0x129D00; // type:func\nFIsAloStatic = 0x129D70; // type:func\nResolveAlo = 0x129DF8; // type:func\nFUN_00129e10 = 0x129E10; // type:func\nFUN_00129e88 = 0x129E88; // type:func\nFUN_00129ee0 = 0x129EE0; // type:func\nFUN_00129f58 = 0x129F58; // type:func\nFUN_00129fb0 = 0x129FB0; // type:func\nFUN_0012a028 = 0x12A028; // type:func\nFUN_0012a080 = 0x12A080; // type:func\nFUN_0012a0f8 = 0x12A0F8; // type:func\nFUN_0012a150 = 0x12A150; // type:func\nFUN_0012a1a0 = 0x12A1A0; // type:func\nFUN_0012a200 = 0x12A200; // type:func\nFUN_0012a270 = 0x12A270; // type:func\nFUN_0012a2c0 = 0x12A2C0; // type:func\nFUN_0012a320 = 0x12A320; // type:func\nFUN_0012a3c8 = 0x12A3C8; // type:func\nFUN_0012a3e8 = 0x12A3E8; // type:func\nFUN_0012a430 = 0x12A430; // type:func\nFUN_0012a4a0 = 0x12A4A0; // type:func\nFUN_0012a4e8 = 0x12A4E8; // type:func\nFUN_0012a528 = 0x12A528; // type:func\nFUN_0012a580 = 0x12A580; // type:func\nFUN_0012a5d0 = 0x12A5D0; // type:func\nFUN_0012a630 = 0x12A630; // type:func\nFUN_0012a6a0 = 0x12A6A0; // type:func\nFUN_0012a700 = 0x12A700; // type:func\nFUN_0012a770 = 0x12A770; // type:func\nFUN_0012a7c0 = 0x12A7C0; // type:func\nFUN_0012a810 = 0x12A810; // type:func\nFUN_0012a860 = 0x12A860; // type:func\nFUN_0012a888 = 0x12A888; // type:func\nFUN_0012a8b8 = 0x12A8B8; // type:func\nFUN_0012a8c8 = 0x12A8C8; // type:func\nFUN_0012a8d8 = 0x12A8D8; // type:func\nFUN_0012a970 = 0x12A970; // type:func\nFUN_0012a9c8 = 0x12A9C8; // type:func\nFUN_0012aa00 = 0x12AA00; // type:func\nSetAloTargetHitTest = 0x12AA28; // type:func\nFUN_0012aa50 = 0x12AA50; // type:func\nSetAloEyesClosed = 0x12AAE8; // type:func\nFUN_0012aba8 = 0x12ABA8; // type:func\nFUN_0012abd0 = 0x12ABD0; // type:func\nFUN_0012ac08 = 0x12AC08; // type:func\nFUN_0012aca0 = 0x12ACA0; // type:func\nFUN_0012acf8 = 0x12ACF8; // type:func\nFUN_0012ad30 = 0x12AD30; // type:func\nFUN_0012ad98 = 0x12AD98; // type:func\nFUN_0012add0 = 0x12ADD0; // type:func\nFUN_0012ae20 = 0x12AE20; // type:func\nFUN_0012ae78 = 0x12AE78; // type:func\nFUN_0012aeb0 = 0x12AEB0; // type:func\nFUN_0012af38 = 0x12AF38; // type:func\nFUN_0012b010 = 0x12B010; // type:func\nEnsureAloThrob = 0x12B040; // type:func\nFUN_0012b0b0 = 0x12B0B0; // type:func\nFUN_0012b140 = 0x12B140; // type:func\nFUN_0012b1a0 = 0x12B1A0; // type:func\nFUN_0012b200 = 0x12B200; // type:func\nSetAloPoseCombo = 0x12B2F8; // type:func\nSetAloForceCameraFade = 0x12B420; // type:func\nSetAloRealClock = 0x12B4C8; // type:func\nFUN_0012b5b8 = 0x12B5B8; // type:func\ncheck_anticrack_firewall = 0x12B760; // type:func\nFUN_0012b868 = 0x12B868; // type:func\nFUN_0012b870 = 0x12B870; // type:func\nLoadAsegFromBrx = 0x12B8C8; // type:func\nLoadAsegEventsFromBrx = 0x12BC38; // type:func\nFUN_0012c140 = 0x12C140; // type:func\nFUN_0012c160 = 0x12C160; // type:func\nFUN_0012c208 = 0x12C208; // type:func\nApplyAsegOvr = 0x12C288; // type:func\nApplyAsegQMARK = 0x12C7B0; // type:func\nFUN_0012c7d8 = 0x12C7D8; // type:func\nFUN_0012c808 = 0x12C808; // type:func\nFUN_0012c840 = 0x12C840; // type:func\nPasegaEnsureAseg = 0x12C8F8; // type:func\nFUN_0012c918 = 0x12C918; // type:func\nFWipingAseg = 0x12C9A8; // type:func\nFindAsegClosestPoint = 0x12C9E8; // type:func\nPeaFindAsegLabel = 0x12CBE8; // type:func\nFUN_0012ccc0 = 0x12CCC0; // type:func\nFUN_0012cce8 = 0x12CCE8; // type:func\nFUN_0012cd78 = 0x12CD78; // type:func\nFUN_0012d1b0 = 0x12D1B0; // type:func\nFUN_0012d2a8 = 0x12D2A8; // type:func\nFUN_0012d398 = 0x12D398; // type:func\nFUN_0012d3f8 = 0x12D3F8; // type:func\nSetAsegaHandsOff = 0x12D448; // type:func\nUpdateAsegaIeaCur = 0x12D4A8; // type:func\nFUN_0012d570 = 0x12D570; // type:func\nHandleAsegaEvent = 0x12D5D0; // type:func\nHandleAsegaEventsFF = 0x12E4E0; // type:func\nHandleAsegaEvents = 0x12E5D0; // type:func\nRemoveAsega = 0x12E710; // type:func\nRetractAsega = 0x12E760; // type:func\nFUN_0012e928 = 0x12E928; // type:func\nUFromEaErrorFunc = 0x12E968; // type:func\nFWrapAsegaTime = 0x12E9E0; // type:func\nUpdateAsega = 0x12EBD8; // type:func\nFUN_0012f0a0 = 0x12F0A0; // type:func\nFUN_0012f190 = 0x12F190; // type:func\nAdaptAsega = 0x12F1D8; // type:func\nFindChnClosestPointLocal = 0x12F210; // type:func\nSetAsegaSpeed = 0x12F6B0; // type:func\nFUN_0012f6d0 = 0x12F6D0; // type:func\nFUN_0012f718 = 0x12F718; // type:func\nSendAsegaMessage = 0x12F760; // type:func\nFUN_0012f7e0 = 0x12F7E0; // type:func\nFUN_0012f810 = 0x12F810; // type:func\nFUN_0012f840 = 0x12F840; // type:func\nFUN_0012f888 = 0x12F888; // type:func\nPostBarrierLoad = 0x12F8C8; // type:func\nFUN_0012f9b8 = 0x12F9B8; // type:func\nFIgnoreBarrierIntersection = 0x12FA88; // type:func\nFUN_0012fb68 = 0x12FB68; // type:func\nCBinaryAsyncStream__CBinaryAsyncStream = 0x12FCF0; // type:func\nCBinaryAsyncStream__~CBinaryAsyncStream = 0x12FD30; // type:func\nFUN_0012fd78 = 0x12FD78; // type:func\nFUN_0012fda0 = 0x12FDA0; // type:func\nCBinaryAsyncStream__Close = 0x12FDE8; // type:func\nCBinaryAsyncStream__StartSpooling = 0x12FE70; // type:func\nCBinaryAsyncStream__FSpooling = 0x12FF10; // type:func\nCBinaryAsyncStream__FSpoolingComplete = 0x12FF20; // type:func\nFUN_0012ffe8 = 0x12FFE8; // type:func\nFUN_00130070 = 0x130070; // type:func\nCBinaryAsyncStream__Skip = 0x1300D8; // type:func\nFIsBasicDerivedFrom = 0x1300E8; // type:func\nFUN_00130110 = 0x130110; // type:func\nEvaluateBezierWeightedFloat = 0x130168; // type:func\nEvaluateBezierFloat = 0x1303F0; // type:func\nEvaluateBezierPos = 0x130540; // type:func\nEvaluateBezierMat = 0x130748; // type:func\nFUN_00130b48 = 0x130B48; // type:func\nFUN_00130c20 = 0x130C20; // type:func\nLimitBezierMulti = 0x130C58; // type:func\nInitBei = 0x130F48; // type:func\nGEvaluateBei = 0x131000; // type:func\nFUN_001310f0 = 0x1310F0; // type:func\nFUN_00131140 = 0x131140; // type:func\nFUN_00131198 = 0x131198; // type:func\nDrawBinocCompass = 0x1316E8; // type:func\nDrawBinocZoom = 0x131F60; // type:func\nDrawBinocReticle = 0x132500; // type:func\nDrawBinocOutline = 0x133B58; // type:func\nFUN_00134aa0 = 0x134AA0; // type:func\nFUN_00134b48 = 0x134B48; // type:func\nDrawBinocFilter = 0x135228; // type:func\nFUN_00135550 = 0x135550; // type:func\nopen_close_binoc = 0x1356C0; // type:func\nFUN_001357f0 = 0x1357F0; // type:func\nFUN_00135858 = 0x135858; // type:func\nFUN_001358d0 = 0x1358D0; // type:func\nSetBinocBfk = 0x135E78; // type:func\nFUN_00135f48 = 0x135F48; // type:func\nFUN_00136040 = 0x136040; // type:func\nFUN_00136238 = 0x136238; // type:func\nFUN_001363d0 = 0x1363D0; // type:func\nSetBinocAchzDraw = 0x136408; // type:func\nFDoneBinocAchz = 0x136530; // type:func\nSetBinocLookat = 0x1365A0; // type:func\nSetBinocZoom = 0x1365A8; // type:func\nFUN_001365f0 = 0x1365F0; // type:func\nFUN_00136648 = 0x136648; // type:func\nDrawBinoc = 0x1366A0; // type:func\nGetBinocReticleFocus = 0x136EC8; // type:func\nFUN_00136ef8 = 0x136EF8; // type:func\nFUN_00136fa8 = 0x136FA8; // type:func\n__static_initialization_and_destruction_0 = 0x136FE8; // type:func\nCTextBox__SetPos = 0x137228; // type:func\nCTextBox__SetSize = 0x137238; // type:func\nCTextBox__SetTextColor = 0x137248; // type:func\nCTextBox__SetHorizontalJust = 0x137260; // type:func\nCTextBox__SetVerticalJust = 0x137268; // type:func\n_GLOBAL_$I$InitBei__FP3BEIP3CLQffi = 0x137270; // type:func\nCBinaryInputStream = 0x137290; // type:func\nCBinaryInputStream__~CBinaryInputStream = 0x1372E0; // type:func\nCBinaryInputStream__FOpenSector = 0x137328; // type:func\nCBinaryInputStream__OpenMemory = 0x137398; // type:func\nCBinaryInputStream__FOpenFile = 0x1373B0; // type:func\nCBinaryInputStream__Close = 0x1373D0; // type:func\nCBinaryInputStream__DecrementCdReadLimit = 0x137480; // type:func\nCBinaryInputStream__PumpCd = 0x137490; // type:func\nFUN_001377c0 = 0x1377C0; // type:func\nCBinaryInputStream__Pump = 0x137820; // type:func\ndecompress_impl = 0x1378A0; // type:func\nCBinaryInputStream__Read = 0x137A60; // type:func\nCBinaryInputStream__Align = 0x137B60; // type:func\nU8Read = 0x137B90; // type:func\nCBinaryInputStream__U16Read = 0x137BE0; // type:func\nCBinaryInputStream__U32Read = 0x137C40; // type:func\nS8Read = 0x137CC0; // type:func\nCBinaryInputStream__S16Read = 0x137D10; // type:func\nCBinaryInputStream__S32Read = 0x137D78; // type:func\nCBinaryInputStream__F32Read = 0x137DF8; // type:func\nCBinaryInputStream__ReadVector = 0x137E70; // type:func\nCBinaryInputStream__ReadVector4 = 0x137E90; // type:func\nCBinaryInputStream__ReadMatrix = 0x137EB0; // type:func\nCBinaryInputStream__ReadMatrix4 = 0x137F08; // type:func\nCBinaryInputStream__ReadGeom = 0x137FB0; // type:func\nCBinaryInputStream__ReadBspc = 0x138278; // type:func\nCBinaryInputStream__ReadVbsp = 0x138398; // type:func\nReadStringSw = 0x1384A0; // type:func\nLoadUnknown0FromBrx = 0x138518; // type:func\nLoadUnknown1FromBrx = 0x138550; // type:func\nUpdateSwPox = 0x1385A0; // type:func\nPoxAddSw = 0x138738; // type:func\nFUN_00138788 = 0x138788; // type:func\nPoxFromSoSo = 0x1387C0; // type:func\nFUN_001387f8 = 0x1387F8; // type:func\nFUN_00138828 = 0x138828; // type:func\nFUN_001388a0 = 0x1388A0; // type:func\nFUN_001389c8 = 0x1389C8; // type:func\nFUN_001389d0 = 0x1389D0; // type:func\nInvalidateSwXpForObject = 0x138BE0; // type:func\nRecalcSwXpAll = 0x138C00; // type:func\nRecalcSwOxfFilterForObject = 0x138F28; // type:func\nVerifyAeaEquivalence = 0x138FF0; // type:func\nEnsureAsegBlendDynamic = 0x139038; // type:func\nFillBlAmrsg = 0x139600; // type:func\nCalculateBlendAmrsg = 0x139740; // type:func\nFUN_00139970 = 0x139970; // type:func\nReblendAsegbl = 0x1399F8; // type:func\nFUN_00139b38 = 0x139B38; // type:func\nBuildBlipAqwGifs = 0x139B70; // type:func\nStartupBlips = 0x139C38; // type:func\nFUN_00139c70 = 0x139C70; // type:func\nFUN_00139d28 = 0x139D28; // type:func\nFUN_00139d68 = 0x139D68; // type:func\nFUN_00139de8 = 0x139DE8; // type:func\nFUN_00139e80 = 0x139E80; // type:func\nFUN_00139ec8 = 0x139EC8; // type:func\nSetBlipgShader = 0x139F80; // type:func\nFUN_0013a008 = 0x13A008; // type:func\nSetBlipgEmitb = 0x13A128; // type:func\nUpdateBlipg = 0x13A3A0; // type:func\nFUN_0013a418 = 0x13A418; // type:func\nCblipeProjectBlipTransformAccel = 0x13A498; // type:func\nProjectBlipgTransformAccel = 0x13A618; // type:func\nProjectBlipgTransform = 0x13A940; // type:func\nRenderBlipgSelf = 0x13AD08; // type:func\nFUN_0013ad80 = 0x13AD80; // type:func\nFUN_0013b430 = 0x13B430; // type:func\nInitBomb = 0x13B4C0; // type:func\nLoadBombFromBrx = 0x13B598; // type:func\nFUN_0013b5c8 = 0x13B5C8; // type:func\nFUN_0013b610 = 0x13B610; // type:func\nFUN_0013b708 = 0x13B708; // type:func\nFUN_0013b778 = 0x13B778; // type:func\nFUN_0013b828 = 0x13B828; // type:func\nFUN_0013b9d8 = 0x13B9D8; // type:func\nFUN_0013ba70 = 0x13BA70; // type:func\nFUN_0013bba0 = 0x13BBA0; // type:func\nFUN_0013bc80 = 0x13BC80; // type:func\nFUN_0013be00 = 0x13BE00; // type:func\nFUN_0013be18 = 0x13BE18; // type:func\nFUN_0013bf68 = 0x13BF68; // type:func\nFUN_0013c950 = 0x13C950; // type:func\nFUN_0013c988 = 0x13C988; // type:func\nCByteQueue__Reset = 0x13C9B0; // type:func\nFUN_0013c9d0 = 0x13C9D0; // type:func\nCByteQueue__CbDrain = 0x13CAD8; // type:func\nFUN_0013cc00 = 0x13CC00; // type:func\nCByteQueue__FreeDrain = 0x13CC48; // type:func\nCQueueInputMemory__CbRead = 0x13CC80; // type:func\nInitBrk = 0x13CCF8; // type:func\nLoadBrkFromBrx = 0x13CD80; // type:func\nCloneBrk = 0x13CDE8; // type:func\nFUN_0013ce40 = 0x13CE40; // type:func\nFUN_0013ce80 = 0x13CE80; // type:func\nUpdateBrk = 0x13D068; // type:func\nFUN_0013d0b0 = 0x13D0B0; // type:func\nBreakBrk = 0x13D278; // type:func\nFUN_0013d820 = 0x13D820; // type:func\nFUN_0013daf0 = 0x13DAF0; // type:func\nFUN_0013db28 = 0x13DB28; // type:func\nFUN_0013dc38 = 0x13DC38; // type:func\nFUN_0013dca8 = 0x13DCA8; // type:func\nFUN_0013dd08 = 0x13DD08; // type:func\nFUN_0013dd78 = 0x13DD78; // type:func\nFUN_0013ddb8 = 0x13DDB8; // type:func\nFUN_0013ddf0 = 0x13DDF0; // type:func\nFUN_0013de38 = 0x13DE38; // type:func\nFUN_0013dee8 = 0x13DEE8; // type:func\nUpdateZapbreak = 0x13DF68; // type:func\nFUN_0013dfd8 = 0x13DFD8; // type:func\nPruneBsp = 0x13E430; // type:func\nPbspPointInBspQuick = 0x13E658; // type:func\nFUN_0013e6c8 = 0x13E6C8; // type:func\nFUN_0013e7c0 = 0x13E7C0; // type:func\nFUN_0013e868 = 0x13E868; // type:func\nFAddAshAseg = 0x13E8D8; // type:func\nFAddAshOid = 0x13E8F8; // type:func\nInitBtn = 0x13E918; // type:func\nLoadBtn = 0x13E950; // type:func\nPostBtnLoad = 0x13EA38; // type:func\nRestoreBtnFromCheckpointCallback = 0x13EAE0; // type:func\nSetBtnRsmg = 0x13EB30; // type:func\nSetBtnButtons = 0x13EB68; // type:func\nFAddRsmg = 0x13EC00; // type:func\nTriggerRsmg = 0x13ECB0; // type:func\nRunBtnAsegs = 0x13ED90; // type:func\nTriggerBtn = 0x13EF50; // type:func\nUntriggerBtn = 0x13F070; // type:func\nInitButton = 0x13F0E0; // type:func\nLoadButtonFromBrx = 0x13F110; // type:func\nFUN_0013f140 = 0x13F140; // type:func\nFUN_0013f1d8 = 0x13F1D8; // type:func\nFUN_0013f290 = 0x13F290; // type:func\nFUN_0013f6c0 = 0x13F6C0; // type:func\nSetButtonButtons = 0x13F6F8; // type:func\nFUN_0013f718 = 0x13F718; // type:func\nIposFindButtonClosest = 0x13F8A0; // type:func\nFUN_0013f940 = 0x13F940; // type:func\nPresetButtonAccel = 0x13FA10; // type:func\nUpdateButtonInternalXps = 0x13FAE8; // type:func\nUpdateButton = 0x13FD20; // type:func\nFAbsorbButtonWkr = 0x140028; // type:func\nFUN_001400a8 = 0x1400A8; // type:func\nLoadVolbtnFromBrx = 0x140100; // type:func\nFUN_00140140 = 0x140140; // type:func\nFUN_00140200 = 0x140200; // type:func\nSetVolbtnButtons = 0x140238; // type:func\nUpdateVolbtn = 0x140258; // type:func\nFUN_00140550 = 0x140550; // type:func\nFUN_001405d0 = 0x1405D0; // type:func\nFUN_00140640 = 0x140640; // type:func\nAddAlarmStepguard = 0x140688; // type:func\nFUN_00140750 = 0x140750; // type:func\nFUN_00140770 = 0x140770; // type:func\nCSpliceVarAccessor__PvVarOwner = 0x1407A0; // type:func\nCpchzTokenizePath = 0x1407A8; // type:func\nFUN_00140968 = 0x140968; // type:func\nFUN_001409a8 = 0x1409A8; // type:func\nUpdateCd = 0x1409E0; // type:func\nCdPath = 0x140B60; // type:func\nFUN_00140c28 = 0x140C28; // type:func\ncalls_sceCdRead = 0x140CC8; // type:func\nFUN_00140d68 = 0x140D68; // type:func\nResetChkmgrCheckpoints = 0x140D90; // type:func\nSaveChkmgrCheckpoint = 0x140E10; // type:func\nReturnChkmgrToCheckpoint = 0x140ED0; // type:func\nRestoreChkmgrFromCheckpoint = 0x140F48; // type:func\nIchkAllocChkmgr = 0x140FF8; // type:func\nFGetChkmgrIchk = 0x141008; // type:func\nSetChkmgrIchk = 0x141040; // type:func\nClearChkmgrIchk = 0x1410A0; // type:func\nLoadVolFromBrx = 0x141108; // type:func\nFCheckVolPoint = 0x141170; // type:func\nInitChkpnt = 0x1411A8; // type:func\nLoadChkpntFromBrx = 0x141210; // type:func\nBindChkpnt = 0x141338; // type:func\nFUN_00141438 = 0x141438; // type:func\nFUN_001415d0 = 0x1415D0; // type:func\nFUN_00141690 = 0x141690; // type:func\nFUN_001417f0 = 0x1417F0; // type:func\nFUN_00141870 = 0x141870; // type:func\nPsoHitTestLineObjects = 0x1419E8; // type:func\nFUN_00141b48 = 0x141B48; // type:func\nClsgClipEdgeToObject = 0x141C28; // type:func\nClsgClipEdgeToObjectPruned = 0x141C90; // type:func\nClsgClipCylinderToObject = 0x141D00; // type:func\nClsgClipLineToSphere = 0x141D88; // type:func\nClsgClipEdgeToSphere = 0x141F48; // type:func\nFUN_00142170 = 0x142170; // type:func\nClsgClipEdgeToCylinder = 0x142278; // type:func\nClsgMergeAlsg = 0x1429F8; // type:func\nFUN_00142b78 = 0x142B78; // type:func\nSetClockRate = 0x142ED0; // type:func\nMarkClockTick = 0x142F10; // type:func\nMarkClockTickRealOnly = 0x143030; // type:func\nResetClock = 0x1430B8; // type:func\nSetClockEnabled = 0x1430C0; // type:func\nStartupClock = 0x1430C8; // type:func\nTickNow = 0x1430F8; // type:func\nCalcCmAdjust = 0x143148; // type:func\nSpringCm = 0x143180; // type:func\nAdjustCmCpdefi = 0x143208; // type:func\nFUN_001433e0 = 0x1433E0; // type:func\nFUN_00143418 = 0x143418; // type:func\nFUN_001434c8 = 0x1434C8; // type:func\nFUN_00143560 = 0x143560; // type:func\nInitCm = 0x143648; // type:func\nSetSwCameraFov = 0x1437C0; // type:func\nFUN_001437e8 = 0x1437E8; // type:func\nFUN_00143810 = 0x143810; // type:func\nFUN_00143838 = 0x143838; // type:func\nFUN_00143860 = 0x143860; // type:func\nFUN_00143888 = 0x143888; // type:func\nFUN_001438b0 = 0x1438B0; // type:func\nFUN_001438d8 = 0x1438D8; // type:func\nFUN_00143900 = 0x143900; // type:func\nFUN_00143920 = 0x143920; // type:func\nFUN_00143940 = 0x143940; // type:func\nFUN_00143968 = 0x143968; // type:func\nFUN_00143988 = 0x143988; // type:func\nFUN_001439a8 = 0x1439A8; // type:func\nFUN_001439c8 = 0x1439C8; // type:func\nFUN_001439e8 = 0x1439E8; // type:func\nFUN_00143a08 = 0x143A08; // type:func\nFUN_00143a38 = 0x143A38; // type:func\nResetCm = 0x143A60; // type:func\nClearCmFadeObjects = 0x143AF0; // type:func\nAddCmFadeObject = 0x143AF8; // type:func\nRemoveCmFadeObject = 0x143B20; // type:func\nUpdateCmFade = 0x143BE0; // type:func\nUpdateCmLast = 0x143E40; // type:func\nSetupCmRotateToCam = 0x144008; // type:func\nConvertCmScreenToWorld = 0x144128; // type:func\nConvertCmWorldToScreen = 0x1441C0; // type:func\nSetupCm = 0x144270; // type:func\nCombineEyeLookAtProj = 0x1442C8; // type:func\nBuildFrustrum = 0x1443C8; // type:func\nUpdateCmMat4 = 0x144540; // type:func\nFUN_00144848 = 0x144848; // type:func\nFUN_001448c8 = 0x1448C8; // type:func\nFUN_00144938 = 0x144938; // type:func\nFUN_00144978 = 0x144978; // type:func\nFUN_00144aa0 = 0x144AA0; // type:func\nFUN_00144b70 = 0x144B70; // type:func\nFUN_00144be8 = 0x144BE8; // type:func\nAdjustCmJoy = 0x144FF8; // type:func\nSetCmPolicy = 0x145088; // type:func\nRevokeCmPolicy = 0x1451F0; // type:func\nFUN_001453b0 = 0x1453B0; // type:func\nDecomposeCylind = 0x145438; // type:func\nDecomposeSphere = 0x1454E0; // type:func\nSetCmCut = 0x1455C0; // type:func\nFUN_001455e0 = 0x1455E0; // type:func\nFUN_001455f0 = 0x1455F0; // type:func\nFUN_00145610 = 0x145610; // type:func\nSetCm = 0x145718; // type:func\nPsoEnemyStepguard = 0x145810; // type:func\nFUN_00145950 = 0x145950; // type:func\nFUN_00145b68 = 0x145B68; // type:func\nFUN_00145de8 = 0x145DE8; // type:func\nFUN_00145e68 = 0x145E68; // type:func\nFUN_00145fb8 = 0x145FB8; // type:func\nFUN_00145fd8 = 0x145FD8; // type:func\nFUN_00145ff8 = 0x145FF8; // type:func\nFUN_00146018 = 0x146018; // type:func\nFUN_00146028 = 0x146028; // type:func\nFUN_00146038 = 0x146038; // type:func\nFUN_001460b8 = 0x1460B8; // type:func\nFUN_001460e0 = 0x1460E0; // type:func\nInitCnvo = 0x146100; // type:func\nLoadCnvoFromBrx = 0x146130; // type:func\nPostCnvoLoad = 0x146178; // type:func\nFUN_00146240 = 0x146240; // type:func\nMatchCnvoScrollerToBeltSpeed = 0x146298; // type:func\nFUN_00146340 = 0x146340; // type:func\nLoadDprizeFromBrx = 0x1463C0; // type:func\nFUN_00146418 = 0x146418; // type:func\nFUN_00146470 = 0x146470; // type:func\nFUN_00146518 = 0x146518; // type:func\nFFilterDprizeObjects = 0x146D10; // type:func\nFUN_00146db0 = 0x146DB0; // type:func\nFUN_001471b0 = 0x1471B0; // type:func\nFUN_001473e0 = 0x1473E0; // type:func\nget_charmQMARK = 0x147428; // type:func\nFUN_001478f0 = 0x1478F0; // type:func\nSetDprizeDprizes = 0x147AB0; // type:func\nFUN_00147e40 = 0x147E40; // type:func\nFUN_00147ed0 = 0x147ED0; // type:func\nFUN_00147ef8 = 0x147EF8; // type:func\nFUN_00147fb0 = 0x147FB0; // type:func\nincrement_charm_count = 0x148038; // type:func\nAddLife = 0x148178; // type:func\nOnCoinSmack = 0x1481A0; // type:func\nSetCoinDprizes = 0x148298; // type:func\nFUN_00148400 = 0x148400; // type:func\nSetCharmDprizes = 0x148470; // type:func\nFUN_00148510 = 0x148510; // type:func\nSetKeyDprizes = 0x148598; // type:func\nFUN_00148698 = 0x148698; // type:func\nFUN_00148718 = 0x148718; // type:func\nFUN_00148748 = 0x148748; // type:func\nFUN_00148770 = 0x148770; // type:func\nFUN_00148828 = 0x148828; // type:func\nFUN_00148888 = 0x148888; // type:func\nFUN_00148938 = 0x148938; // type:func\nCpdprizeAttractSwDprizes = 0x148AC0; // type:func\nRemoveSwExtraneousCharms = 0x148CE0; // type:func\nFUN_00148d90 = 0x148D90; // type:func\nFUN_00148e18 = 0x148E18; // type:func\nFUN_00148e40 = 0x148E40; // type:func\nFUN_00148ef8 = 0x148EF8; // type:func\nincrement_and_show_life_count = 0x148F80; // type:func\nCollectLifeTkn = 0x148FF0; // type:func\nFUN_00149168 = 0x149168; // type:func\nbreak_bottleQMARK = 0x149190; // type:func\nInitCplcy = 0x149398; // type:func\nFUN_001493a0 = 0x1493A0; // type:func\nSetCpmanCpmt = 0x1493B8; // type:func\nPosCplookAnchor = 0x1493C8; // type:func\nFUN_00149458 = 0x149458; // type:func\nplays_binoc_sfx = 0x149508; // type:func\nPushCplookLookk = 0x1495E8; // type:func\nLookkPopCplook = 0x149610; // type:func\nLookkCurCplook = 0x149638; // type:func\nInitCplookQMARK = 0x149660; // type:func\nFUN_001496c0 = 0x1496C0; // type:func\nUpdateCplook = 0x149760; // type:func\nFUN_0014a7b8 = 0x14A7B8; // type:func\nInitCpalign = 0x14A888; // type:func\nFUN_0014a8d0 = 0x14A8D0; // type:func\nUpdateCpalign = 0x14A8F8; // type:func\nUpdateCpaseg = 0x14AAA0; // type:func\nInitCredit = 0x14ABD0; // type:func\nPostCreditLoad = 0x14AC48; // type:func\nFUN_0014ad00 = 0x14AD00; // type:func\nFUN_0014ad70 = 0x14AD70; // type:func\nFUN_0014ade0 = 0x14ADE0; // type:func\nFUN_0014aea0 = 0x14AEA0; // type:func\nFUN_0014af10 = 0x14AF10; // type:func\nSetCreditLine = 0x14AF38; // type:func\nCroutDecomp = 0x14B0C0; // type:func\nCroutSolve = 0x14B3E0; // type:func\nFUN_0014b550 = 0x14B550; // type:func\nFUN_0014b588 = 0x14B588; // type:func\nFUN_0014b5c0 = 0x14B5C0; // type:func\nFUN_0014b608 = 0x14B608; // type:func\nFUN_0014b640 = 0x14B640; // type:func\nFUN_0014b678 = 0x14B678; // type:func\nFUN_0014b6a8 = 0x14B6A8; // type:func\nFUN_0014bb08 = 0x14BB08; // type:func\nFUN_0014bce8 = 0x14BCE8; // type:func\nFUN_0014bd38 = 0x14BD38; // type:func\nSgsNextCrfodkAI = 0x14BDC8; // type:func\nFUN_0014bea8 = 0x14BEA8; // type:func\nFUN_0014bef8 = 0x14BEF8; // type:func\nFUN_0014bf88 = 0x14BF88; // type:func\nFUN_0014c018 = 0x14C018; // type:func\nFUN_0014c138 = 0x14C138; // type:func\nFUN_0014c2f0 = 0x14C2F0; // type:func\nFUN_0014c5e8 = 0x14C5E8; // type:func\nFUN_0014c668 = 0x14C668; // type:func\nFUN_0014c6e0 = 0x14C6E0; // type:func\nFUN_0014c788 = 0x14C788; // type:func\nFUN_0014c858 = 0x14C858; // type:func\nFUN_0014cba8 = 0x14CBA8; // type:func\nFUN_0014cd70 = 0x14CD70; // type:func\nFUN_0014cdc8 = 0x14CDC8; // type:func\nFUN_0014cf30 = 0x14CF30; // type:func\nSMeasureApos = 0x14D0A8; // type:func\nGWrapApos = 0x14D138; // type:func\nFUN_0014d1a0 = 0x14D1A0; // type:func\nEvaluateAposG = 0x14D280; // type:func\nFindAposClosestPointAll = 0x14D3A8; // type:func\nFUN_0014d680 = 0x14D680; // type:func\nFUN_0014d938 = 0x14D938; // type:func\nPcrvNew = 0x14D9A8; // type:func\nFUN_0014da38 = 0x14DA38; // type:func\nFUN_0014da68 = 0x14DA68; // type:func\nFUN_0014da98 = 0x14DA98; // type:func\nFUN_0014dbd0 = 0x14DBD0; // type:func\nDuGetCrvSearchIncrement = 0x14DD00; // type:func\nLoadCrvlFromBrx = 0x14DD28; // type:func\nFUN_0014de08 = 0x14DE08; // type:func\nFUN_0014de40 = 0x14DE40; // type:func\nRenderCrvlSegment = 0x14DE78; // type:func\nFUN_0014df68 = 0x14DF68; // type:func\nFUN_0014df98 = 0x14DF98; // type:func\nFUN_0014e000 = 0x14E000; // type:func\nFUN_0014e068 = 0x14E068; // type:func\nFUN_0014e090 = 0x14E090; // type:func\nFUN_0014e170 = 0x14E170; // type:func\nFUN_0014e2a0 = 0x14E2A0; // type:func\nLoadCrvcFromBrx = 0x14E3D0; // type:func\nInvalidateCrvcCache = 0x14E500; // type:func\nFUN_0014e510 = 0x14E510; // type:func\nEvaluateCrvcFromU = 0x14E5B8; // type:func\nEvaluateCrvcFromS = 0x14E6A8; // type:func\nFUN_0014e710 = 0x14E710; // type:func\nFUN_0014e828 = 0x14E828; // type:func\nFUN_0014e910 = 0x14E910; // type:func\nFUN_0014e990 = 0x14E990; // type:func\nFUN_0014ea48 = 0x14EA48; // type:func\nFUN_0014eb10 = 0x14EB10; // type:func\nFUN_0014ec70 = 0x14EC70; // type:func\nFindCrvcClosestPointFromS = 0x14ED98; // type:func\nInitDart = 0x14EE40; // type:func\nFUN_0014ee70 = 0x14EE70; // type:func\nFUN_0014ef00 = 0x14EF00; // type:func\nFUN_0014ef40 = 0x14EF40; // type:func\nLoadDartFromBrx = 0x14EF88; // type:func\nFUN_0014efb8 = 0x14EFB8; // type:func\nFUN_0014f020 = 0x14F020; // type:func\nUpdateDart = 0x14F058; // type:func\nSetDartDarts = 0x14F110; // type:func\nFUN_0014f168 = 0x14F168; // type:func\nUpdateDartAirborne = 0x14F270; // type:func\nFUN_0014f740 = 0x14F740; // type:func\nHandleDartgunMessage = 0x14F770; // type:func\nBindDartgun = 0x14F850; // type:func\nFUN_0014f920 = 0x14F920; // type:func\nFUN_0014fa88 = 0x14FA88; // type:func\nFUN_0014fbe0 = 0x14FBE0; // type:func\nFUN_0014fc38 = 0x14FC38; // type:func\nFUN_0014fce8 = 0x14FCE8; // type:func\nFUN_0014fda8 = 0x14FDA8; // type:func\nFPrepareDartgunToFire = 0x14FEC0; // type:func\nFUN_00150008 = 0x150008; // type:func\nFUN_00150298 = 0x150298; // type:func\nPratGetDartgunRatTarget = 0x150338; // type:func\nFUN_00150408 = 0x150408; // type:func\nAddDartgunTargetAreaTarget = 0x150418; // type:func\nFUN_001504e0 = 0x1504E0; // type:func\nLoadDialogFromBrx = 0x150528; // type:func\nLoadDialogEventsFromBrx = 0x150570; // type:func\nFUN_001506f0 = 0x1506F0; // type:func\nFUN_00150750 = 0x150750; // type:func\nFUN_00150760 = 0x150760; // type:func\nSetDialogDialogs = 0x150790; // type:func\nFUN_00150ae8 = 0x150AE8; // type:func\nonscreen_text_related = 0x150DC0; // type:func\nFUN_001512a8 = 0x1512A8; // type:func\nFPauseDialog = 0x151300; // type:func\nFUN_001516c0 = 0x1516C0; // type:func\nFUN_001517c0 = 0x1517C0; // type:func\nFUN_00151860 = 0x151860; // type:func\nTriggerDialog = 0x1518B8; // type:func\nUntriggerDialog = 0x1519A8; // type:func\nFUN_001519e0 = 0x1519E0; // type:func\nOnDifficultyGameLoad = 0x151A68; // type:func\nOnDifficultyWorldPreLoad = 0x151A88; // type:func\nOnDifficultyWorldPostLoad = 0x151D28; // type:func\nOnDifficultyInitialTeleport = 0x151E18; // type:func\nOnDifficultyPlayerDeath = 0x151E20; // type:func\nOnDifficultyTriggerCheckpoint = 0x151ED8; // type:func\nOnDifficultyCollectKey = 0x151FC8; // type:func\nOnDifficultyBreak = 0x152010; // type:func\nChangeSuck = 0x152410; // type:func\nInitDl = 0x152438; // type:func\nClearDl = 0x152440; // type:func\nFUN_00152450 = 0x152450; // type:func\nPdleFromDlEntry = 0x152460; // type:func\nAppendDlEntry = 0x152470; // type:func\nFUN_001524d8 = 0x1524D8; // type:func\nInsertDlEntryBefore = 0x152540; // type:func\nRemoveDlEntry = 0x152600; // type:func\nFUN_001526d0 = 0x1526D0; // type:func\nFIsDlEmpty = 0x152720; // type:func\nFUN_00152730 = 0x152730; // type:func\nCPvDl = 0x1527D8; // type:func\nStartupDma = 0x152810; // type:func\nDMAS__DMAS = 0x152888; // type:func\nDMAS__Clear = 0x1528C8; // type:func\nDMAS__Reset = 0x1528E0; // type:func\nFUN_001528f0 = 0x1528F0; // type:func\nFUN_00152938 = 0x152938; // type:func\nDMAS__AllocStack = 0x152980; // type:func\nDMAS__AllocStatic = 0x1529C8; // type:func\nDMAS__Detach = 0x1529E0; // type:func\nDMAS__DetachCopySw = 0x152A50; // type:func\nDMAS__Send = 0x152AE0; // type:func\nDMAS__AddDmaCnt = 0x152B38; // type:func\nFUN_00152b80 = 0x152B80; // type:func\nFUN_00152c18 = 0x152C18; // type:func\nFUN_00152ca0 = 0x152CA0; // type:func\nFUN_00152ce0 = 0x152CE0; // type:func\nDMAS__AddDmaEnd = 0x152D30; // type:func\nDMAS__EndDmaCnt = 0x152D70; // type:func\nSetDyshShadow = 0x152E48; // type:func\nFUN_00153328 = 0x153328; // type:func\nDrawDysh = 0x1533A8; // type:func\nFUN_00153528 = 0x153528; // type:func\nClearDzgSolution = 0x153608; // type:func\nFUN_001536c8 = 0x1536C8; // type:func\nFUN_00153780 = 0x153780; // type:func\nFUN_00153a50 = 0x153A50; // type:func\nSolveDzg = 0x153EC0; // type:func\nSolveDzgFric = 0x154088; // type:func\nApplyDzg = 0x154370; // type:func\nFUN_00154880 = 0x154880; // type:func\nInitEmitb = 0x1549C8; // type:func\nFUN_00154c10 = 0x154C10; // type:func\nLoadEmitmeshFromBrx = 0x154C80; // type:func\nLoadEmitblipColorsFromBrx = 0x154EE0; // type:func\nLoadEmitterFromBrx = 0x154F98; // type:func\nFUN_00155080 = 0x155080; // type:func\nBindEmitterCallback = 0x1550B8; // type:func\nFUN_001550e8 = 0x1550E8; // type:func\nFUN_00155270 = 0x155270; // type:func\nFUN_00155678 = 0x155678; // type:func\nFUN_001556e8 = 0x1556E8; // type:func\nPemitbEnsureEmitter = 0x155778; // type:func\nFUN_001557d0 = 0x1557D0; // type:func\nModifyEmitterParticles = 0x155868; // type:func\nFUN_00155ab0 = 0x155AB0; // type:func\nFUN_00155f28 = 0x155F28; // type:func\nFUN_00155f78 = 0x155F78; // type:func\nFUN_00155f90 = 0x155F90; // type:func\nFUN_00155fa0 = 0x155FA0; // type:func\nFPausedEmitter = 0x155FB0; // type:func\nFUN_00156000 = 0x156000; // type:func\nFUN_00156030 = 0x156030; // type:func\nFUN_00156060 = 0x156060; // type:func\nOnEmitterValuesChanged = 0x156088; // type:func\nSetEmitterParticleCount = 0x156108; // type:func\nSetEmitterAutoPause = 0x156178; // type:func\nFUN_00156188 = 0x156188; // type:func\nFUN_00156218 = 0x156218; // type:func\nFUN_00156250 = 0x156250; // type:func\nFUN_00156288 = 0x156288; // type:func\nStandardSmokeCloud = 0x1566C8; // type:func\nFUN_00156718 = 0x156718; // type:func\nConvertEmitoPosVec = 0x156F08; // type:func\nFUN_00156fc8 = 0x156FC8; // type:func\nChooseEmitVelocity = 0x157098; // type:func\nChooseEmitvVelocityAge = 0x157248; // type:func\nFUN_00157320 = 0x157320; // type:func\nEmitBlips = 0x1575D8; // type:func\nOriginateParticles = 0x1579B0; // type:func\nFUN_00157b88 = 0x157B88; // type:func\nEmitParticles = 0x157E00; // type:func\nFUN_00157ef8 = 0x157EF8; // type:func\nStockSplashBig = 0x157FF8; // type:func\nFUN_00158108 = 0x158108; // type:func\nAddEmitoSkeleton = 0x158198; // type:func\nBindEmitb = 0x158288; // type:func\nSetEmitdvEmitb = 0x1583E8; // type:func\nCalculateEmitdvMatrix = 0x158480; // type:func\nPostExplLoad = 0x1585F8; // type:func\nCalculateExplTransform = 0x158630; // type:func\nExplodeExpl = 0x158730; // type:func\nExplodeExplParams = 0x158778; // type:func\nLoadExplgFromBrx = 0x1587C8; // type:func\nFUN_00158980 = 0x158980; // type:func\nBindExplg = 0x158A10; // type:func\nExplodeExplgExplso = 0x158A80; // type:func\nFUN_00158b00 = 0x158B00; // type:func\nLoadExploFromBrx = 0x158B30; // type:func\nFUN_00158c28 = 0x158C28; // type:func\nFUN_00158c60 = 0x158C60; // type:func\nFUN_00158d40 = 0x158D40; // type:func\nPemitbEnsureExplo = 0x158DD8; // type:func\nFUN_00158e10 = 0x158E10; // type:func\nFUN_00158e48 = 0x158E48; // type:func\nHandleExplsMessage = 0x158F10; // type:func\nExplodeExplsExplso = 0x158F80; // type:func\nFUN_00159068 = 0x159068; // type:func\nFUN_001590a0 = 0x1590A0; // type:func\nInferExpl = 0x159478; // type:func\nFireSwTimedExplodeStyles = 0x159588; // type:func\nPostEyesLoad = 0x1596E0; // type:func\nSetEyesEyess = 0x159770; // type:func\nFUN_00159890 = 0x159890; // type:func\nSetEyesClosed = 0x159A00; // type:func\nFUN_00159a80 = 0x159A80; // type:func\nUpdateFader = 0x159AD0; // type:func\nPfaderNew = 0x159BB0; // type:func\nRemoveFader = 0x159C28; // type:func\nFUN_00159ca0 = 0x159CA0; // type:func\nFUN_00159d00 = 0x159D00; // type:func\nFUN_00159ed0 = 0x159ED0; // type:func\nPdlFromSwOid = 0x159F20; // type:func\nMatchSwObject = 0x159F48; // type:func\nCploFindSwObjects = 0x15A198; // type:func\nPloFindSwObject = 0x15A418; // type:func\nPloFindSwNearest = 0x15A448; // type:func\nFUN_0015a480 = 0x15A480; // type:func\nFIsCidDerivedFrom = 0x15A4B8; // type:func\nCploFindSwObjectsByClass = 0x15A4F0; // type:func\nFUN_0015a838 = 0x15A838; // type:func\nPaloFindLoCommonParent = 0x15A868; // type:func\nInitFlash = 0x15A8B0; // type:func\nLoadFlashFromBrx = 0x15A918; // type:func\nUpdateFlash = 0x15A960; // type:func\nRenderFlashSelf = 0x15A9A8; // type:func\nFPosFlashWithin = 0x15AA50; // type:func\nInitFly = 0x15AAE0; // type:func\nLoadFlyFromBrx = 0x15AC08; // type:func\nFUN_0015ad80 = 0x15AD80; // type:func\nFUN_0015ae38 = 0x15AE38; // type:func\nPostFlyLoad = 0x15AEB0; // type:func\nPresetFlyAccel = 0x15AF50; // type:func\nFUN_0015b128 = 0x15B128; // type:func\nRenderFlySelf = 0x15B4D0; // type:func\nFUN_0015b720 = 0x15B720; // type:func\nSetFlyFlys = 0x15B7B8; // type:func\nFUN_0015bc78 = 0x15BC78; // type:func\nFFindFlyClosestLandingPos = 0x15BD48; // type:func\nFUN_0015bef0 = 0x15BEF0; // type:func\nFUN_0015bfc0 = 0x15BFC0; // type:func\nFCheckFlyOpenSpaceBelow = 0x15C0A0; // type:func\nFUN_0015c188 = 0x15C188; // type:func\nFUN_0015c1c0 = 0x15C1C0; // type:func\nFUN_0015c200 = 0x15C200; // type:func\nFUN_0015c260 = 0x15C260; // type:func\nFUN_0015c2e8 = 0x15C2E8; // type:func\nFUN_0015c3c0 = 0x15C3C0; // type:func\nCFont__DxFromPchz = 0x15C418; // type:func\nFUN_0015c4a8 = 0x15C4A8; // type:func\nCFont__ClineWrapPchz = 0x15C4E8; // type:func\nCFont__DrawPchz = 0x15C638; // type:func\nFUN_0015c8b8 = 0x15C8B8; // type:func\nCFont__PopScaling = 0x15C900; // type:func\nFUN_0015c930 = 0x15C930; // type:func\nCFont__CopyTo = 0x15C9B0; // type:func\nFUN_0015ca38 = 0x15CA38; // type:func\nFUN_0015ca60 = 0x15CA60; // type:func\nCFontBrx__FEnsureLoaded = 0x15CAB8; // type:func\nCFontBrx__SetupDraw = 0x15CB88; // type:func\nFUN_0015cc80 = 0x15CC80; // type:func\nCFontBrx__DxDrawCh = 0x15CD18; // type:func\nFUN_0015cf70 = 0x15CF70; // type:func\nFUN_0015d338 = 0x15D338; // type:func\nCFontBrx__EdgeRect = 0x15D4E0; // type:func\nCFontBrx__LoadFromBrx = 0x15D8A8; // type:func\nCFontBrx__PostLoad = 0x15D998; // type:func\nCFontBrx__PglyffFromCh = 0x15DAB8; // type:func\nFUN_0015db28 = 0x15DB28; // type:func\nFUN_0015db80 = 0x15DB80; // type:func\nCRichText__SetBaseColor = 0x15DBB8; // type:func\nFUN_0015dbe0 = 0x15DBE0; // type:func\nFUN_0015df58 = 0x15DF58; // type:func\nCRichText__Trim = 0x15DFA0; // type:func\nFUN_0015dff8 = 0x15DFF8; // type:func\nFUN_0015e068 = 0x15E068; // type:func\nFUN_0015e1b0 = 0x15E1B0; // type:func\nCRichText__DxMaxLine = 0x15E1F0; // type:func\nFUN_0015e290 = 0x15E290; // type:func\nCRichText__Draw = 0x15E318; // type:func\nPostFontsLoad = 0x15E5F0; // type:func\nStartupFrame = 0x15E810; // type:func\nOpenFrame = 0x15E9F0; // type:func\nEnsureVu1Code = 0x15EAE0; // type:func\nFinalizeFrameVifs = 0x15EB20; // type:func\nFUN_0015ebf0 = 0x15EBF0; // type:func\nCloseFrame = 0x15EC68; // type:func\nFUN_0015ed50 = 0x15ED50; // type:func\ncheck_anticrack_antigrab = 0x15EDB8; // type:func\nFrameRenderLoop = 0x15EE80; // type:func\nFUN_0015ef88 = 0x15EF88; // type:func\nClearPendingFrame = 0x15EFE8; // type:func\nFlushFrames = 0x15F210; // type:func\nFUN_0015f320 = 0x15F320; // type:func\nFUN_0015f618 = 0x15F618; // type:func\nFUN_0015f658 = 0x15F658; // type:func\nRemergeSwObject = 0x15F678; // type:func\nFUN_0015f6c0 = 0x15F6C0; // type:func\nSplinterSwFreezeGroup = 0x15F710; // type:func\nMergeSwGroup = 0x15F7D8; // type:func\nFUN_0015f8b0 = 0x15F8B0; // type:func\nFUN_0015f930 = 0x15F930; // type:func\nFUN_0015f9a0 = 0x15F9A0; // type:func\nFUN_0015fa58 = 0x15FA58; // type:func\nFUN_0015fb28 = 0x15FB28; // type:func\nFreezeAlo = 0x15FBB8; // type:func\nFreezeSo = 0x15FCD8; // type:func\nFUN_0015fd78 = 0x15FD78; // type:func\nFUN_0015ff58 = 0x15FF58; // type:func\nPostFrzgLoad = 0x15FF88; // type:func\nStartupGame = 0x160070; // type:func\nsearch_level_by_load_data = 0x1600A0; // type:func\nsearch_level_by_id = 0x160110; // type:func\nget_level_name_by_id = 0x160148; // type:func\ncall_search_level_by_id = 0x160180; // type:func\nFFindLevel = 0x1601A0; // type:func\nget_level_completion_by_id = 0x1601D8; // type:func\ntally_world_completion = 0x160208; // type:func\ncheck_game_completion = 0x1602A0; // type:func\nunlock_intro_cutscene_for_world = 0x160340; // type:func\nboss_defeated = 0x1603E8; // type:func\nunlock_endgame_cutscenes = 0x1604B8; // type:func\nplay_ending = 0x160578; // type:func\nInitGameState = 0x1605E8; // type:func\nFUN_00160650 = 0x160650; // type:func\nSetupGame = 0x160690; // type:func\nUpdateGameState = 0x1607D0; // type:func\nget_level_state_ptr_by_id = 0x160810; // type:func\nget_level_state_flags_by_id = 0x160850; // type:func\nUnloadGame = 0x160880; // type:func\nRetryGame = 0x1608E0; // type:func\nStartGame = 0x160918; // type:func\nFUN_00160948 = 0x160948; // type:func\ncalculate_percent_completion = 0x160B28; // type:func\nSetCcharm = 0x160C48; // type:func\nFCharmAvailable = 0x160C58; // type:func\nPfLookupDialog = 0x160CA0; // type:func\nclr_8_bytes_1 = 0x160CC8; // type:func\nFUN_00160ce8 = 0x160CE8; // type:func\nOnGameAlarmTriggered = 0x160CF0; // type:func\nOnGameAlarmDisabled = 0x160D00; // type:func\ngrfvault_something = 0x160D10; // type:func\nset_offset_based_on_worldQMARK = 0x160D30; // type:func\nCcharmMost = 0x160D98; // type:func\nreload_post_death = 0x160DA0; // type:func\nInitGeom = 0x160E80; // type:func\nCloneGeom = 0x160EA0; // type:func\nFUN_00161028 = 0x161028; // type:func\n__4GIFS = 0x1611B8; // type:func\nGIFS__AddPrimEnd = 0x161200; // type:func\nGIFS__EndPrim = 0x161278; // type:func\nGIFS__CheckReg = 0x1612E8; // type:func\nGIFS__AddPrimBulk = 0x1612F8; // type:func\nGIFS__AddPrimPack = 0x1613C0; // type:func\nPackRGBA = 0x161458; // type:func\nFUN_001614c8 = 0x1614C8; // type:func\nFUN_00161520 = 0x161520; // type:func\nFUN_00161588 = 0x161588; // type:func\nPackXYZF = 0x1615F0; // type:func\nFUN_00161670 = 0x161670; // type:func\nPackAD = 0x161708; // type:func\nGIFS__AddPrimList = 0x161768; // type:func\nFUN_001617e8 = 0x1617E8; // type:func\nFUN_00161860 = 0x161860; // type:func\nFUN_001618c0 = 0x1618C0; // type:func\nGIFS__AddImage = 0x161958; // type:func\nFUN_001619c0 = 0x1619C0; // type:func\nFUN_00161a88 = 0x161A88; // type:func\nFUN_00161ab0 = 0x161AB0; // type:func\nFUN_00161b10 = 0x161B10; // type:func\nFUN_00161b80 = 0x161B80; // type:func\nFUN_00161bb0 = 0x161BB0; // type:func\nFUN_00161c00 = 0x161C00; // type:func\nFUN_00161f70 = 0x161F70; // type:func\nFUN_00162508 = 0x162508; // type:func\nGLBS__SetPos = 0x162680; // type:func\nGLBS__SetRgba = 0x1626A8; // type:func\nGLBS__SetUv = 0x1626C0; // type:func\nGLBS__AddVtx = 0x1626D8; // type:func\nFUN_00162810 = 0x162810; // type:func\nLoadGlobsetFromBrx = 0x162890; // type:func\nFUN_00163938 = 0x163938; // type:func\nFUN_00163990 = 0x163990; // type:func\nFUN_001639e8 = 0x1639E8; // type:func\nFUN_00163ed8 = 0x163ED8; // type:func\nBuildSubglobSinglePass = 0x164868; // type:func\nFUN_00165588 = 0x165588; // type:func\nCBinaryInputStream__PostGlobsetLoad = 0x165728; // type:func\nBindGlobset = 0x165828; // type:func\nCloneGlobset = 0x165920; // type:func\nFUN_00165ae8 = 0x165AE8; // type:func\nUpdateGlobset = 0x165FE0; // type:func\nFUN_001660a0 = 0x1660A0; // type:func\nUpdateAloInfluences = 0x1660E8; // type:func\nFUN_001662a8 = 0x1662A8; // type:func\nFUN_00166658 = 0x166658; // type:func\nDrawGlob = 0x166690; // type:func\nFUN_00167d20 = 0x167D20; // type:func\nFUN_00167d48 = 0x167D48; // type:func\nFUN_00167d68 = 0x167D68; // type:func\nFUN_00167e08 = 0x167E08; // type:func\nFUN_00167ef0 = 0x167EF0; // type:func\nFUN_00167f10 = 0x167F10; // type:func\nBlendDisplayOnBufferMismatch = 0x168130; // type:func\nFUN_001682c0 = 0x1682C0; // type:func\nSyncVBlank = 0x1683B8; // type:func\nSwapGsBuffers = 0x1683E8; // type:func\nFUN_001684e8 = 0x1684E8; // type:func\nRestoreGsBuffers = 0x1685B8; // type:func\nFUN_00168698 = 0x168698; // type:func\nSendDmaSyncGsFinish = 0x1686E8; // type:func\nBuildClearGifs = 0x168770; // type:func\nStartupGs = 0x1688B8; // type:func\nBlastAqwGifsBothFrames = 0x168A48; // type:func\nFUN_00168af8 = 0x168AF8; // type:func\nFadeFramesToBlack = 0x168B68; // type:func\nResetGsMemory = 0x168D00; // type:func\nNLog2 = 0x168D30; // type:func\nInitGsb = 0x168D68; // type:func\nResetGsb = 0x168D78; // type:func\nIgsAllocGsb = 0x168D88; // type:func\nFUN_00168d98 = 0x168D98; // type:func\nBuildClutTex2 = 0x168E78; // type:func\nFUN_00168f48 = 0x168F48; // type:func\nFUN_00168fb0 = 0x168FB0; // type:func\nFUN_00169088 = 0x169088; // type:func\nFBuildUploadBitmapGifs = 0x1690C0; // type:func\nUploadBitmaps = 0x1692B0; // type:func\nPqwGifsBitmapUpload = 0x1693A8; // type:func\nFUN_001694a0 = 0x1694A0; // type:func\nFUN_001694f8 = 0x1694F8; // type:func\nFUN_00169608 = 0x169608; // type:func\nRebaseSurs = 0x1696B8; // type:func\nPropagateSurs = 0x169718; // type:func\nPqwVifsBitmapUpload = 0x169780; // type:func\nFUN_00169b18 = 0x169B18; // type:func\nStartupHide = 0x169C58; // type:func\nResetHideList = 0x169CA0; // type:func\nFUN_00169cd8 = 0x169CD8; // type:func\nFUN_00169d20 = 0x169D20; // type:func\nFUN_00169d58 = 0x169D58; // type:func\nFUN_00169d90 = 0x169D90; // type:func\nFUN_00169dd8 = 0x169DD8; // type:func\nGetHshapeHidePos = 0x169E20; // type:func\nFUN_00169fc0 = 0x169FC0; // type:func\nFUN_0016a100 = 0x16A100; // type:func\nFUN_0016a140 = 0x16A140; // type:func\nFUN_0016a178 = 0x16A178; // type:func\nFUN_0016a1b0 = 0x16A1B0; // type:func\nFUN_0016a1f8 = 0x16A1F8; // type:func\nFUN_0016a240 = 0x16A240; // type:func\nFUN_0016a320 = 0x16A320; // type:func\nFUN_0016a3a8 = 0x16A3A8; // type:func\nLoadHbskFromBrx = 0x16A420; // type:func\nOnHbskAdd__FP4HBSK = 0x16A490; // type:func\nOnHbskRemove = 0x16A4C8; // type:func\nCloneHbsk = 0x16A500; // type:func\nFIgnoreHbskIntersection = 0x16A548; // type:func\nPresetHbskAccel = 0x16A580; // type:func\nSetHbskHbsks = 0x16A5F0; // type:func\nCdartStuckHbsk = 0x16A758; // type:func\nPdartOldestHbskStuck = 0x16A820; // type:func\nGetHbskClosestHidePos = 0x16A910; // type:func\niterates_levels_something = 0x16AA18; // type:func\ncalls_something = 0x16AB38; // type:func\nPost_something_load = 0x16AED8; // type:func\nhideout_set_focus = 0x16AF80; // type:func\nFTakeStepguardDamage = 0x16B0F8; // type:func\nstart_world_for_first_timeQMARK = 0x16B190; // type:func\nsomething = 0x16B300; // type:func\nFUN_0016b4a0 = 0x16B4A0; // type:func\nFUN_0016b520 = 0x16B520; // type:func\nFUN_0016b560 = 0x16B560; // type:func\nFUN_0016b580 = 0x16B580; // type:func\nFUN_0016b7a8 = 0x16B7A8; // type:func\nFUN_0016b860 = 0x16B860; // type:func\nFUN_0016ba40 = 0x16BA40; // type:func\nCFont__PushScaling = 0x16BB78; // type:func\nFUN_0016bba8 = 0x16BBA8; // type:func\nFUN_0016bdd0 = 0x16BDD0; // type:func\nFUN_0016bea0 = 0x16BEA0; // type:func\nFUN_0016c360 = 0x16C360; // type:func\nFUN_0016c470 = 0x16C470; // type:func\nLoadHndFromBrx = 0x16C4B8; // type:func\nFUN_0016c508 = 0x16C508; // type:func\nSolveAloIK = 0x16C528; // type:func\nFUN_0016ce00 = 0x16CE00; // type:func\nLoadJloFromBrx = 0x16CE80; // type:func\nFUN_0016cf70 = 0x16CF70; // type:func\nFUN_0016d040 = 0x16D040; // type:func\nFUN_0016d0c0 = 0x16D0C0; // type:func\nFUN_0016d128 = 0x16D128; // type:func\nFUN_0016d1e0 = 0x16D1E0; // type:func\nFUN_0016d3f0 = 0x16D3F0; // type:func\nFUN_0016d490 = 0x16D490; // type:func\nFUN_0016d788 = 0x16D788; // type:func\nFUN_0016d828 = 0x16D828; // type:func\nFUN_0016d928 = 0x16D928; // type:func\nFUN_0016d9a8 = 0x16D9A8; // type:func\nFUN_0016da00 = 0x16DA00; // type:func\nFUN_0016dac0 = 0x16DAC0; // type:func\nFUN_0016dcf0 = 0x16DCF0; // type:func\nFUN_0016dd00 = 0x16DD00; // type:func\nFUN_0016dd10 = 0x16DD10; // type:func\nLoadJlocFromBrx = 0x16DD90; // type:func\nFUN_0016dde8 = 0x16DDE8; // type:func\nFUN_0016de20 = 0x16DE20; // type:func\nFUN_0016df30 = 0x16DF30; // type:func\nBindJlovol = 0x16DF68; // type:func\nFUN_0016dfe0 = 0x16DFE0; // type:func\nStartupJoy = 0x16E0B8; // type:func\nAddGrfusr = 0x16E0F0; // type:func\nRemoveGrfusr = 0x16E118; // type:func\nUpdateGrfjoytFromGrfusr = 0x16E148; // type:func\nInitJoy = 0x16E1A0; // type:func\nUpdateJoy = 0x16E238; // type:func\nSetJoyJoys = 0x16E630; // type:func\nGetJoyXYDeflection = 0x16E738; // type:func\nFReadJoy = 0x16E940; // type:func\nSetJoyBtnHandled = 0x16EC20; // type:func\nFUN_0016ec38 = 0x16EC38; // type:func\nStartJoySelection = 0x16EC88; // type:func\nFUN_0016ec98 = 0x16EC98; // type:func\nFUN_0016eed0 = 0x16EED0; // type:func\nUBtnpJoy = 0x16F108; // type:func\nAddCode = 0x16F188; // type:func\n_ResetCodes = 0x16F1F8; // type:func\n_MatchCodes = 0x16F238; // type:func\nUpdateCodes = 0x16F2E0; // type:func\nremove_all_fchts = 0x16F408; // type:func\nAddFcht = 0x16F430; // type:func\ncheat_activate_chetkido = 0x16F478; // type:func\nStartupCodes = 0x16F588; // type:func\nInitJt = 0x16F608; // type:func\nLoadJtFromBrx = 0x16F7B0; // type:func\nPostJtLoad = 0x16F810; // type:func\nFUN_0016fd70 = 0x16FD70; // type:func\nFUN_001701b0 = 0x1701B0; // type:func\nFUN_00170410 = 0x170410; // type:func\nAdjustJtDz = 0x170528; // type:func\nFUN_001705c8 = 0x1705C8; // type:func\nUpdateJtInternalXps = 0x170660; // type:func\nFCheckJtXpBase = 0x170790; // type:func\nFUN_00170820 = 0x170820; // type:func\nHandleJtMessage = 0x170960; // type:func\nFTurnJtToTarget = 0x171180; // type:func\nFUN_00171238 = 0x171238; // type:func\nRebuildJtXmg = 0x1719E8; // type:func\nFMatchJtXmg = 0x171C80; // type:func\nFUN_00171dd8 = 0x171DD8; // type:func\nFUN_00171f28 = 0x171F28; // type:func\nFUN_00171fe0 = 0x171FE0; // type:func\nCalculateJtToolSpin = 0x172078; // type:func\nFUN_001721b0 = 0x1721B0; // type:func\nFUN_00172530 = 0x172530; // type:func\nFUN_001725e0 = 0x1725E0; // type:func\nUpdateJtTool = 0x1727B0; // type:func\nFUN_00172898 = 0x172898; // type:func\nFUN_00172ae0 = 0x172AE0; // type:func\nFUN_00172b08 = 0x172B08; // type:func\nFUN_00172b88 = 0x172B88; // type:func\nFUN_00172bf8 = 0x172BF8; // type:func\nFUN_00172cf0 = 0x172CF0; // type:func\nFUN_00172ee0 = 0x172EE0; // type:func\nGetJtCpdefiFlatten = 0x1733B8; // type:func\nFUN_00173708 = 0x173708; // type:func\nFUN_00173750 = 0x173750; // type:func\nUpdateJtActive = 0x173888; // type:func\nUpdateJt = 0x174808; // type:func\nFUN_00174e20 = 0x174E20; // type:func\nFUN_00174f50 = 0x174F50; // type:func\nEnableJtActadj = 0x175078; // type:func\nSetJtJts = 0x175170; // type:func\nFUN_001777f8 = 0x1777F8; // type:func\nFUN_00177800 = 0x177800; // type:func\nPaloAbsorbWkr = 0x177838; // type:func\nFUN_00177990 = 0x177990; // type:func\nFIsJtSoundBase = 0x177E20; // type:func\nFUN_00177e70 = 0x177E70; // type:func\nFUN_00177f98 = 0x177F98; // type:func\nFUN_00178008 = 0x178008; // type:func\nOnPoAdd = 0x178038; // type:func\nFUN_00178068 = 0x178068; // type:func\nFUN_001781e0 = 0x1781E0; // type:func\nFUN_00178258 = 0x178258; // type:func\nFUN_00178280 = 0x178280; // type:func\nFUN_001782c0 = 0x1782C0; // type:func\nFUN_00178598 = 0x178598; // type:func\nFUN_00178678 = 0x178678; // type:func\nFUN_001788f0 = 0x1788F0; // type:func\nFUN_00178d98 = 0x178D98; // type:func\nFUN_001790b8 = 0x1790B8; // type:func\nFUN_001793c0 = 0x1793C0; // type:func\nFUN_001793f0 = 0x1793F0; // type:func\nFUN_001794e0 = 0x1794E0; // type:func\nFUN_00179590 = 0x179590; // type:func\nFUN_00179690 = 0x179690; // type:func\nFUN_001796d0 = 0x1796D0; // type:func\nFUN_00179a68 = 0x179A68; // type:func\nFUN_0017a6d0 = 0x17A6D0; // type:func\nFUN_0017a700 = 0x17A700; // type:func\nFUN_0017a788 = 0x17A788; // type:func\nFUN_0017a9e0 = 0x17A9E0; // type:func\nFUN_0017aa40 = 0x17AA40; // type:func\nFUN_0017ab58 = 0x17AB58; // type:func\nFUN_0017abe8 = 0x17ABE8; // type:func\nFUN_0017ad50 = 0x17AD50; // type:func\nFUN_0017add0 = 0x17ADD0; // type:func\nFUN_0017ae00 = 0x17AE00; // type:func\nFUN_0017af38 = 0x17AF38; // type:func\nFUN_0017b308 = 0x17B308; // type:func\nFUN_0017b3a8 = 0x17B3A8; // type:func\nFUN_0017b410 = 0x17B410; // type:func\nFUN_0017b510 = 0x17B510; // type:func\nFUN_0017b550 = 0x17B550; // type:func\nFUN_0017b598 = 0x17B598; // type:func\nFUN_0017b5d0 = 0x17B5D0; // type:func\nFUN_0017b610 = 0x17B610; // type:func\nFUN_0017b648 = 0x17B648; // type:func\nFUN_0017b710 = 0x17B710; // type:func\nFUN_0017b7a8 = 0x17B7A8; // type:func\nFUN_0017b8c0 = 0x17B8C0; // type:func\nFUN_0017b998 = 0x17B998; // type:func\nFUN_0017b9d0 = 0x17B9D0; // type:func\nSetJsgFocus = 0x17BB78; // type:func\nFUN_0017bc20 = 0x17BC20; // type:func\nNextJsgJsge = 0x17BCD0; // type:func\nFUN_0017c428 = 0x17C428; // type:func\nFUN_0017c660 = 0x17C660; // type:func\nFUN_0017c718 = 0x17C718; // type:func\nFUN_0017cda8 = 0x17CDA8; // type:func\nFUN_0017cde0 = 0x17CDE0; // type:func\nFUN_0017ce20 = 0x17CE20; // type:func\nFUN_0017ce80 = 0x17CE80; // type:func\nFUN_0017cf38 = 0x17CF38; // type:func\nFUN_0017cfc8 = 0x17CFC8; // type:func\nFUN_0017cff0 = 0x17CFF0; // type:func\nFUN_0017d018 = 0x17D018; // type:func\nFUN_0017d040 = 0x17D040; // type:func\nFUN_0017d078 = 0x17D078; // type:func\nFUN_0017d0a0 = 0x17D0A0; // type:func\nFUN_0017d0d8 = 0x17D0D8; // type:func\nFUN_0017d100 = 0x17D100; // type:func\nFUN_0017d148 = 0x17D148; // type:func\nFUN_0017d180 = 0x17D180; // type:func\nFUN_0017d1b8 = 0x17D1B8; // type:func\nFUN_0017d1e8 = 0x17D1E8; // type:func\nFUN_0017d220 = 0x17D220; // type:func\nPresetJtAccelJump = 0x17D248; // type:func\nFUN_0017d5d8 = 0x17D5D8; // type:func\nFCheckJtSingleEdge = 0x17DCE0; // type:func\nFUN_0017de88 = 0x17DE88; // type:func\nFUN_0017e088 = 0x17E088; // type:func\nPxpFindJtBestEdge = 0x17E3C8; // type:func\nJtsResetJt = 0x17E6D0; // type:func\nFUN_0017e710 = 0x17E710; // type:func\nFUN_0017ece8 = 0x17ECE8; // type:func\nFUN_0017f018 = 0x17F018; // type:func\nFUN_0017fac0 = 0x17FAC0; // type:func\nGetJtJumpVelocity = 0x17FB78; // type:func\nFUN_0017fc48 = 0x17FC48; // type:func\nFUN_0017fcc8 = 0x17FCC8; // type:func\nFUN_0017fd48 = 0x17FD48; // type:func\nResetJmtList = 0x17FD70; // type:func\nFUN_0017fd90 = 0x17FD90; // type:func\nFUN_0017fdc8 = 0x17FDC8; // type:func\nFUN_0017fe00 = 0x17FE00; // type:func\nFUN_0017fe48 = 0x17FE48; // type:func\nFUN_0017fe90 = 0x17FE90; // type:func\nLoadKeyholeFromBrx = 0x17FEC0; // type:func\nDrawKeyholeMask = 0x180108; // type:func\nDrawKeyhole = 0x180398; // type:func\n__static_initialization_and_destruction_01 = 0x180E38; // type:func\nFUN_00180e90 = 0x180E90; // type:func\nFUN_00180eb0 = 0x180EB0; // type:func\nFUN_00180ee8 = 0x180EE8; // type:func\nFUN_00180f20 = 0x180F20; // type:func\nFUN_00180f68 = 0x180F68; // type:func\nFUN_00180f98 = 0x180F98; // type:func\nFUN_00181078 = 0x181078; // type:func\nFUN_00181448 = 0x181448; // type:func\nFUN_00181658 = 0x181658; // type:func\nOnLgnActive = 0x181780; // type:func\nRenderLgnAll = 0x181818; // type:func\nFUN_00181a58 = 0x181A58; // type:func\nFUN_00181a98 = 0x181A98; // type:func\nFUN_00181af0 = 0x181AF0; // type:func\nFUN_00181b20 = 0x181B20; // type:func\nFUN_00181bc8 = 0x181BC8; // type:func\nFUN_00181d28 = 0x181D28; // type:func\nFUN_00181d88 = 0x181D88; // type:func\nFUN_00181da8 = 0x181DA8; // type:func\nFUN_00181ed0 = 0x181ED0; // type:func\nFUN_001821b0 = 0x1821B0; // type:func\nFUN_00182470 = 0x182470; // type:func\nFUN_001824d8 = 0x1824D8; // type:func\nFUN_00182548 = 0x182548; // type:func\nProjectSwpTransform = 0x182748; // type:func\nFUN_00182948 = 0x182948; // type:func\nInitLo = 0x182C18; // type:func\nPostLoLoad = 0x182C58; // type:func\nAddLo = 0x182C80; // type:func\nAddLoHierarchy = 0x182D00; // type:func\nOnLoAdd = 0x182D48; // type:func\nRemoveLo = 0x182D50; // type:func\nFUN_00182dd8 = 0x182DD8; // type:func\nSetLoSuckHideLimit = 0x182E40; // type:func\nRemoveLoHierarchy = 0x182E88; // type:func\nOnLoRemove = 0x182ED0; // type:func\nSnipLo = 0x182ED8; // type:func\nFFindLoParent = 0x182F40; // type:func\nSetLoParent = 0x182F78; // type:func\nFIsLoInWorld = 0x182FC8; // type:func\nFUN_00183028 = 0x183028; // type:func\nFUN_00183058 = 0x183058; // type:func\nCloneLoHierarchy = 0x1830B0; // type:func\nCloneLo = 0x1830D8; // type:func\nFUN_001831e8 = 0x1831E8; // type:func\nFUN_00183238 = 0x183238; // type:func\nFUN_00183290 = 0x183290; // type:func\nFUN_001832c0 = 0x1832C0; // type:func\nSubscribeLoObject = 0x1832F0; // type:func\nFUN_00183320 = 0x183320; // type:func\nSendLoMessage = 0x183350; // type:func\nLoadLoFromBrx = 0x1833D0; // type:func\nFMatchesLoName = 0x1833F0; // type:func\nOidProxyLo = 0x183438; // type:func\nFUN_00183458 = 0x183458; // type:func\nGetLoOidProxy = 0x183478; // type:func\nPostSpliceEventCallback = 0x1834A0; // type:func\nFFilterSpliceEvent = 0x183668; // type:func\nHandleLoSpliceEvent = 0x1837E0; // type:func\nFUN_00183910 = 0x183910; // type:func\nFUN_00183990 = 0x183990; // type:func\nFUN_00183a10 = 0x183A10; // type:func\nFUN_00183a90 = 0x183A90; // type:func\nFUN_00183b20 = 0x183B20; // type:func\nFUN_00183bb8 = 0x183BB8; // type:func\nFUN_00183c38 = 0x183C38; // type:func\nInitLight = 0x183CC8; // type:func\nFUN_00183d88 = 0x183D88; // type:func\nFUN_00183dc0 = 0x183DC0; // type:func\nFUN_00183df8 = 0x183DF8; // type:func\nFUN_00183e40 = 0x183E40; // type:func\nFUN_00183e70 = 0x183E70; // type:func\nCloneLight = 0x183EA0; // type:func\nFUN_00183f40 = 0x183F40; // type:func\nFUN_00183fe0 = 0x183FE0; // type:func\nFUN_001840b8 = 0x1840B8; // type:func\nFUN_001840f0 = 0x1840F0; // type:func\nInvalidateLight = 0x1841B0; // type:func\nRebuildLightVifs = 0x1841D0; // type:func\nFUN_00184768 = 0x184768; // type:func\nFUN_001847f0 = 0x1847F0; // type:func\nSetLightHighlightColor = 0x184818; // type:func\nFUN_00184838 = 0x184838; // type:func\nFUN_00184858 = 0x184858; // type:func\nFUN_00184878 = 0x184878; // type:func\nFUN_00184898 = 0x184898; // type:func\nSetLightDirection = 0x1848B8; // type:func\nFUN_00184968 = 0x184968; // type:func\nFUN_00184990 = 0x184990; // type:func\nFUN_001849d0 = 0x1849D0; // type:func\nFUN_00184a08 = 0x184A08; // type:func\nFUN_00184a38 = 0x184A38; // type:func\nRebuildLightFrustrum = 0x184A70; // type:func\nUpdateLightBeamGrfzon = 0x184B58; // type:func\nFUN_00184cd0 = 0x184CD0; // type:func\nFUN_00184d20 = 0x184D20; // type:func\nFUN_00184d58 = 0x184D58; // type:func\nNCmpFindLight = 0x184D78; // type:func\nPrepareSwLightsForDraw = 0x184DE8; // type:func\nTwpsFindSwLights = 0x185150; // type:func\nInitActla = 0x185358; // type:func\nFUN_001853f0 = 0x1853F0; // type:func\nPaloGetActlaTarget = 0x185468; // type:func\nUpdateActla = 0x185498; // type:func\nGetActlaRotationGoal = 0x185538; // type:func\nmain = 0x185758; // type:func\nStartupVU0 = 0x185A58; // type:func\nStartupVU1 = 0x185AC8; // type:func\nStartup = 0x185B38; // type:func\nMuFromAmtlk = 0x185C18; // type:func\nElasFromAmtlk = 0x185CA0; // type:func\nPxpAdd = 0x185D20; // type:func\nRecalcSwXpPos = 0x185F48; // type:func\nRecalcSwXpMovement = 0x1860A8; // type:func\nFreeSwXpList = 0x1861E8; // type:func\nFindClosestPointOnLine = 0x186230; // type:func\nFUN_00186320 = 0x186320; // type:func\nClsgClipSoAllEdges = 0x186450; // type:func\nClsgClipSoBspEdges = 0x186568; // type:func\nCategorizeAlsg = 0x1867C8; // type:func\nCplsgFindEdgePath = 0x186A70; // type:func\nFUN_00186ba8 = 0x186BA8; // type:func\nFUN_00187260 = 0x187260; // type:func\nMarkSoContactsSphereBsp = 0x1879C0; // type:func\nMarkSoContactsSphereSphere = 0x187A88; // type:func\nCalculateCenterContact = 0x187B60; // type:func\nFMarkSoContactsCenterBsp = 0x187C28; // type:func\nFClipEdgeToSphere = 0x187D08; // type:func\nFMarkSoContactsCenterSphere = 0x187E88; // type:func\nFUN_00187f40 = 0x187F40; // type:func\nFUN_00188270 = 0x188270; // type:func\nMATRIX4__PostCopyMatrix3 = 0x1884C0; // type:func\nFUN_001884e0 = 0x1884E0; // type:func\nMatMulMatTransMat = 0x188520; // type:func\nFUN_001885e0 = 0x1885E0; // type:func\noperatorSTAR = 0x188628; // type:func\noperatorSTAR1 = 0x188668; // type:func\nMultiplyMatrix4Vector = 0x188700; // type:func\noperatorSTAR2 = 0x188740; // type:func\nTransposeMatrix4 = 0x188770; // type:func\nAddMatrix4Matrix4 = 0x188810; // type:func\nLoadRotateMatrixRad = 0x188850; // type:func\nLoadRotateMatrix = 0x188978; // type:func\nLoadRotateMatrixEuler = 0x188A20; // type:func\nLoadMatrixFromPosRot = 0x188B08; // type:func\nLoadMatrixFromPosRotInverse = 0x188B48; // type:func\nLoadMatrixFromPosRotScale = 0x188C10; // type:func\nFUN_00188ce0 = 0x188CE0; // type:func\nDecomposeRotateMatrixRad = 0x188D28; // type:func\nDecomposeRotateMatrixEuler = 0x188FD8; // type:func\nNormalizeRotateMatrix3 = 0x1890A0; // type:func\nCalculateDmat = 0x189150; // type:func\nFUN_001891c0 = 0x1891C0; // type:func\nFUN_00189230 = 0x189230; // type:func\nFUN_001892a0 = 0x1892A0; // type:func\nLoadLookAtMatrix__FP6VECTORP7MATRIX3 = 0x189350; // type:func\nTiltMatUpright = 0x189378; // type:func\nFInvertMatrix = 0x189438; // type:func\nFInvertMatrix3 = 0x1897F0; // type:func\nFUN_00189af0 = 0x189AF0; // type:func\nFUN_00189b18 = 0x189B18; // type:func\nFUN_00189c28 = 0x189C28; // type:func\nBuildRotateVectorsMatrix = 0x189D38; // type:func\nFUN_00189f58 = 0x189F58; // type:func\nLoadScaleMatrixScalar = 0x18A008; // type:func\nLoadScaleMatrixVector = 0x18A040; // type:func\nLoadRotateVectorMatrix = 0x18A160; // type:func\nFUN_0018a388 = 0x18A388; // type:func\nLoadUnknown2FromBrx = 0x18A3B8; // type:func\nFUN_0018a3f0 = 0x18A3F0; // type:func\nFUN_0018a510 = 0x18A510; // type:func\nFUN_0018a628 = 0x18A628; // type:func\nPsoHitTestCylinderObjects = 0x18A6C0; // type:func\nFUN_0018a830 = 0x18A830; // type:func\nFObstructedMbg = 0x18A910; // type:func\nFUN_0018a9a8 = 0x18A9A8; // type:func\nFUN_0018aae0 = 0x18AAE0; // type:func\nFUN_0018ab88 = 0x18AB88; // type:func\nFUN_0018abf0 = 0x18ABF0; // type:func\nFUN_0018ac58 = 0x18AC58; // type:func\nFUN_0018acd0 = 0x18ACD0; // type:func\nFUN_0018acf0 = 0x18ACF0; // type:func\nFUN_0018ad88 = 0x18AD88; // type:func\nFUN_0018ae38 = 0x18AE38; // type:func\nFUN_0018b2e8 = 0x18B2E8; // type:func\nFUN_0018b340 = 0x18B340; // type:func\nFUN_0018b460 = 0x18B460; // type:func\nFUN_0018b580 = 0x18B580; // type:func\nFUN_0018b5c0 = 0x18B5C0; // type:func\nthread_entrypoint = 0x18B600; // type:func\ncreates_a_thread2 = 0x18B670; // type:func\nFUN_0018b720 = 0x18B720; // type:func\nvalidate_thread_id = 0x18B770; // type:func\nFUN_0018b780 = 0x18B780; // type:func\nzero29_pos30_neg31 = 0x18B910; // type:func\nFUN_0018b930 = 0x18B930; // type:func\nFUN_0018b988 = 0x18B988; // type:func\nFUN_0018bc90 = 0x18BC90; // type:func\nFUN_0018bd00 = 0x18BD00; // type:func\nFUN_0018bd58 = 0x18BD58; // type:func\nunk_save_related = 0x18BDC8; // type:func\nFUN_0018bfa8 = 0x18BFA8; // type:func\nFUN_0018c028 = 0x18C028; // type:func\nFUN_0018c178 = 0x18C178; // type:func\nFUN_0018c1a8 = 0x18C1A8; // type:func\nFUN_0018c1e8 = 0x18C1E8; // type:func\ncalls_calls_wac_related_notcalled = 0x18C250; // type:func\nFUN_0018c420 = 0x18C420; // type:func\nload_save_fileQMARK = 0x18C568; // type:func\nFUN_0018c638 = 0x18C638; // type:func\nFUN_0018c770 = 0x18C770; // type:func\nautosaveQMARK = 0x18C7F8; // type:func\nFUN_0018c888 = 0x18C888; // type:func\nFUN_0018c9c0 = 0x18C9C0; // type:func\nFUN_0018ca10 = 0x18CA10; // type:func\ncalls_wac_related_notcalled = 0x18CBF8; // type:func\nwac_related_notcalled = 0x18CC20; // type:func\nFUN_0018cdd8 = 0x18CDD8; // type:func\nFUN_0018cfc0 = 0x18CFC0; // type:func\nFUN_0018d028 = 0x18D028; // type:func\nFUN_0018d0a0 = 0x18D0A0; // type:func\nFUN_0018d168 = 0x18D168; // type:func\nFUN_0018d1f8 = 0x18D1F8; // type:func\nFUN_0018d228 = 0x18D228; // type:func\nFUN_0018d268 = 0x18D268; // type:func\nFUN_0018d2b0 = 0x18D2B0; // type:func\nFUN_0018d2e8 = 0x18D2E8; // type:func\nFUN_0018d328 = 0x18D328; // type:func\nFUN_0018d368 = 0x18D368; // type:func\nCFileLocation__Clear = 0x18D410; // type:func\nPvAllocGlobalImpl = 0x18D4B0; // type:func\nCheckForOutOfMemory = 0x18D4F8; // type:func\nPvAllowSwImpl = 0x18D500; // type:func\nFreeSw = 0x18D550; // type:func\nPvAllocSwCopyImpl = 0x18D568; // type:func\nPvAllocSwClearImpl = 0x18D5C0; // type:func\nInitStackImpl = 0x18D608; // type:func\nPvAllocStackImpl = 0x18D658; // type:func\nFUN_0018d6a8 = 0x18D6A8; // type:func\nFreeStackImpl = 0x18D6F0; // type:func\nmalloc = 0x18D740; // type:func\n_malloc_r = 0x18D748; // type:func\nfree = 0x18D750; // type:func\nFUN_0018d758 = 0x18D758; // type:func\n__builtin_delete = 0x18D778; // type:func\nCopyAqw = 0x18D780; // type:func\nCopyAb = 0x18D800; // type:func\nFUN_0018d8e0 = 0x18D8E0; // type:func\nLoadMissileFromBrx = 0x18D910; // type:func\nOnMissileRemove = 0x18D978; // type:func\nProjectMissileTransform = 0x18D9B8; // type:func\nFireMissile = 0x18DA40; // type:func\nRenderMissileAll = 0x18DB20; // type:func\nFUN_0018dc88 = 0x18DC88; // type:func\nFUN_0018dd50 = 0x18DD50; // type:func\nFUN_0018dd78 = 0x18DD78; // type:func\nFUN_0018dda0 = 0x18DDA0; // type:func\nFireAccmiss = 0x18DDD8; // type:func\nFUN_0018de70 = 0x18DE70; // type:func\nFireSplmiss = 0x18DEE8; // type:func\nFUN_0018e040 = 0x18E040; // type:func\nget_cutscene_pchz_from_oid = 0x18E410; // type:func\nPchzFriendlyFromCid = 0x18E480; // type:func\nFUN_0018e4c0 = 0x18E4C0; // type:func\nFUN_0018e4f0 = 0x18E4F0; // type:func\nFUN_0018e558 = 0x18E558; // type:func\nFUN_0018e5e8 = 0x18E5E8; // type:func\nFUN_0018e678 = 0x18E678; // type:func\nCQueueOutputIop__Reset = 0x18E6A0; // type:func\nFUN_0018e6c0 = 0x18E6C0; // type:func\nFUN_0018e7c0 = 0x18E7C0; // type:func\nFUN_0018e838 = 0x18E838; // type:func\nFUN_0018e940 = 0x18E940; // type:func\nCMpegAudio__Reset = 0x18EA48; // type:func\nCMpegAudio__Close = 0x18EAA0; // type:func\nCMpegAudio__FAccept = 0x18EAF8; // type:func\nCMpegAudio__Update = 0x18EB98; // type:func\nFUN_0018ec40 = 0x18EC40; // type:func\nFUN_0018ec80 = 0x18EC80; // type:func\nFUN_0018eca8 = 0x18ECA8; // type:func\nFUN_0018ed78 = 0x18ED78; // type:func\nBuildMpegGifs = 0x18EDA8; // type:func\nFUN_0018ef78 = 0x18EF78; // type:func\ncutscene_mgr_unlock_cutscene = 0x18F0E8; // type:func\nCMpeg__do_executeQMARK = 0x18F148; // type:func\nCMpeg__Execute = 0x18F198; // type:func\nCMpeg__Start = 0x18F448; // type:func\ncheck_anticrack_vehicles = 0x18F610; // type:func\nCMpeg__Update = 0x18F6E8; // type:func\nCMpeg__Finish = 0x18F7D0; // type:func\nCMpeg__CbDemuxed = 0x18F890; // type:func\n__static_initialization_and_destruction_02 = 0x18F940; // type:func\nFUN_0018f968 = 0x18F968; // type:func\nFUN_0018f988 = 0x18F988; // type:func\nFUN_0018f9d8 = 0x18F9D8; // type:func\nFUN_0018fef8 = 0x18FEF8; // type:func\nFUN_0018ff28 = 0x18FF28; // type:func\nFUN_0018ffb0 = 0x18FFB0; // type:func\nFUN_001900a0 = 0x1900A0; // type:func\nFUN_00190128 = 0x190128; // type:func\nFUN_00190258 = 0x190258; // type:func\nFCanPuffcAttack = 0x1903F0; // type:func\nFUN_00190450 = 0x190450; // type:func\nFUN_001904e0 = 0x1904E0; // type:func\nFUN_00190570 = 0x190570; // type:func\nFUN_00190660 = 0x190660; // type:func\nFUN_001906f8 = 0x1906F8; // type:func\nFUN_00190770 = 0x190770; // type:func\nPcbspExtract = 0x1907E0; // type:func\nPcgtExtract = 0x1907F0; // type:func\nPcgtPointInCbspQuick = 0x190810; // type:func\nFUN_001908c0 = 0x1908C0; // type:func\nFUN_001909b0 = 0x1909B0; // type:func\nFUN_001909f0 = 0x1909F0; // type:func\nFUN_00190e30 = 0x190E30; // type:func\nIcgvFromPcgv = 0x190EA8; // type:func\nFUN_00190eb8 = 0x190EB8; // type:func\nSimplifyApcgvNeighbor = 0x191128; // type:func\nCposFindPath = 0x191290; // type:func\nFindClosestPointInCg = 0x191570; // type:func\nLoadPathzoneFromBrx = 0x1916D0; // type:func\nFUN_001919f8 = 0x1919F8; // type:func\nFUN_00191a68 = 0x191A68; // type:func\nFUN_00191a88 = 0x191A88; // type:func\nFUN_00191aa8 = 0x191AA8; // type:func\nFUN_00191ac8 = 0x191AC8; // type:func\nChoosePathzoneRandomPoint = 0x191C78; // type:func\nSetPhase = 0x191E70; // type:func\nClearPhase = 0x191EB0; // type:func\nStartupPipe = 0x191EC0; // type:func\nResetPipeList = 0x191EE8; // type:func\nFUN_00191f08 = 0x191F08; // type:func\nFUN_00191f68 = 0x191F68; // type:func\nFUN_00191fa0 = 0x191FA0; // type:func\nFUN_00191fd8 = 0x191FD8; // type:func\nFUN_00192020 = 0x192020; // type:func\nLoadPntFromBrx = 0x192068; // type:func\nFUN_001920b0 = 0x1920B0; // type:func\nFUN_001920e0 = 0x1920E0; // type:func\nLoadUnknown3FromBrx = 0x192150; // type:func\nFUN_00192190 = 0x192190; // type:func\nFUN_001921a8 = 0x1921A8; // type:func\nClonePo = 0x1921E8; // type:func\nHandlePoMessage = 0x192230; // type:func\nOnPoActive = 0x1922E8; // type:func\nGetPoCpdefi = 0x192380; // type:func\nFUN_00192418 = 0x192418; // type:func\nFUN_00192450 = 0x192450; // type:func\nFUN_00192498 = 0x192498; // type:func\nFUN_001924c8 = 0x1924C8; // type:func\nPpoCur = 0x1925F0; // type:func\nPpoStart = 0x192620; // type:func\n_IppoFindPo = 0x192688; // type:func\nFUN_001926d0 = 0x1926D0; // type:func\nRemovePoFromList = 0x192780; // type:func\nFUN_00192820 = 0x192820; // type:func\nOnPoRemove = 0x192850; // type:func\nSwitchToIppo = 0x192880; // type:func\nFUN_00192990 = 0x192990; // type:func\nSwitchToPo = 0x1929D0; // type:func\nFUN_001929f8 = 0x1929F8; // type:func\nFUN_00192a38 = 0x192A38; // type:func\nFUN_00192a70 = 0x192A70; // type:func\nUpdatePo = 0x192B58; // type:func\nFUN_00192c58 = 0x192C58; // type:func\nFUN_00192dd0 = 0x192DD0; // type:func\nFUN_001930b8 = 0x1930B8; // type:func\nFUN_001931f0 = 0x1931F0; // type:func\nCProg__CProg = 0x193210; // type:func\nCProg__Begin = 0x193270; // type:func\nCProg__SetRemain = 0x193288; // type:func\nCProg__End = 0x193300; // type:func\nCProg__Draw = 0x193318; // type:func\nAchzFromRespk = 0x193598; // type:func\nFUN_001935b0 = 0x1935B0; // type:func\nFUN_00193660 = 0x193660; // type:func\nrender_pause_menuQMARK = 0x1936A0; // type:func\nFUN_00193e58 = 0x193E58; // type:func\nFUN_00193ee8 = 0x193EE8; // type:func\nFUN_001940e8 = 0x1940E8; // type:func\nFUN_00194278 = 0x194278; // type:func\nFUN_00194398 = 0x194398; // type:func\nupdate_pausemenu_active = 0x1943E8; // type:func\nFUN_00194d30 = 0x194D30; // type:func\ngui_draw_start_menuQMARK = 0x194E60; // type:func\nFUN_00194f00 = 0x194F00; // type:func\nFUN_00194f38 = 0x194F38; // type:func\nrender_menu = 0x194F80; // type:func\nFUN_00195928 = 0x195928; // type:func\nFUN_00195958 = 0x195958; // type:func\nFUN_001961c0 = 0x1961C0; // type:func\nFUN_00196330 = 0x196330; // type:func\nFUN_001963d8 = 0x1963D8; // type:func\nLoadProxyFromBrx = 0x196410; // type:func\nFUN_00196810 = 0x196810; // type:func\nFUN_00196900 = 0x196900; // type:func\nFUN_00196938 = 0x196938; // type:func\nLoadPufferFromBrx = 0x1969C0; // type:func\nFUN_001969f8 = 0x1969F8; // type:func\nFUN_00196b78 = 0x196B78; // type:func\nFUN_00196e48 = 0x196E48; // type:func\nFUN_00196eb0 = 0x196EB0; // type:func\nPpufftChoosePuffer = 0x1971B8; // type:func\nFUN_001973d8 = 0x1973D8; // type:func\nFUN_00197458 = 0x197458; // type:func\nFUN_001974d8 = 0x1974D8; // type:func\nFUN_001974f8 = 0x1974F8; // type:func\nFUN_00197788 = 0x197788; // type:func\nFUN_00197848 = 0x197848; // type:func\nFUN_00197a08 = 0x197A08; // type:func\nFUN_00197a88 = 0x197A88; // type:func\nFUN_00197f10 = 0x197F10; // type:func\nFUN_00198090 = 0x198090; // type:func\nFUN_001980b0 = 0x1980B0; // type:func\nFUN_001982a0 = 0x1982A0; // type:func\nFUN_00198318 = 0x198318; // type:func\nFUN_001984b8 = 0x1984B8; // type:func\nFUN_00198530 = 0x198530; // type:func\nFUN_00198570 = 0x198570; // type:func\nFUN_001986e8 = 0x1986E8; // type:func\nFUN_00198760 = 0x198760; // type:func\nFUN_00198860 = 0x198860; // type:func\nFUN_00198920 = 0x198920; // type:func\nFUN_00198980 = 0x198980; // type:func\nLoadSprizeFromBrx = 0x1989B0; // type:func\nBindSprize = 0x198A88; // type:func\nFUN_00198b28 = 0x198B28; // type:func\nFUN_00198bd8 = 0x198BD8; // type:func\nFUN_00198da8 = 0x198DA8; // type:func\nEmitSprizeExplosion = 0x198E58; // type:func\nFUN_00198e98 = 0x198E98; // type:func\nHandleSprizeMessage = 0x198EF8; // type:func\nFUN_00198fb0 = 0x198FB0; // type:func\nFUN_00199000 = 0x199000; // type:func\nFUN_00199070 = 0x199070; // type:func\nFUN_001990a8 = 0x1990A8; // type:func\nPcsFromScprize = 0x1990E0; // type:func\nFUN_00199138 = 0x199138; // type:func\nLoadLockFromBrx = 0x199170; // type:func\nPostLockLoad = 0x1991A8; // type:func\nLoadLockgFromBrx = 0x1991E0; // type:func\nPostLockgLoad = 0x199218; // type:func\nFUN_001993c0 = 0x1993C0; // type:func\nFUN_001993f0 = 0x1993F0; // type:func\nLoadClueFromBrx = 0x199428; // type:func\nFUN_001994c8 = 0x1994C8; // type:func\nspawn_clue_bottleQMARK = 0x199500; // type:func\nFUN_00199698 = 0x199698; // type:func\nOnClueSmack = 0x199850; // type:func\nFUN_001999d0 = 0x1999D0; // type:func\nFUN_00199af0 = 0x199AF0; // type:func\nFUN_00199b18 = 0x199B18; // type:func\nFUN_00199c10 = 0x199C10; // type:func\nFUN_00199c58 = 0x199C58; // type:func\nFUN_00199c78 = 0x199C78; // type:func\nFUN_00199d08 = 0x199D08; // type:func\ncollect_all_clues = 0x199F38; // type:func\nset_grfvault = 0x199FF0; // type:func\nFUN_0019a000 = 0x19A000; // type:func\nunlock_all_levels_in_world = 0x19A088; // type:func\nunlock_all_worlds = 0x19A0F0; // type:func\nFUN_0019a148 = 0x19A148; // type:func\nFUN_0019a178 = 0x19A178; // type:func\nFUN_0019a1e0 = 0x19A1E0; // type:func\nFUN_0019a520 = 0x19A520; // type:func\nUpdateVaultActive = 0x19A6A8; // type:func\nFUN_0019ab78 = 0x19AB78; // type:func\nAddVaultGoadDialog = 0x19AD30; // type:func\nOpenVault = 0x19AD68; // type:func\nFUN_0019af00 = 0x19AF00; // type:func\nFUN_0019af38 = 0x19AF38; // type:func\nFUN_0019af70 = 0x19AF70; // type:func\nFUN_0019afa8 = 0x19AFA8; // type:func\nFUN_0019aff0 = 0x19AFF0; // type:func\nFUN_0019b038 = 0x19B038; // type:func\nLoadRatFromBrx = 0x19B0A0; // type:func\nFUN_0019b188 = 0x19B188; // type:func\nFUN_0019b1e0 = 0x19B1E0; // type:func\nFUN_0019b218 = 0x19B218; // type:func\nFUN_0019b250 = 0x19B250; // type:func\nFUN_0019b298 = 0x19B298; // type:func\nFUN_0019b378 = 0x19B378; // type:func\nRenderRatAll = 0x19BC40; // type:func\nFUN_0019be08 = 0x19BE08; // type:func\nChooseRatFleeTarget = 0x19BE80; // type:func\nFUN_0019c068 = 0x19C068; // type:func\nFUN_0019c1c0 = 0x19C1C0; // type:func\nFUN_0019c3d0 = 0x19C3D0; // type:func\nFUN_0019c408 = 0x19C408; // type:func\nFUN_0019c440 = 0x19C440; // type:func\nLoadRchmFromBrx = 0x19C470; // type:func\nPostRchmLoad = 0x19C728; // type:func\nFUN_0019c9c8 = 0x19C9C8; // type:func\nBuildRchmCoefficients = 0x19CC10; // type:func\nConvertRchmIposToRclIoLhub = 0x19CD90; // type:func\nFUN_0019ce28 = 0x19CE28; // type:func\nFUN_0019ce38 = 0x19CE38; // type:func\nFUN_0019ce50 = 0x19CE50; // type:func\nFUN_0019cec0 = 0x19CEC0; // type:func\nPtwrMapRchmSafe = 0x19CF68; // type:func\nFindRchmClosestPoint = 0x19D0E0; // type:func\nTrackJtTarget = 0x19D2A8; // type:func\nFUN_0019d338 = 0x19D338; // type:func\nSubmitRpl = 0x19D410; // type:func\nNCmpPrplReverseZ = 0x19D468; // type:func\nCprplPartitionArpl = 0x19D4B0; // type:func\nRenderSw = 0x19D6C0; // type:func\nEnsureRenderGlobals = 0x19D860; // type:func\nEnsureCameraGlobals = 0x19D930; // type:func\nEnsureScreenCleared = 0x19D968; // type:func\nFUN_0019da30 = 0x19DA30; // type:func\nFUN_0019da60 = 0x19DA60; // type:func\nSetupRpBlotContext = 0x19DAD8; // type:func\nFUN_0019db20 = 0x19DB20; // type:func\nFUN_0019db68 = 0x19DB68; // type:func\nFUN_0019dbb0 = 0x19DBB0; // type:func\nDrawSw = 0x19DC98; // type:func\nFillScreenRect = 0x19DDA0; // type:func\nFUN_0019df48 = 0x19DF48; // type:func\nPripgNew = 0x19E040; // type:func\nFUN_0019e0b8 = 0x19E0B8; // type:func\nFUN_0019e158 = 0x19E158; // type:func\nOnRipgRemove = 0x19E168; // type:func\nProjectRipgTransform = 0x19E220; // type:func\nUpdateRipg = 0x19E420; // type:func\nFUN_0019e558 = 0x19E558; // type:func\nRenderRipgSelf = 0x19E848; // type:func\nPvtripFromRipt = 0x19E908; // type:func\nPripNewRipg = 0x19EA78; // type:func\nInitRip = 0x19EB28; // type:func\nFUN_0019ebe8 = 0x19EBE8; // type:func\nAddRipRef = 0x19EC20; // type:func\nFUN_0019ec30 = 0x19EC30; // type:func\nFUN_0019ece0 = 0x19ECE0; // type:func\nForceRipFade = 0x19ED00; // type:func\nFBounceRip = 0x19ED58; // type:func\nFUN_0019f390 = 0x19F390; // type:func\nUpdateRip = 0x19F560; // type:func\nFUN_0019f620 = 0x19F620; // type:func\nFUN_0019f858 = 0x19F858; // type:func\nFUN_0019f8e8 = 0x19F8E8; // type:func\nFUN_0019f918 = 0x19F918; // type:func\nFUN_0019f950 = 0x19F950; // type:func\nFUN_0019f988 = 0x19F988; // type:func\nFUN_0019f9d0 = 0x19F9D0; // type:func\nFUN_0019fa98 = 0x19FA98; // type:func\nProjectBubletTransform = 0x19FB08; // type:func\nFUN_0019fce8 = 0x19FCE8; // type:func\nFUN_0019fd08 = 0x19FD08; // type:func\nFUN_0019fd70 = 0x19FD70; // type:func\nFUN_0019fdc0 = 0x19FDC0; // type:func\nFUN_0019fe10 = 0x19FE10; // type:func\nFUN_0019fe50 = 0x19FE50; // type:func\nRenderFlake = 0x19FF20; // type:func\nFUN_001a0020 = 0x1A0020; // type:func\nFUN_001a0040 = 0x1A0040; // type:func\nRenderSpark = 0x1A00A0; // type:func\nFUN_001a01b8 = 0x1A01B8; // type:func\nFUN_001a0258 = 0x1A0258; // type:func\nFUN_001a0318 = 0x1A0318; // type:func\nSetTrailTrls = 0x1A0338; // type:func\nDetachTrail = 0x1A04A0; // type:func\nFUN_001a05d8 = 0x1A05D8; // type:func\nRenderTrail = 0x1A0758; // type:func\nHandleTrailMessage = 0x1A0950; // type:func\nFUN_001a09c0 = 0x1A09C0; // type:func\nFUN_001a0a78 = 0x1A0A78; // type:func\nInitSmokecloud = 0x1A0B20; // type:func\nFUN_001a0ba0 = 0x1A0BA0; // type:func\nFUN_001a0c50 = 0x1A0C50; // type:func\nInitSmack = 0x1A0C98; // type:func\nFUN_001a0d60 = 0x1A0D60; // type:func\nRenderSmack = 0x1A0DF0; // type:func\nFUN_001a0f88 = 0x1A0F88; // type:func\nFUN_001a0fe8 = 0x1A0FE8; // type:func\nFUN_001a11c0 = 0x1A11C0; // type:func\nFUN_001a1398 = 0x1A1398; // type:func\nFUN_001a1410 = 0x1A1410; // type:func\nFUN_001a1458 = 0x1A1458; // type:func\nFUN_001a14a0 = 0x1A14A0; // type:func\nFUN_001a15d8 = 0x1A15D8; // type:func\nSetRoseRoses = 0x1A1DF0; // type:func\nFUN_001a1f40 = 0x1A1F40; // type:func\nChpBuildConvexHullXY = 0x1A2070; // type:func\nFUN_001a22e0 = 0x1A22E0; // type:func\nCreateStuck = 0x1A2380; // type:func\nFBounceFlying = 0x1A25F0; // type:func\nFUN_001a26b0 = 0x1A26B0; // type:func\nFUN_001a26f8 = 0x1A26F8; // type:func\nFUN_001a2770 = 0x1A2770; // type:func\nProjectLeafTransform = 0x1A2830; // type:func\nFUN_001a2a68 = 0x1A2A68; // type:func\nPostFlameEmit = 0x1A2B48; // type:func\nFUN_001a2d30 = 0x1A2D30; // type:func\nRenderBullet = 0x1A2D88; // type:func\nFUN_001a2e68 = 0x1A2E68; // type:func\nFUN_001a3008 = 0x1A3008; // type:func\nFUN_001a3128 = 0x1A3128; // type:func\nFUN_001a31a0 = 0x1A31A0; // type:func\nInitGlint = 0x1A31F0; // type:func\nRenderGlint = 0x1A3250; // type:func\nFUN_001a3598 = 0x1A3598; // type:func\nFUN_001a35f0 = 0x1A35F0; // type:func\nProjectMatchTransform = 0x1A3730; // type:func\nFUN_001a38f0 = 0x1A38F0; // type:func\nFUN_001a3990 = 0x1A3990; // type:func\nFUN_001a39c8 = 0x1A39C8; // type:func\nFUN_001a3a18 = 0x1A3A18; // type:func\nLoadRovFromBrx = 0x1A3B20; // type:func\nPostRovLoad = 0x1A3B58; // type:func\nUpdateRovActive = 0x1A3C40; // type:func\nFUN_001a3d40 = 0x1A3D40; // type:func\nFUN_001a3f40 = 0x1A3F40; // type:func\nRovsNextRov = 0x1A3FE0; // type:func\nFUN_001a4070 = 0x1A4070; // type:func\nRovtsNextRov = 0x1A4258; // type:func\nSetRovRovts = 0x1A42C8; // type:func\nFUN_001a43c8 = 0x1A43C8; // type:func\nFUN_001a44e8 = 0x1A44E8; // type:func\nFUN_001a4538 = 0x1A4538; // type:func\nFUN_001a45b8 = 0x1A45B8; // type:func\nPropagateRovForce = 0x1A4610; // type:func\nInitRob = 0x1A4718; // type:func\nRobkCur = 0x1A4898; // type:func\nFUN_001a48c0 = 0x1A48C0; // type:func\nFUN_001a4b30 = 0x1A4B30; // type:func\nFUN_001a4c48 = 0x1A4C48; // type:func\nFUN_001a4d60 = 0x1A4D60; // type:func\nFUN_001a4dc0 = 0x1A4DC0; // type:func\nSetRobRobs = 0x1A4EF0; // type:func\nFUN_001a5120 = 0x1A5120; // type:func\nFUN_001a54f8 = 0x1A54F8; // type:func\nFUN_001a5760 = 0x1A5760; // type:func\nFUN_001a5b28 = 0x1A5B28; // type:func\nFUN_001a5c38 = 0x1A5C38; // type:func\nFUN_001a5c90 = 0x1A5C90; // type:func\nFUN_001a5d50 = 0x1A5D50; // type:func\nReturnedRobRoh = 0x1A5DD8; // type:func\nExitedRobRoh = 0x1A5DF8; // type:func\nKilledRobRoh = 0x1A5F78; // type:func\nFUN_001a6090 = 0x1A6090; // type:func\nTakeRobRoc = 0x1A6168; // type:func\nFChooseRobRoh = 0x1A6238; // type:func\nFUN_001a6328 = 0x1A6328; // type:func\nFUN_001a63f8 = 0x1A63F8; // type:func\nInitRoh = 0x1A6498; // type:func\nLoadRohFromBrx = 0x1A64F8; // type:func\nFUN_001a6540 = 0x1A6540; // type:func\nFUN_001a6588 = 0x1A6588; // type:func\nFUN_001a65c8 = 0x1A65C8; // type:func\nMoveRohToTarget = 0x1A6788; // type:func\nFUN_001a69f8 = 0x1A69F8; // type:func\nFUN_001a6be0 = 0x1A6BE0; // type:func\nFUN_001a6de0 = 0x1A6DE0; // type:func\nFUN_001a6f28 = 0x1A6F28; // type:func\nFUN_001a6f88 = 0x1A6F88; // type:func\nLoadRocFromBrx = 0x1A7008; // type:func\nFUN_001a7050 = 0x1A7050; // type:func\nPostRocLoad = 0x1A7098; // type:func\nFUN_001a7128 = 0x1A7128; // type:func\nPresetRocAccel = 0x1A7230; // type:func\nFAbsorbRocWkr = 0x1A72B0; // type:func\nRocsNextRoc = 0x1A7420; // type:func\nSetRocRocs = 0x1A7480; // type:func\nFUN_001a7520 = 0x1A7520; // type:func\nLoadRostFromBrx = 0x1A7550; // type:func\nFUN_001a7588 = 0x1A7588; // type:func\nPostRostLoad = 0x1A75D0; // type:func\nFUN_001a7648 = 0x1A7648; // type:func\nFUN_001a7698 = 0x1A7698; // type:func\nSetRostRosts = 0x1A76A0; // type:func\nFUN_001a7708 = 0x1A7708; // type:func\nLoadRopFromBrx = 0x1A7750; // type:func\nPostRopLoad = 0x1A7798; // type:func\nUpdateRop = 0x1A7800; // type:func\nSetRopRops = 0x1A7998; // type:func\nRopsNextRop = 0x1A7AA0; // type:func\nInitRumble = 0x1A7B20; // type:func\nFUN_001a7b88 = 0x1A7B88; // type:func\nFUN_001a7ce8 = 0x1A7CE8; // type:func\nFUN_001a7d18 = 0x1A7D18; // type:func\nSetRumbleRums = 0x1A7D98; // type:func\nStopRumbleActuators = 0x1A7E40; // type:func\nvibration_flip_on = 0x1A7E70; // type:func\nreset_settings = 0x1A7E90; // type:func\nFUN_001a7ee8 = 0x1A7EE8; // type:func\nFUN_001a7f50 = 0x1A7F50; // type:func\nInitRwm = 0x1A7FE8; // type:func\nFUN_001a80e0 = 0x1A80E0; // type:func\nFUN_001a8110 = 0x1A8110; // type:func\nFUN_001a8150 = 0x1A8150; // type:func\nFUN_001a8208 = 0x1A8208; // type:func\nFUN_001a84c8 = 0x1A84C8; // type:func\nFUN_001a8590 = 0x1A8590; // type:func\nFUN_001a86f8 = 0x1A86F8; // type:func\nFUN_001a8718 = 0x1A8718; // type:func\nFUN_001a8778 = 0x1A8778; // type:func\nFUN_001a87a8 = 0x1A87A8; // type:func\nFUN_001a87e0 = 0x1A87E0; // type:func\nFUN_001a8820 = 0x1A8820; // type:func\nFUN_001a88a0 = 0x1A88A0; // type:func\nFUN_001a89e8 = 0x1A89E8; // type:func\nFUN_001a8af8 = 0x1A8AF8; // type:func\nFUN_001a8c50 = 0x1A8C50; // type:func\nFUN_001a8c90 = 0x1A8C90; // type:func\nFUN_001a93c8 = 0x1A93C8; // type:func\nFUN_001a93e8 = 0x1A93E8; // type:func\nFUN_001a9438 = 0x1A9438; // type:func\nFUN_001a9498 = 0x1A9498; // type:func\nFUN_001a94c0 = 0x1A94C0; // type:func\nFUN_001a95d0 = 0x1A95D0; // type:func\nFUN_001a97c8 = 0x1A97C8; // type:func\nFUN_001a9868 = 0x1A9868; // type:func\nFUN_001a98f8 = 0x1A98F8; // type:func\nFUN_001a9928 = 0x1A9928; // type:func\nFUN_001a9960 = 0x1A9960; // type:func\nFUN_001a99b8 = 0x1A99B8; // type:func\nFUN_001a99f8 = 0x1A99F8; // type:func\nFUN_001a9a40 = 0x1A9A40; // type:func\nFUN_001a9a98 = 0x1A9A98; // type:func\nFUN_001a9ae8 = 0x1A9AE8; // type:func\nFUN_001a9c58 = 0x1A9C58; // type:func\nStartupScreen = 0x1A9C68; // type:func\nPostBlotsLoad = 0x1A9F78; // type:func\nFUN_001a9fd0 = 0x1A9FD0; // type:func\nForceHideBlots = 0x1AA060; // type:func\nForceHideBlots1 = 0x1AA0C0; // type:func\nRenderBlots = 0x1AA110; // type:func\nDrawBlots = 0x1AA178; // type:func\nInitBlot = 0x1AA1F0; // type:func\nPostBlotLoad = 0x1AA268; // type:func\nUpdateBlot = 0x1AA298; // type:func\nSetBlotAchzDraw = 0x1AA4F0; // type:func\nFUN_001aa5a0 = 0x1AA5A0; // type:func\nSetBlotFontScale = 0x1AA788; // type:func\nFUN_001aa790 = 0x1AA790; // type:func\nDtAppearBlot = 0x1AA898; // type:func\nDtVisibleBlot = 0x1AA8A0; // type:func\nDtDisappearBlot = 0x1AA8A8; // type:func\nSetBlotDtAppear = 0x1AA8B0; // type:func\nSetBlotDtVisible = 0x1AA8B8; // type:func\nSetBlotDtDisappear = 0x1AA8C0; // type:func\nOnBlotReset = 0x1AA8C8; // type:func\nShowBlot = 0x1AA8F0; // type:func\nHideBlot = 0x1AA958; // type:func\nSetBlotBlots = 0x1AA998; // type:func\npfnFIncludeBlotForPeg = 0x1AAAC8; // type:func\nFUN_001aab20 = 0x1AAB20; // type:func\nRepositionBlot = 0x1AAB60; // type:func\nRepositionBlotDependents = 0x1AAEC0; // type:func\nSetBlotClock = 0x1AAF58; // type:func\nPostCtrLoad = 0x1AAF88; // type:func\nUpdateCtr = 0x1AB058; // type:func\nDrawCtr = 0x1AB198; // type:func\nFUN_001ab2b8 = 0x1AB2B8; // type:func\nDtVisibleCtr = 0x1AB5D8; // type:func\nFUN_001ab600 = 0x1AB600; // type:func\nFUN_001ab660 = 0x1AB660; // type:func\nDrawTimer = 0x1AB710; // type:func\nFUN_001ab890 = 0x1AB890; // type:func\nSetTimerSpeed = 0x1AB920; // type:func\nSetTimerExpire = 0x1AB928; // type:func\nFUN_001ab938 = 0x1AB938; // type:func\nFUN_001ab958 = 0x1AB958; // type:func\nRebuildTimerAchzDraw = 0x1AB980; // type:func\nFUN_001abe20 = 0x1ABE20; // type:func\ndtvisible_unk_zero_1 = 0x1ABE40; // type:func\ndtvisible_unk_always_zero = 0x1ABE50; // type:func\nFUN_001abe70 = 0x1ABE70; // type:func\nFUN_001ac060 = 0x1AC060; // type:func\nFUN_001ac0e8 = 0x1AC0E8; // type:func\nPostNoteLoad = 0x1AC5C0; // type:func\nSetNoteAchzDraw = 0x1AC638; // type:func\nDrawNote = 0x1AC700; // type:func\nFUN_001ac888 = 0x1AC888; // type:func\nFUN_001ac910 = 0x1AC910; // type:func\nFUN_001ac990 = 0x1AC990; // type:func\nFUN_001ac9e0 = 0x1AC9E0; // type:func\nFUN_001aca30 = 0x1ACA30; // type:func\nFUN_001aca68 = 0x1ACA68; // type:func\nDrawTitle = 0x1ACAA8; // type:func\nPostTotalsLoad = 0x1ACDA0; // type:func\nFUN_001ace38 = 0x1ACE38; // type:func\nFUN_001acee0 = 0x1ACEE0; // type:func\nrender_level_info_from_id = 0x1AD088; // type:func\nrender_level_info = 0x1AD0D0; // type:func\nrender_hideout_world_info = 0x1AD1E8; // type:func\nSetTotalsBlots = 0x1AD320; // type:func\nShowTotalsQMARK = 0x1AD378; // type:func\nHideTotalsQMARK = 0x1AD3B0; // type:func\nDrawTotals = 0x1AD3F0; // type:func\nFUN_001ad6a8 = 0x1AD6A8; // type:func\nFUN_001ad718 = 0x1AD718; // type:func\nFUN_001ad7b0 = 0x1AD7B0; // type:func\nFUN_001ad940 = 0x1AD940; // type:func\nFUN_001ad970 = 0x1AD970; // type:func\nDrawLetterbox = 0x1ADB00; // type:func\nFUN_001adc60 = 0x1ADC60; // type:func\nDrawLogo = 0x1ADD28; // type:func\nFUN_001adf28 = 0x1ADF28; // type:func\nFUN_001adff0 = 0x1ADFF0; // type:func\nFUN_001ae130 = 0x1AE130; // type:func\nFUN_001ae178 = 0x1AE178; // type:func\nDrawLineScreen = 0x1AE3B8; // type:func\nFUN_001ae510 = 0x1AE510; // type:func\nFUN_001ae758 = 0x1AE758; // type:func\nFUN_001ae7f8 = 0x1AE7F8; // type:func\nFUN_001ae820 = 0x1AE820; // type:func\nFUN_001aea08 = 0x1AEA08; // type:func\nFUN_001aea70 = 0x1AEA70; // type:func\nFUN_001aecb0 = 0x1AECB0; // type:func\nSetSensorSensors = 0x1AECE8; // type:func\nFCheckSensorObject = 0x1AED78; // type:func\nFIgnoreSensorObject = 0x1AEE50; // type:func\nFUN_001aef00 = 0x1AEF00; // type:func\nFUN_001aef68 = 0x1AEF68; // type:func\nFUN_001aefa0 = 0x1AEFA0; // type:func\nFUN_001af0a0 = 0x1AF0A0; // type:func\nLoadLasenFromBrx = 0x1AF0D0; // type:func\nFUN_001af108 = 0x1AF108; // type:func\nFUN_001af3b8 = 0x1AF3B8; // type:func\nUpdateBusyLasenSenseTimes = 0x1AF508; // type:func\nUpdateLasen = 0x1AF5C8; // type:func\nFreezeLasen = 0x1AF7A8; // type:func\nFUN_001af820 = 0x1AF820; // type:func\nFUN_001afaf8 = 0x1AFAF8; // type:func\nFUN_001afbb0 = 0x1AFBB0; // type:func\nFUN_001b00e8 = 0x1B00E8; // type:func\nDisableLasen = 0x1B0120; // type:func\nOnLasenAlarmTriggered = 0x1B0160; // type:func\nFUN_001b01b0 = 0x1B01B0; // type:func\nSCalcLasenShapeExtent = 0x1B0360; // type:func\nFUN_001b0470 = 0x1B0470; // type:func\nFUN_001b0488 = 0x1B0488; // type:func\nFUN_001b04a0 = 0x1B04A0; // type:func\nPostCamsenLoad = 0x1B04D0; // type:func\nFUN_001b0578 = 0x1B0578; // type:func\nFUN_001b0838 = 0x1B0838; // type:func\nFUN_001b0be0 = 0x1B0BE0; // type:func\nFUN_001b0c68 = 0x1B0C68; // type:func\nFUN_001b0ea8 = 0x1B0EA8; // type:func\nFUN_001b0ee0 = 0x1B0EE0; // type:func\nOnCamsenAlarmTriggered = 0x1B0F70; // type:func\nSetCamsenSensors = 0x1B0FC0; // type:func\nSetCamsenCsdts = 0x1B1070; // type:func\nFUN_001b1158 = 0x1B1158; // type:func\nFUN_001b11a0 = 0x1B11A0; // type:func\nUpdatePrsen = 0x1B1238; // type:func\nSensePrsen = 0x1B1438; // type:func\nFUN_001b15d0 = 0x1B15D0; // type:func\nFUN_001b1608 = 0x1B1608; // type:func\nOnPrsenAlarmTriggered = 0x1B1698; // type:func\nSetPrsenSensors = 0x1B1710; // type:func\nUpdatePrsenLoopShader = 0x1B1898; // type:func\nInitShadow = 0x1B1AC8; // type:func\nPostShadowLoad = 0x1B1B38; // type:func\nInvalidateShadowVifs = 0x1B1BF0; // type:func\nRebuildShadowRegion = 0x1B1BF8; // type:func\nFUN_001b1cf8 = 0x1B1CF8; // type:func\nFShadowRadiusSet = 0x1B1D38; // type:func\nSetShadowNearRadius = 0x1B1D70; // type:func\nSetShadowFarRadius = 0x1B1DA8; // type:func\nSetShadowCastPosition = 0x1B1DE0; // type:func\nSetShadowCastNormal = 0x1B1EC8; // type:func\nFUN_001b1fb0 = 0x1B1FB0; // type:func\nFUN_001b1fe0 = 0x1B1FE0; // type:func\nFUN_001b2010 = 0x1B2010; // type:func\nSetShadowFrustrumUp = 0x1B2068; // type:func\nFShadowValid = 0x1B2090; // type:func\nUpdateShadow = 0x1B2140; // type:func\nFUN_001b2358 = 0x1B2358; // type:func\nFUN_001b2640 = 0x1B2640; // type:func\nFShadowIntersectsSphere = 0x1B26F8; // type:func\nFUN_001b2790 = 0x1B2790; // type:func\nLoadShapeFromBrx = 0x1B2840; // type:func\nSetShapeParent = 0x1B28A8; // type:func\nTex0FromTexIframeCtk = 0x1B2988; // type:func\nPackTexGifs = 0x1B29E0; // type:func\nLoadClutFromBrx = 0x1B2B50; // type:func\nLoadColorTablesFromBrx = 0x1B2BA8; // type:func\nLoadBmpFromBrx = 0x1B2CA8; // type:func\nLoadBitmapsFromBrx = 0x1B2CF8; // type:func\nLoadFontsFromBrx = 0x1B2DF8; // type:func\nLoadTexFromBrx = 0x1B2F00; // type:func\nLoadShadersFromBrx = 0x1B3040; // type:func\nUploadPermShaders = 0x1B3450; // type:func\nPropagateShaders = 0x1B3488; // type:func\nFillShaders = 0x1B3510; // type:func\nUnloadShaders = 0x1B40C8; // type:func\nConvertRgbToHsv = 0x1B4188; // type:func\nConvertHsvToRgb = 0x1B4330; // type:func\nFUN_001b4580 = 0x1B4580; // type:func\nFUN_001b4600 = 0x1B4600; // type:func\nPshdFindShader = 0x1B4688; // type:func\nSetSaiIframe = 0x1B46E0; // type:func\nSetSaiDuDv = 0x1B4750; // type:func\nPropagateSais = 0x1B47C0; // type:func\nUpdateShaders = 0x1B4878; // type:func\nCbFromSaak = 0x1B4920; // type:func\nPvtsaaFromSaak = 0x1B4980; // type:func\nPsaaLoadFromBrx = 0x1B4A10; // type:func\nInitSaa = 0x1B4AA0; // type:func\nFUN_001b4ad0 = 0x1B4AD0; // type:func\nFUpdatableSaa = 0x1B4B08; // type:func\nPsaiFromSaaShd = 0x1B4B48; // type:func\nFUN_001b4b68 = 0x1B4B68; // type:func\nFUN_001b4bc8 = 0x1B4BC8; // type:func\nUpdateLoop = 0x1B4C30; // type:func\nFUN_001b4d48 = 0x1B4D48; // type:func\nFUN_001b4da8 = 0x1B4DA8; // type:func\nUpdatePingpong = 0x1B4E18; // type:func\nFUN_001b4f80 = 0x1B4F80; // type:func\nFUN_001b4fc0 = 0x1B4FC0; // type:func\nInitHologram = 0x1B5060; // type:func\nFUN_001b5108 = 0x1B5108; // type:func\nNotifyHologramRender = 0x1B5160; // type:func\nFUN_001b5200 = 0x1B5200; // type:func\nFUN_001b5278 = 0x1B5278; // type:func\nSetScrollerMasterSpeeds = 0x1B5388; // type:func\nFUN_001b5398 = 0x1B5398; // type:func\nFUN_001b5400 = 0x1B5400; // type:func\nFUN_001b5488 = 0x1B5488; // type:func\nFUN_001b54d0 = 0x1B54D0; // type:func\nSetVecPosad = 0x1B5588; // type:func\nSetUvPuvqd = 0x1B55A8; // type:func\nFUN_001b55c0 = 0x1B55C0; // type:func\nFUN_001b5b58 = 0x1B5B58; // type:func\nFUN_001b5c40 = 0x1B5C40; // type:func\nFUN_001b5cd8 = 0x1B5CD8; // type:func\nFUN_001b5d28 = 0x1B5D28; // type:func\nFUN_001b5d80 = 0x1B5D80; // type:func\nCreateSlotheapSw = 0x1B5DD0; // type:func\nFUN_001b5e30 = 0x1B5E30; // type:func\nPvAllocSlotheapUnsafe = 0x1B5EA0; // type:func\nFUN_001b5ec0 = 0x1B5EC0; // type:func\nPvAllocSlotheapClearImpl = 0x1B5EE0; // type:func\nFreeSlotheapPv = 0x1B5F28; // type:func\nLoadSmFromBrx = 0x1B5F50; // type:func\nFUN_001b61a8 = 0x1B61A8; // type:func\nPostSmLoadCallback = 0x1B61F0; // type:func\nPsmaApplySm = 0x1B6290; // type:func\nFUN_001b6388 = 0x1B6388; // type:func\nIsmsFindSmOptional = 0x1B63C0; // type:func\nIsmsFindSmRequired = 0x1B63F8; // type:func\nOidFromSmIsms = 0x1B6420; // type:func\nRetractSma = 0x1B6438; // type:func\nSetSmaGoal = 0x1B64D8; // type:func\nFUN_001b6568 = 0x1B6568; // type:func\nFUN_001b6598 = 0x1B6598; // type:func\nFUN_001b65f8 = 0x1B65F8; // type:func\nSeekSma = 0x1B6628; // type:func\nChooseSmaTransition = 0x1B66A0; // type:func\nEndSmaTransition = 0x1B6C68; // type:func\nHandleSmaMessage = 0x1B6CA8; // type:func\nFUN_001b6cf0 = 0x1B6CF0; // type:func\nSendSmaMessage = 0x1B6D78; // type:func\nFUN_001b6df8 = 0x1B6DF8; // type:func\nNotifySmaSpliceOnEnterState = 0x1B6E28; // type:func\nFUN_001b6ec8 = 0x1B6EC8; // type:func\nFUN_001b6f50 = 0x1B6F50; // type:func\nFUN_001b70b0 = 0x1B70B0; // type:func\nFUN_001b7128 = 0x1B7128; // type:func\nFUN_001b71c8 = 0x1B71C8; // type:func\nFUN_001b7280 = 0x1B7280; // type:func\nFUN_001b7608 = 0x1B7608; // type:func\nFUN_001b7638 = 0x1B7638; // type:func\nOnSmartguardEnteringSgs = 0x1B7790; // type:func\nFUN_001b7818 = 0x1B7818; // type:func\nFUN_001b78c0 = 0x1B78C0; // type:func\nFUN_001b7920 = 0x1B7920; // type:func\nInitSo = 0x1B7968; // type:func\nOnSoAdd = 0x1B7A98; // type:func\nOnSoRemove = 0x1B7B78; // type:func\nEnableSoPhys = 0x1B7C40; // type:func\nDisplaceSo = 0x1B7D00; // type:func\nImpactSo = 0x1B7F78; // type:func\nFUN_001b8148 = 0x1B8148; // type:func\nExtendSoBounds = 0x1B8420; // type:func\nUpdateSoBounds = 0x1B8540; // type:func\nUpdateGeomWorld = 0x1B8820; // type:func\nFUN_001b8960 = 0x1B8960; // type:func\nFUN_001b89b8 = 0x1B89B8; // type:func\nFCanStepguardAttack = 0x1B8A08; // type:func\nUpdateSoImpacts = 0x1B8A48; // type:func\nUProjectVector = 0x1B8B30; // type:func\nFUN_001b8b90 = 0x1B8B90; // type:func\nCalculateSoAngularEffectWorld = 0x1B8FE8; // type:func\nFUN_001b9058 = 0x1B9058; // type:func\nAccelSoTowardMatSpring = 0x1B91A8; // type:func\nPresetSoAccel = 0x1B9338; // type:func\nFUN_001b93d8 = 0x1B93D8; // type:func\nUpdateSo = 0x1B93F8; // type:func\nSetSoMass = 0x1B9418; // type:func\nAdjustSoMomint = 0x1B9448; // type:func\nDiscardSoXps = 0x1B94F0; // type:func\nUpdateSoPosWorldPrev = 0x1B9680; // type:func\nTranslateSoToPos = 0x1B9690; // type:func\nRotateSoToMat = 0x1B97E0; // type:func\nTranslateSoToPosSafe = 0x1B9860; // type:func\nFUN_001b99f0 = 0x1B99F0; // type:func\nFUN_001b9ab0 = 0x1B9AB0; // type:func\nAddSoAcceleration = 0x1B9AC8; // type:func\nFUN_001b9ae0 = 0x1B9AE0; // type:func\nSetSoParent = 0x1B9B50; // type:func\nApplySoProxy = 0x1B9C80; // type:func\nAccelSoTowardMatSmooth = 0x1B9D10; // type:func\nFUN_001b9f30 = 0x1B9F30; // type:func\nFUN_001b9fb0 = 0x1B9FB0; // type:func\nFUN_001ba068 = 0x1BA068; // type:func\nCloneSo = 0x1BA130; // type:func\nApplySoConstraintWorld = 0x1BA2E8; // type:func\nApplyConstr = 0x1BA430; // type:func\nFUN_001ba500 = 0x1BA500; // type:func\nFUN_001ba528 = 0x1BA528; // type:func\nFUN_001ba550 = 0x1BA550; // type:func\nFUN_001ba5b0 = 0x1BA5B0; // type:func\nLoadSOFromBrx = 0x1BAC30; // type:func\nFUN_001bb000 = 0x1BB000; // type:func\nConstrFromCnstr = 0x1BB028; // type:func\nFUN_001bb058 = 0x1BB058; // type:func\nFUN_001bb0c8 = 0x1BB0C8; // type:func\nFUN_001bb1e0 = 0x1BB1E0; // type:func\nSendSoMessage = 0x1BB210; // type:func\nPxpFindSoGround = 0x1BB290; // type:func\nFUN_001bb3b0 = 0x1BB3B0; // type:func\nFUN_001bb400 = 0x1BB400; // type:func\nFUN_001bb450 = 0x1BB450; // type:func\nFUN_001bb4a0 = 0x1BB4A0; // type:func\nPsoFindSoPhysHook = 0x1BB540; // type:func\nFUN_001bb580 = 0x1BB580; // type:func\nFUN_001bb710 = 0x1BB710; // type:func\nFUN_001bb800 = 0x1BB800; // type:func\nFSoInStsoList = 0x1BB9A0; // type:func\nGenerateSoSpliceTouchingEvents = 0x1BB9D0; // type:func\nEnsureSoLvo = 0x1BBC38; // type:func\nProjectSoLvo = 0x1BBEB8; // type:func\nProjectSoTransform = 0x1BC088; // type:func\nApplySoImpulse = 0x1BC0E0; // type:func\nFUN_001bc260 = 0x1BC260; // type:func\nFAbsorbSoWkr = 0x1BC320; // type:func\nCloneSoPhys = 0x1BC368; // type:func\nFUN_001bc4d8 = 0x1BC4D8; // type:func\nFUN_001bc670 = 0x1BC670; // type:func\nRenumberSo = 0x1BC760; // type:func\nCalculateSoEffect = 0x1BC7F8; // type:func\nPropagateSoForce = 0x1BC828; // type:func\nDistributeSoEffects = 0x1BC978; // type:func\nFUN_001bcd00 = 0x1BCD00; // type:func\nCpxpBuildXpArray = 0x1BD558; // type:func\nBuildContactGroup = 0x1BD678; // type:func\nSplitSoFreeze = 0x1BD790; // type:func\nSortSwGroup = 0x1BD888; // type:func\nFUN_001bda50 = 0x1BDA50; // type:func\nSolveSw = 0x1BDD00; // type:func\nSwapEntries = 0x1BE068; // type:func\nHeapSort = 0x1BE0A8; // type:func\nUnloadMusic = 0x1BE1E8; // type:func\nSbpEnsureBank = 0x1BE268; // type:func\nSbpEnsureBank1 = 0x1BE4A8; // type:func\nFUN_001be4d8 = 0x1BE4D8; // type:func\nFContinuousSound = 0x1BE568; // type:func\nFUN_001be5e8 = 0x1BE5E8; // type:func\nFUN_001be5f8 = 0x1BE5F8; // type:func\nFUN_001be708 = 0x1BE708; // type:func\nPreloadVag = 0x1BE728; // type:func\nFPauseForVag = 0x1BE810; // type:func\nRefreshPambVolPan = 0x1BE860; // type:func\nFUN_001be8f8 = 0x1BE8F8; // type:func\nFVagPlaying = 0x1BE980; // type:func\nStopVag = 0x1BE998; // type:func\nFUN_001bea28 = 0x1BEA28; // type:func\nFUN_001bea50 = 0x1BEA50; // type:func\nKillMusic = 0x1BEA78; // type:func\nPreloadMusidSongComplete = 0x1BEAC8; // type:func\nPreloadMusidSong = 0x1BEB10; // type:func\nStartMusidSong = 0x1BEC58; // type:func\nPauseMusic = 0x1BECF8; // type:func\nContinueMusic = 0x1BED20; // type:func\nFUN_001bed48 = 0x1BED48; // type:func\nFUN_001bed70 = 0x1BED70; // type:func\nFUN_001bed98 = 0x1BED98; // type:func\nFUN_001bedf8 = 0x1BEDF8; // type:func\nKillExcitement = 0x1BEE48; // type:func\nPexcSetExcitement = 0x1BEEF8; // type:func\nSetIexcCurHigh = 0x1BEF88; // type:func\nUnsetExcitement = 0x1BF048; // type:func\nFUN_001bf0d8 = 0x1BF0D8; // type:func\nFUN_001bf130 = 0x1BF130; // type:func\nFUN_001bf1f0 = 0x1BF1F0; // type:func\nCalculateVolPan = 0x1BF200; // type:func\nPposEar = 0x1BF3D0; // type:func\nSetDoppler = 0x1BF428; // type:func\nFUN_001bf578 = 0x1BF578; // type:func\nFUN_001bf5e0 = 0x1BF5E0; // type:func\nFUN_001bf620 = 0x1BF620; // type:func\nPambAlloc = 0x1BF6B8; // type:func\nDropPamb = 0x1BF718; // type:func\nRemoveAmb = 0x1BF728; // type:func\nStopSound = 0x1BF788; // type:func\nSetPambFrq = 0x1BF7F8; // type:func\nFUN_001bf8e8 = 0x1BF8E8; // type:func\nincrements_sly_anim_counter = 0x1BF920; // type:func\nFUN_001bfaf8 = 0x1BFAF8; // type:func\nScheduleNextIntermittentSound = 0x1BFBF8; // type:func\nStartSound = 0x1BFCD8; // type:func\nVIFE__DrawPrelit = 0x1C0000; // type:func\nUpdateSounds = 0x1C0070; // type:func\n989snd_related__ = 0x1C05D0; // type:func\nSetMvgkUvol = 0x1C0600; // type:func\nSetMvgkRvol = 0x1C06A0; // type:func\nFUN_001c06d8 = 0x1C06D8; // type:func\nFUN_001c0760 = 0x1C0760; // type:func\nFUN_001c0790 = 0x1C0790; // type:func\nKillSoundSystem = 0x1C07B0; // type:func\nKillSounds = 0x1C0808; // type:func\nFUN_001c08b0 = 0x1C08B0; // type:func\nFUN_001c0950 = 0x1C0950; // type:func\nFUN_001c09d8 = 0x1C09D8; // type:func\nStartSwIntermittentSounds = 0x1C0B38; // type:func\nFUN_001c0c08 = 0x1C0C08; // type:func\nFUN_001c0c50 = 0x1C0C50; // type:func\nFUN_001c0c68 = 0x1C0C68; // type:func\nFUN_001c0cb0 = 0x1C0CB0; // type:func\nFUN_001c0cf0 = 0x1C0CF0; // type:func\nNextSneakyFootstep = 0x1C0EC0; // type:func\nInitSpeakerQMARK = 0x1C0F30; // type:func\nFUN_001c0ff0 = 0x1C0FF0; // type:func\nFUN_001c1030 = 0x1C1030; // type:func\nFUN_001c10a8 = 0x1C10A8; // type:func\nFUN_001c10d8 = 0x1C10D8; // type:func\nFUN_001c1110 = 0x1C1110; // type:func\nFUN_001c1148 = 0x1C1148; // type:func\nLoadSwSpliceFromBrx = 0x1C1190; // type:func\nPframeFromIsplice = 0x1C1390; // type:func\nFUN_001c13e8 = 0x1C13E8; // type:func\nPeopidFind = 0x1C14C0; // type:func\nFUN_001c1530 = 0x1C1530; // type:func\nFUN_001c15d8 = 0x1C15D8; // type:func\nFAppendSpliceListElement = 0x1C1A28; // type:func\nFUN_001c1ad8 = 0x1C1AD8; // type:func\nRefSetPvsFromSplice = 0x1C1BF8; // type:func\nRefSetArgListFromPvs = 0x1C1E48; // type:func\nRefSetPeopid = 0x1C1F20; // type:func\nRefGetOption = 0x1C21A0; // type:func\nRefSetOption = 0x1C2238; // type:func\nFUN_001c22b8 = 0x1C22B8; // type:func\nFUN_001c2320 = 0x1C2320; // type:func\nRefSetArgsFromSplice = 0x1C23B0; // type:func\nLoadSprBuf = 0x1C2430; // type:func\nSaveSprBuf = 0x1C25B0; // type:func\nFUN_001c27b0 = 0x1C27B0; // type:func\nFUN_001c29c8 = 0x1C29C8; // type:func\nFUN_001c29e8 = 0x1C29E8; // type:func\nFUN_001c29f8 = 0x1C29F8; // type:func\nFUN_001c3028 = 0x1C3028; // type:func\nFUN_001c30e8 = 0x1C30E8; // type:func\nFUN_001c3390 = 0x1C3390; // type:func\nFUN_001c33c8 = 0x1C33C8; // type:func\nFUN_001c34c8 = 0x1C34C8; // type:func\nFUN_001c3928 = 0x1C3928; // type:func\nFUN_001c39a0 = 0x1C39A0; // type:func\nFUN_001c3b40 = 0x1C3B40; // type:func\nFUN_001c3c00 = 0x1C3C00; // type:func\nFUN_001c3d28 = 0x1C3D28; // type:func\nFUN_001c3d60 = 0x1C3D60; // type:func\nFUN_001c3e80 = 0x1C3E80; // type:func\nFUN_001c3eb0 = 0x1C3EB0; // type:func\nFUN_001c3f68 = 0x1C3F68; // type:func\nFUN_001c3fc8 = 0x1C3FC8; // type:func\nFUN_001c4180 = 0x1C4180; // type:func\nFUN_001c41a0 = 0x1C41A0; // type:func\nInitStep = 0x1C4458; // type:func\nPostStepLoad = 0x1C44F0; // type:func\nLimitStepHands = 0x1C4578; // type:func\nFUN_001c4618 = 0x1C4618; // type:func\nFUN_001c4790 = 0x1C4790; // type:func\nFUN_001c4848 = 0x1C4848; // type:func\nFUN_001c49c8 = 0x1C49C8; // type:func\nReadStepJoystick = 0x1C49E8; // type:func\nUpdateStepFootfall = 0x1C4A80; // type:func\nUpdateStepPhys = 0x1C4C20; // type:func\nFUN_001c4d60 = 0x1C4D60; // type:func\nUpdateStep = 0x1C4ED0; // type:func\nFUN_001c4f08 = 0x1C4F08; // type:func\nFUN_001c4fa0 = 0x1C4FA0; // type:func\nFUN_001c4ff8 = 0x1C4FF8; // type:func\nFUN_001c5118 = 0x1C5118; // type:func\nPresetStepAccelBase = 0x1C5148; // type:func\nFCheckStepXpBase = 0x1C5248; // type:func\nAdjustStepNewXp = 0x1C5338; // type:func\nFUN_001c5388 = 0x1C5388; // type:func\nFUN_001c53a8 = 0x1C53A8; // type:func\nFUN_001c53b0 = 0x1C53B0; // type:func\nFUN_001c53e0 = 0x1C53E0; // type:func\nUpdateStepXfWorld = 0x1C5438; // type:func\nAdjustStepXpVelocityBase = 0x1C54D0; // type:func\nFUN_001c57c8 = 0x1C57C8; // type:func\nFUN_001c5bf0 = 0x1C5BF0; // type:func\nAddStepCustomXpsBase = 0x1C5C10; // type:func\nFUN_001c5d58 = 0x1C5D58; // type:func\nFUN_001c5db8 = 0x1C5DB8; // type:func\nSetStepSpinRatio = 0x1C5E50; // type:func\nFUN_001c5ea8 = 0x1C5EA8; // type:func\nGetActaddPositionGoal = 0x1C5F18; // type:func\nGetActaddRotationGoal = 0x1C6028; // type:func\nSetJtJtcs = 0x1C61E0; // type:func\nFUN_001c6890 = 0x1C6890; // type:func\nFUN_001c6928 = 0x1C6928; // type:func\nFUN_001c6aa8 = 0x1C6AA8; // type:func\nChooseJtSweepTarget = 0x1C6D00; // type:func\nFUN_001c6e58 = 0x1C6E58; // type:func\nFUN_001c6ed0 = 0x1C6ED0; // type:func\nFUN_001c6f48 = 0x1C6F48; // type:func\nLoadStepguardFromBrx = 0x1C7140; // type:func\nFUN_001c7188 = 0x1C7188; // type:func\nBindStepguard = 0x1C71E0; // type:func\nPostStepguardLoadCallback = 0x1C7278; // type:func\nFUN_001c72a0 = 0x1C72A0; // type:func\nFCanSmartguardAttack = 0x1C7468; // type:func\nFUN_001c74e8 = 0x1C74E8; // type:func\nFUN_001c7520 = 0x1C7520; // type:func\nFUN_001c75b0 = 0x1C75B0; // type:func\nFUN_001c7a60 = 0x1C7A60; // type:func\nFUN_001c7ae0 = 0x1C7AE0; // type:func\nFUN_001c7b60 = 0x1C7B60; // type:func\nUpdateStepguardDrive = 0x1C7BE8; // type:func\nFUN_001c7cb8 = 0x1C7CB8; // type:func\nSgsNextStepguardAI = 0x1C8010; // type:func\nSetStepguardGoal = 0x1C8418; // type:func\nFReachedStepguardGoal = 0x1C84C0; // type:func\nFFilterStepguardJump = 0x1C84E8; // type:func\nFUN_001c8590 = 0x1C8590; // type:func\nFUN_001c8920 = 0x1C8920; // type:func\nFUN_001c8bc0 = 0x1C8BC0; // type:func\nFUN_001c8c08 = 0x1C8C08; // type:func\nOnStepguardWaypointActive = 0x1C8D78; // type:func\nUpdateStepguardSgs = 0x1C8E28; // type:func\nSetStepguardSgs = 0x1C8F20; // type:func\nFUN_001c8fd0 = 0x1C8FD0; // type:func\nFUN_001c9008 = 0x1C9008; // type:func\nFUN_001c91c8 = 0x1C91C8; // type:func\nFUN_001c96b8 = 0x1C96B8; // type:func\nFUN_001c96d8 = 0x1C96D8; // type:func\nFUN_001c9990 = 0x1C9990; // type:func\nFUN_001c9a48 = 0x1C9A48; // type:func\nHandleStepguardGrfsgsc = 0x1C9A58; // type:func\nFUN_001c9af8 = 0x1C9AF8; // type:func\nFUN_001c9cf8 = 0x1C9CF8; // type:func\nFUN_001c9d50 = 0x1C9D50; // type:func\nFUN_001c9de0 = 0x1C9DE0; // type:func\nFUN_001ca468 = 0x1CA468; // type:func\nFUN_001ca5e0 = 0x1CA5E0; // type:func\nFValidSgs = 0x1CA600; // type:func\nFUN_001ca608 = 0x1CA608; // type:func\nFUN_001ca658 = 0x1CA658; // type:func\nFUN_001ca6d0 = 0x1CA6D0; // type:func\nFUN_001ca720 = 0x1CA720; // type:func\nPasegFindStepguard = 0x1CA758; // type:func\nLoadStepguardAnimations = 0x1CA7C0; // type:func\nFUN_001ca898 = 0x1CA898; // type:func\nLoadStepguardPhys = 0x1CA8E8; // type:func\nFUN_001ca960 = 0x1CA960; // type:func\nFUN_001ca998 = 0x1CA998; // type:func\nFUN_001caa08 = 0x1CAA08; // type:func\nFUN_001caad0 = 0x1CAAD0; // type:func\nRebindStepguardEnemy = 0x1CAB10; // type:func\nFUN_001cac28 = 0x1CAC28; // type:func\nFUN_001cac30 = 0x1CAC30; // type:func\nFUN_001cacb0 = 0x1CACB0; // type:func\nAddStepguardAlarm = 0x1CAD40; // type:func\nMatchStepguardAnimationPhase = 0x1CAD60; // type:func\nFUN_001cad98 = 0x1CAD98; // type:func\nFUN_001caee0 = 0x1CAEE0; // type:func\nFUN_001caf38 = 0x1CAF38; // type:func\nSetStepguardPatrolAnimation = 0x1CB328; // type:func\nFUN_001cb3d0 = 0x1CB3D0; // type:func\nFUN_001cb578 = 0x1CB578; // type:func\nFUN_001cb5b8 = 0x1CB5B8; // type:func\nFUN_001cb618 = 0x1CB618; // type:func\nFUN_001cb648 = 0x1CB648; // type:func\nFUN_001cb6f8 = 0x1CB6F8; // type:func\nBindSgg = 0x1CB7A0; // type:func\nPostSggLoadCallback = 0x1CB8B8; // type:func\nEnsureSggCallback = 0x1CBAA0; // type:func\nPsoEnemySgg = 0x1CBAF8; // type:func\nFUN_001cbb20 = 0x1CBB20; // type:func\nFUN_001cbb88 = 0x1CBB88; // type:func\nFUN_001cbcb8 = 0x1CBCB8; // type:func\nFAbandonSggSearch = 0x1CBD58; // type:func\nEnsureSggAlarm = 0x1CBE20; // type:func\nTriggerSggAlarms = 0x1CBE70; // type:func\nSetSggSggs = 0x1CBEE8; // type:func\nFUN_001cc120 = 0x1CC120; // type:func\nFUN_001cc410 = 0x1CC410; // type:func\nFUN_001cc490 = 0x1CC490; // type:func\nCalculateJtHangAccel = 0x1CC818; // type:func\nPresetJtAccelHang = 0x1CCF98; // type:func\nFUN_001cd088 = 0x1CD088; // type:func\nFUN_001cd0c8 = 0x1CD0C8; // type:func\nCheckJtUnhook = 0x1CD6C0; // type:func\nUpdateJtHookOx = 0x1CD7E0; // type:func\nAddJtHookXps = 0x1CD870; // type:func\nFUN_001cdb28 = 0x1CDB28; // type:func\nFUN_001cdb70 = 0x1CDB70; // type:func\nFUN_001cdd98 = 0x1CDD98; // type:func\nFUN_001cdf78 = 0x1CDF78; // type:func\nJtbsChooseJtHide = 0x1CDFB8; // type:func\nMeasureJtJumpToTarget = 0x1CE590; // type:func\nGetJtRailLanding = 0x1CE800; // type:func\nFUN_001ce9e8 = 0x1CE9E8; // type:func\nFUN_001cea58 = 0x1CEA58; // type:func\nFUN_001ceab8 = 0x1CEAB8; // type:func\nFUN_001ceb18 = 0x1CEB18; // type:func\nFUN_001cedf8 = 0x1CEDF8; // type:func\nFUN_001cee30 = 0x1CEE30; // type:func\nFUN_001ceec8 = 0x1CEEC8; // type:func\nFUN_001cf138 = 0x1CF138; // type:func\nruns_on_cane_hook_grab = 0x1CF158; // type:func\nFUN_001cffd0 = 0x1CFFD0; // type:func\nFUN_001d0b20 = 0x1D0B20; // type:func\nFUN_001d0c78 = 0x1D0C78; // type:func\nFUN_001d0f20 = 0x1D0F20; // type:func\nSetJtHfdk = 0x1D1200; // type:func\nFUN_001d1260 = 0x1D1260; // type:func\nPresetJtAccelHide = 0x1D12F0; // type:func\nFUN_001d1478 = 0x1D1478; // type:func\nPostJtLoadPipe = 0x1D14F0; // type:func\nFUN_001d1630 = 0x1D1630; // type:func\nPresetJtAccelPipe = 0x1D1A80; // type:func\nFUN_001d1bb0 = 0x1D1BB0; // type:func\nUpdateJtInternalXpsPipe = 0x1D2518; // type:func\nFUN_001d27c0 = 0x1D27C0; // type:func\nPlaceJtOnPipe = 0x1D2830; // type:func\nSetFsp = 0x1D29C8; // type:func\nUpdateJtActivePowerUp = 0x1D2BB8; // type:func\nIRotatePowerUp = 0x1D3100; // type:func\nFUN_001d31d0 = 0x1D31D0; // type:func\nFUN_001d3290 = 0x1D3290; // type:func\nFUN_001d32d8 = 0x1D32D8; // type:func\nFUN_001d3398 = 0x1D3398; // type:func\nFUN_001d3470 = 0x1D3470; // type:func\nFUN_001d34e0 = 0x1D34E0; // type:func\nFUN_001d3500 = 0x1D3500; // type:func\nFUN_001d35a8 = 0x1D35A8; // type:func\nFUN_001d3678 = 0x1D3678; // type:func\nPostStepLoadRun = 0x1D36F0; // type:func\nCalculateBlrunV = 0x1D39E0; // type:func\nProjectStepRunPlant = 0x1D3A38; // type:func\nFIntersectStepRunPlant = 0x1D3B58; // type:func\nFReblendAbl2D = 0x1D3C68; // type:func\nAdjustStepRun = 0x1D3E00; // type:func\nSetStepRunTarget = 0x1D40A0; // type:func\nPostJtLoadSidestep = 0x1D4148; // type:func\nAdjustJtSidestep = 0x1D4348; // type:func\nSetJtSidestepTarget = 0x1D4698; // type:func\nPostJtLoadZap = 0x1D4848; // type:func\nFUN_001d48e8 = 0x1D48E8; // type:func\nFUN_001d4a98 = 0x1D4A98; // type:func\nsly_set_unk_callback = 0x1D4C90; // type:func\nFUN_001d4c98 = 0x1D4C98; // type:func\nsly_damage_relatedQMARK = 0x1D4D08; // type:func\nFUN_001d51a0 = 0x1D51A0; // type:func\nFUN_001d5398 = 0x1D5398; // type:func\nFUN_001d5418 = 0x1D5418; // type:func\nFUN_001d5468 = 0x1D5468; // type:func\nFUN_001d54e0 = 0x1D54E0; // type:func\nFUN_001d5620 = 0x1D5620; // type:func\nFUN_001d5678 = 0x1D5678; // type:func\nFUN_001d5fa8 = 0x1D5FA8; // type:func\nFUN_001d60b0 = 0x1D60B0; // type:func\nFUN_001d61c8 = 0x1D61C8; // type:func\nFUN_001d62e0 = 0x1D62E0; // type:func\nFUN_001d6608 = 0x1D6608; // type:func\nFUN_001d66a8 = 0x1D66A8; // type:func\nFFindJtWaterSurface = 0x1D6A18; // type:func\nAddJtWaterAcceleration = 0x1D6B18; // type:func\nFUN_001d6cb0 = 0x1D6CB0; // type:func\nFUN_001d6da0 = 0x1D6DA0; // type:func\nFUN_001d6dd8 = 0x1D6DD8; // type:func\nFUN_001d7018 = 0x1D7018; // type:func\nFUN_001d7040 = 0x1D7040; // type:func\nInitZpr = 0x1D7098; // type:func\ngcc2_compiled. = 0x1D7100; // type:func\nOSTRM__OSTRM = 0x1D7120; // type:func\nscePrintf_deci = 0x1D7148; // type:func\nOSTRM__CbWrite = 0x1D7190; // type:func\nscePrintf_deci_ = 0x1D72C8; // type:func\nFUN_001d73a8 = 0x1D73A8; // type:func\ninit_burning_rubber = 0x1D7440; // type:func\nFUN_001d7778 = 0x1D7778; // type:func\nGExcludeAlm = 0x1D8470; // type:func\nUpdateSuvBalance = 0x1D8578; // type:func\nDsGetTrackRelative = 0x1D86F8; // type:func\nFUN_001d8740 = 0x1D8740; // type:func\nUpdateSuvLine = 0x1D87C8; // type:func\nUpdateSuvHeading = 0x1D8BD0; // type:func\nUpdateSuvWheels = 0x1D8D90; // type:func\nUpdateSuvExpls = 0x1D8E40; // type:func\nBoostSuv = 0x1D92F0; // type:func\nFUN_001d9338 = 0x1D9338; // type:func\nUpdateSuvVolumes = 0x1D9488; // type:func\nUpdateSuvSounds = 0x1D9678; // type:func\nUpdateSuvPuncher = 0x1D9AC8; // type:func\nUpdateSuv = 0x1D9C98; // type:func\nUpdateSuvActive = 0x1D9D78; // type:func\nFUN_001da170 = 0x1DA170; // type:func\nFUN_001da320 = 0x1DA320; // type:func\nFUN_001da7e0 = 0x1DA7E0; // type:func\nFUN_001daa18 = 0x1DAA18; // type:func\nFUN_001dac20 = 0x1DAC20; // type:func\nFUN_001dacb0 = 0x1DACB0; // type:func\nUpdateSuvShapes = 0x1DAD28; // type:func\nFUN_001dae18 = 0x1DAE18; // type:func\nFUN_001dae48 = 0x1DAE48; // type:func\nOnSuvActive = 0x1DAE68; // type:func\nHandleSuvMessage = 0x1DAF08; // type:func\nSetSuvTrack = 0x1DAFB8; // type:func\nSetSuvLine = 0x1DB0C8; // type:func\nFUN_001db110 = 0x1DB110; // type:func\nAddSuvFeature = 0x1DB1E8; // type:func\nSetSuvSuvs = 0x1DB238; // type:func\nFUN_001db290 = 0x1DB290; // type:func\nVecCombo = 0x1DB460; // type:func\nInitSwDlHash = 0x1DB480; // type:func\nFUN_001db4c8 = 0x1DB4C8; // type:func\nDeleteSw = 0x1DB838; // type:func\nSetupBulkDataFromBrx = 0x1DB928; // type:func\nLoadBulkDataFromBrx = 0x1DBA38; // type:func\nSetSwGravity = 0x1DBA90; // type:func\nFUN_001dbac0 = 0x1DBAC0; // type:func\nFUN_001dbae0 = 0x1DBAE0; // type:func\nFUN_001dbb00 = 0x1DBB00; // type:func\nFOverflowSwLo = 0x1DBB20; // type:func\nFUN_001dbb50 = 0x1DBB50; // type:func\nFUN_001dbb90 = 0x1DBB90; // type:func\nPmqAllocSw = 0x1DBBD8; // type:func\nFreeSwMqList = 0x1DBC18; // type:func\nSetSoConstraints = 0x1DBC60; // type:func\nPostSwCallback = 0x1DBCC8; // type:func\nClearSwCallbacks = 0x1DBD40; // type:func\nProcessSwCallbacks = 0x1DBE48; // type:func\nFUN_001dbec8 = 0x1DBEC8; // type:func\nFUN_001dc0c8 = 0x1DC0C8; // type:func\nFreeSwStsoList = 0x1DC108; // type:func\nFUN_001dc150 = 0x1DC150; // type:func\nPloGetSwProxySource = 0x1DC208; // type:func\nIntersectSwBoundingBox = 0x1DC238; // type:func\nFUN_001dc4d0 = 0x1DC4D0; // type:func\nRemoveOxa = 0x1DC710; // type:func\nFUN_001dc740 = 0x1DC740; // type:func\nAddOxa = 0x1DC7B0; // type:func\nFUN_001dc7d0 = 0x1DC7D0; // type:func\nFreeSwPoxa = 0x1DC828; // type:func\nCreateSwDefaultLights = 0x1DC9A0; // type:func\nLoadUnknown4FromBrx = 0x1DCCC0; // type:func\nCreateSwPrizes = 0x1DCD28; // type:func\nLoadSwFromBrx = 0x1DCEA0; // type:func\nFClipLineHomogeneous = 0x1DD218; // type:func\nDrawLineWorld = 0x1DD3E0; // type:func\nFUN_001dd548 = 0x1DD548; // type:func\nFUN_001dd628 = 0x1DD628; // type:func\ncheck_level_status_unlocked = 0x1DD690; // type:func\ncheck_level_status_key = 0x1DD6B0; // type:func\ncheck_level_status_vault = 0x1DD6D0; // type:func\ncheck_level_status_mts = 0x1DD6F0; // type:func\nverify_level_completion_key = 0x1DD710; // type:func\nverify_level_completion_vault = 0x1DD758; // type:func\nverify_level_completion_mts = 0x1DD7A0; // type:func\nscene_vars_something = 0x1DD7E8; // type:func\nget_scene_variable = 0x1DD888; // type:func\nFUN_001dd8e8 = 0x1DD8E8; // type:func\nFUN_001dd908 = 0x1DD908; // type:func\nFUN_001dd928 = 0x1DD928; // type:func\nFUN_001dd950 = 0x1DD950; // type:func\nSetPlayerSuck = 0x1DD9A0; // type:func\nFUN_001dd9d8 = 0x1DD9D8; // type:func\nIncrementSwHandsOff = 0x1DDA20; // type:func\nDecrementSwHandsOff = 0x1DDA50; // type:func\nFUN_001dda80 = 0x1DDA80; // type:func\nFUN_001dda90 = 0x1DDA90; // type:func\nFUN_001ddab8 = 0x1DDAB8; // type:func\nset_lighting_value = 0x1DDAC8; // type:func\nFUN_001ddad0 = 0x1DDAD0; // type:func\nFUN_001ddb20 = 0x1DDB20; // type:func\nFUN_001ddb58 = 0x1DDB58; // type:func\nFUN_001ddbb8 = 0x1DDBB8; // type:func\nFUN_001ddbf8 = 0x1DDBF8; // type:func\nFUN_001ddc18 = 0x1DDC18; // type:func\nFUN_001ddc38 = 0x1DDC38; // type:func\nFUN_001ddc40 = 0x1DDC40; // type:func\nFUN_001ddc78 = 0x1DDC78; // type:func\nFUN_001ddc90 = 0x1DDC90; // type:func\nFUN_001ddcb0 = 0x1DDCB0; // type:func\nFUN_001ddcc8 = 0x1DDCC8; // type:func\nFUN_001ddce0 = 0x1DDCE0; // type:func\nFUN_001ddd18 = 0x1DDD18; // type:func\nFUN_001dde90 = 0x1DDE90; // type:func\nFUN_001de768 = 0x1DE768; // type:func\nFUN_001de798 = 0x1DE798; // type:func\nPostTankLoad = 0x1DE808; // type:func\nFUN_001de910 = 0x1DE910; // type:func\nFUN_001deb30 = 0x1DEB30; // type:func\nFUN_001debb8 = 0x1DEBB8; // type:func\nFUN_001debe8 = 0x1DEBE8; // type:func\nFUN_001df290 = 0x1DF290; // type:func\nFUN_001df2c8 = 0x1DF2C8; // type:func\nFUN_001df520 = 0x1DF520; // type:func\nFUN_001df5a0 = 0x1DF5A0; // type:func\nFUN_001df600 = 0x1DF600; // type:func\nFUN_001df700 = 0x1DF700; // type:func\nFUN_001dfa10 = 0x1DFA10; // type:func\nAdjustTankNewXp = 0x1DFA40; // type:func\nFUN_001dfb08 = 0x1DFB08; // type:func\nFUN_001dfbe0 = 0x1DFBE0; // type:func\nFUN_001dfd48 = 0x1DFD48; // type:func\nResetTargetList = 0x1DFD70; // type:func\nFUN_001dfd90 = 0x1DFD90; // type:func\nFUN_001dfdc8 = 0x1DFDC8; // type:func\nFUN_001dfe00 = 0x1DFE00; // type:func\nFUN_001dfe38 = 0x1DFE38; // type:func\nget_commentary_data_by_level_id = 0x1DFE80; // type:func\npost_unknown_load = 0x1DFEB8; // type:func\nFUN_001e00b0 = 0x1E00B0; // type:func\ngui_set_widget_modeQMARK = 0x1E02C8; // type:func\nFUN_001e0678 = 0x1E0678; // type:func\ngui_set_mode_3 = 0x1E0828; // type:func\nFUN_001e0848 = 0x1E0848; // type:func\nCchParsePchzInt = 0x1E08F8; // type:func\nFUN_001e0978 = 0x1E0978; // type:func\nWriteTftPchz = 0x1E0CD0; // type:func\nFNegTftUl = 0x1E0E18; // type:func\nUnRadixFromChConversion = 0x1E0EF8; // type:func\nCchAchFromUl = 0x1E0F58; // type:func\nWriteTftUl = 0x1E1028; // type:func\nFUN_001e1330 = 0x1E1330; // type:func\nFUN_001e13d0 = 0x1E13D0; // type:func\nFUN_001e1498 = 0x1E1498; // type:func\nWriteTftDouble = 0x1E17A8; // type:func\nFUN_001e1a08 = 0x1E1A08; // type:func\nCchOstrmPrintf = 0x1E1DB8; // type:func\nscePrintf_ = 0x1E1EB0; // type:func\nscePrintf = 0x1E1F10; // type:func\nFUN_001e1f58 = 0x1E1F58; // type:func\nsprintf = 0x1E1FD0; // type:func\nFUN_001e2018 = 0x1E2018; // type:func\nFUN_001e20b8 = 0x1E20B8; // type:func\nstrlen = 0x1E2100; // type:func\nstrcpy = 0x1E2138; // type:func\nstrcat = 0x1E2180; // type:func\nstrchr = 0x1E21D8; // type:func\nUpperizePchz = 0x1E2218; // type:func\nSemaCreate__Fii = 0x1E2268; // type:func\nFUN_001e22c0 = 0x1E22C0; // type:func\nEnterCritSect = 0x1E22F8; // type:func\nFUN_001e2358 = 0x1E2358; // type:func\nStartupThread = 0x1E2398; // type:func\nFUN_001e2420 = 0x1E2420; // type:func\nGetTnfnNose = 0x1E2438; // type:func\nFUN_001e2520 = 0x1E2520; // type:func\nFUN_001e25f8 = 0x1E25F8; // type:func\nLoadTnFromBrx = 0x1E2648; // type:func\nFUN_001e2758 = 0x1E2758; // type:func\nFUN_001e2778 = 0x1E2778; // type:func\nFUN_001e2840 = 0x1E2840; // type:func\nFUN_001e2870 = 0x1E2870; // type:func\nFUN_001e2940 = 0x1E2940; // type:func\nFUN_001e2988 = 0x1E2988; // type:func\nFUN_001e29a8 = 0x1E29A8; // type:func\nCalculateTnCrv = 0x1E2A00; // type:func\nCalculateTnPos = 0x1E2BF0; // type:func\nFUN_001e2e68 = 0x1E2E68; // type:func\nFUN_001e30e8 = 0x1E30E8; // type:func\nFUN_001e31f0 = 0x1E31F0; // type:func\nFUN_001e4578 = 0x1E4578; // type:func\nFUN_001e4888 = 0x1E4888; // type:func\nLoadTbspFromBrx = 0x1E4C48; // type:func\nFCheckTbspPoint = 0x1E4DC0; // type:func\nCTransition__CTransition = 0x1E4E38; // type:func\nCTransition__Set = 0x1E4E80; // type:func\nCTransition__Execute = 0x1E4EA8; // type:func\nCTransition__ResetWorld = 0x1E5278; // type:func\n__static_initialization_and_destruction_03 = 0x1E5328; // type:func\n_GLOBAL_$I$g_transition = 0x1E5358; // type:func\nFUN_001e5378 = 0x1E5378; // type:func\nPostTurretLoad = 0x1E5428; // type:func\nFUN_001e55d0 = 0x1E55D0; // type:func\nFUN_001e56a0 = 0x1E56A0; // type:func\nFUN_001e5750 = 0x1E5750; // type:func\nFUN_001e5888 = 0x1E5888; // type:func\nFUN_001e5938 = 0x1E5938; // type:func\nFUN_001e5c78 = 0x1E5C78; // type:func\nHandleTurretMessage = 0x1E5CE8; // type:func\nFUN_001e5da8 = 0x1E5DA8; // type:func\nFUN_001e5e08 = 0x1E5E08; // type:func\nInitTv = 0x1E5E70; // type:func\nPostTvLoad = 0x1E6188; // type:func\nGetTvItvbMinMax = 0x1E6268; // type:func\nDrawTvArea = 0x1E62A8; // type:func\nFUN_001e6600 = 0x1E6600; // type:func\nDrawTvOutline = 0x1E6C20; // type:func\nFUN_001e73b8 = 0x1E73B8; // type:func\nSetTvTvs = 0x1E7440; // type:func\nFUN_001e7460 = 0x1E7460; // type:func\nSetTvTvgs = 0x1E7518; // type:func\nFUN_001e76e0 = 0x1E76E0; // type:func\nFUN_001e77c0 = 0x1E77C0; // type:func\nFUN_001e7c60 = 0x1E7C60; // type:func\nFUN_001e80d8 = 0x1E80D8; // type:func\nFUN_001e83e0 = 0x1E83E0; // type:func\nSetTvSpeaker = 0x1E86E0; // type:func\nSetTvReplace = 0x1E87F0; // type:func\nFUN_001e8840 = 0x1E8840; // type:func\n__static_initialization_and_destruction_04 = 0x1E8878; // type:func\nFUN_001e88b0 = 0x1E88B0; // type:func\nFUN_001e88d0 = 0x1E88D0; // type:func\nFUN_001e8948 = 0x1E8948; // type:func\nPsoPadUbgClosest = 0x1E89F0; // type:func\nFUN_001e8a50 = 0x1E8A50; // type:func\nSgsNextUbgAI = 0x1E8D58; // type:func\nFUN_001e8e08 = 0x1E8E08; // type:func\nFUN_001e8e48 = 0x1E8E48; // type:func\nFUN_001e8ef8 = 0x1E8EF8; // type:func\nFUN_001e8fa8 = 0x1E8FA8; // type:func\nFUN_001e8fe8 = 0x1E8FE8; // type:func\nFUN_001e9038 = 0x1E9038; // type:func\nFUN_001e9088 = 0x1E9088; // type:func\nFUN_001e90a8 = 0x1E90A8; // type:func\nPostUiLoad = 0x1E90E8; // type:func\nUpdateUi = 0x1E9108; // type:func\nFUN_001e9498 = 0x1E9498; // type:func\nPopUiActiveBlot = 0x1E9570; // type:func\nDrawUi = 0x1E9648; // type:func\nRenderUi = 0x1E9668; // type:func\nResetUi = 0x1E9688; // type:func\nSetUiUis = 0x1E96F8; // type:func\nSetUiUPause = 0x1E98E8; // type:func\nFUN_001e9970 = 0x1E9970; // type:func\nFUN_001e9a10 = 0x1E9A10; // type:func\nFUN_001e9a68 = 0x1E9A68; // type:func\nFUN_001e9ad8 = 0x1E9AD8; // type:func\ncheck_anticrack_collectibles = 0x1E9B30; // type:func\nUpdateSwObjects = 0x1E9C78; // type:func\nUpdateSwPosWorldPrev = 0x1E9E30; // type:func\nUpdateSwObjects1 = 0x1E9EE8; // type:func\nUpdateSwDarkening = 0x1EA0A8; // type:func\nUpdateSw = 0x1EA118; // type:func\nRadNormalize = 0x1EA408; // type:func\nGLimitAbs = 0x1EA480; // type:func\nGSmooth = 0x1EA4B8; // type:func\nGSmoothA = 0x1EA620; // type:func\nRadSmooth = 0x1EA728; // type:func\nRadSmoothA = 0x1EA798; // type:func\nPosSmooth = 0x1EA818; // type:func\nSmoothMatrix = 0x1EA918; // type:func\nNRandInRange = 0x1EAA70; // type:func\nGRandInRange = 0x1EAAE0; // type:func\nGRandGaussian = 0x1EAB48; // type:func\nFFloatsNear = 0x1EAC68; // type:func\nCSolveQuadratic = 0x1EACA0; // type:func\nPrescaleClq = 0x1EAD30; // type:func\nCalculateSinCos = 0x1EAD88; // type:func\nGTrunc = 0x1EAE78; // type:func\nGTrunc1 = 0x1EAF28; // type:func\nGModPositive = 0x1EAFE0; // type:func\nFitClq = 0x1EB018; // type:func\nFCheckLm = 0x1EB050; // type:func\nFCheckAlm = 0x1EB080; // type:func\nGLimitLm = 0x1EB0F8; // type:func\nSgnCompareG = 0x1EB128; // type:func\nForce = 0x1EB160; // type:func\nMinimizeRange = 0x1EB168; // type:func\nLoadUnknown5FromBrx = 0x1EB518; // type:func\nFUN_001eb598 = 0x1EB598; // type:func\nFUN_001eb608 = 0x1EB608; // type:func\nFUN_001eb748 = 0x1EB748; // type:func\nFUN_001ebc88 = 0x1EBC88; // type:func\nFUN_001ebcd8 = 0x1EBCD8; // type:func\nFUN_001ebd10 = 0x1EBD10; // type:func\nFUN_001ebdd0 = 0x1EBDD0; // type:func\nFUN_001ebeb0 = 0x1EBEB0; // type:func\nLoadMbgFromBrx = 0x1EBF40; // type:func\nFUN_001ebfb0 = 0x1EBFB0; // type:func\nFUN_001ec098 = 0x1EC098; // type:func\nFUN_001ec0b8 = 0x1EC0B8; // type:func\nFUN_001ec0d8 = 0x1EC0D8; // type:func\nFUN_001ec190 = 0x1EC190; // type:func\nFUN_001ec380 = 0x1EC380; // type:func\nFUN_001ec3d8 = 0x1EC3D8; // type:func\nFUN_001ec478 = 0x1EC478; // type:func\nFUN_001ec528 = 0x1EC528; // type:func\nFUN_001ec570 = 0x1EC570; // type:func\nFUN_001ec7a8 = 0x1EC7A8; // type:func\nFUN_001ec828 = 0x1EC828; // type:func\nFUN_001ecbc8 = 0x1ECBC8; // type:func\nFUN_001ecdf8 = 0x1ECDF8; // type:func\nFUN_001ece98 = 0x1ECE98; // type:func\nFUN_001ecf10 = 0x1ECF10; // type:func\nFUN_001ed018 = 0x1ED018; // type:func\nFUN_001ed020 = 0x1ED020; // type:func\nFUN_001ed090 = 0x1ED090; // type:func\nFUN_001ed0d8 = 0x1ED0D8; // type:func\nFUN_001ed168 = 0x1ED168; // type:func\nFUN_001ed198 = 0x1ED198; // type:func\nFUN_001ed1d8 = 0x1ED1D8; // type:func\nFUN_001ed210 = 0x1ED210; // type:func\nFUN_001ed278 = 0x1ED278; // type:func\nFUN_001ed318 = 0x1ED318; // type:func\nFUN_001ed4c8 = 0x1ED4C8; // type:func\nFUN_001ed558 = 0x1ED558; // type:func\nFUN_001ed588 = 0x1ED588; // type:func\nFUN_001ed5b8 = 0x1ED5B8; // type:func\nFUN_001ed5d8 = 0x1ED5D8; // type:func\nFUN_001ed5f8 = 0x1ED5F8; // type:func\nFUN_001ed618 = 0x1ED618; // type:func\nSetVectorCylind = 0x1ED650; // type:func\nSetVectorSphere = 0x1ED6B0; // type:func\nSProjectVector = 0x1ED738; // type:func\nGetNormalVectors = 0x1ED780; // type:func\nGetNormalVector = 0x1ED840; // type:func\nRadBetweenVectors = 0x1ED908; // type:func\nFindClosestPointBetweenLines = 0x1EDA80; // type:func\nFindClosestPointBetweenLineSegments = 0x1EDC08; // type:func\nCalculateVectorPanTilt = 0x1EDDB0; // type:func\nConvertDeulToW = 0x1EDE38; // type:func\nFCalculateMuzzleVelocity = 0x1EDEF0; // type:func\nFCalculateMuzzleVelocity1 = 0x1EE090; // type:func\nFCalculateMuzzleVelocityAngle = 0x1EE290; // type:func\nLimitVectorLength = 0x1EE2B0; // type:func\nVIFS__VIFS = 0x1EE318; // type:func\nVIFS__Align = 0x1EE368; // type:func\nVIFS__AddVifBaseOffset = 0x1EE3B8; // type:func\nVIFS__AddVifMscal = 0x1EE3F0; // type:func\nVIFS__AddVifMscalf = 0x1EE420; // type:func\nVIFS__AddVifFlush = 0x1EE450; // type:func\nVIFS__AddVifFlusha = 0x1EE468; // type:func\nVIFS__AddVifFlushe = 0x1EE480; // type:func\nVIFS__AddVifStcycl = 0x1EE498; // type:func\nVIFS__AddVifStrow = 0x1EE4C0; // type:func\nVIFS__AddVifStmask = 0x1EE528; // type:func\nVIFS__CbUnpackSetup = 0x1EE560; // type:func\nVIFS__UnpackHelper = 0x1EE5C8; // type:func\nAddVifUnpack = 0x1EE668; // type:func\nVIFS__AddVifUnpackRefs = 0x1EE718; // type:func\nVIFS__AddVifDirect = 0x1EE7D0; // type:func\nFUN_001ee850 = 0x1EE850; // type:func\nVIFS__AddVifGifs = 0x1EE8D0; // type:func\nInitVismap = 0x1EE900; // type:func\nLoadVismapFromBrx = 0x1EE930; // type:func\nGrfzonOneHop = 0x1EE9D0; // type:func\nClipVbspSphereOneHop = 0x1EEA40; // type:func\nClipVismapSphereOneHop = 0x1EEB60; // type:func\nClipVismapPointNoHop = 0x1EEBB0; // type:func\nInitWater = 0x1EEC60; // type:func\nPostWaterLoad = 0x1EECE0; // type:func\nCalculateWaterCurrent = 0x1EED68; // type:func\nUpdateSwXaList = 0x1EEE50; // type:func\nUpdateWater = 0x1EEF90; // type:func\nAddWaterExternalAccelerations = 0x1EF3A8; // type:func\nHandleWaterMessage = 0x1EF3D8; // type:func\nUpdateWaterMergeGroup = 0x1EF520; // type:func\nFUN_001ef5b8 = 0x1EF5B8; // type:func\nFUN_001ef768 = 0x1EF768; // type:func\nFUN_001ef808 = 0x1EF808; // type:func\nFUN_001ef830 = 0x1EF830; // type:func\nInitWaypoint = 0x1EF838; // type:func\nPostWaypointLoad = 0x1EF868; // type:func\nSetWaypointRsmg = 0x1EF8C0; // type:func\nSetWaypointWps = 0x1EF900; // type:func\nFUN_001ef9c8 = 0x1EF9C8; // type:func\nFUN_001efa30 = 0x1EFA30; // type:func\nAddWpsgWaypoint = 0x1EFA60; // type:func\nFUN_001efa88 = 0x1EFA88; // type:func\nUpdateWpsgCallback = 0x1EFB20; // type:func\nFUN_001efc98 = 0x1EFC98; // type:func\nInitWipe = 0x1EFCE8; // type:func\nUpdateWipe = 0x1EFD10; // type:func\nDrawWipe = 0x1EFEE0; // type:func\nActivateWipe = 0x1EFFA0; // type:func\nSetWipeButtonTrans = 0x1F00C0; // type:func\nFCatchWipeButtonTrans = 0x1F00F0; // type:func\nSetWipeWipes = 0x1F0220; // type:func\nWipeToWorldWarp = 0x1F0428; // type:func\nFUN_001f0468 = 0x1F0468; // type:func\nFUN_001f0490 = 0x1F0490; // type:func\nFUN_001f0580 = 0x1F0580; // type:func\nFUN_001f0660 = 0x1F0660; // type:func\nBindWm = 0x1F0758; // type:func\nFUN_001f0878 = 0x1F0878; // type:func\nFUN_001f08f0 = 0x1F08F0; // type:func\nFUN_001f0908 = 0x1F0908; // type:func\nFUN_001f0ae0 = 0x1F0AE0; // type:func\nFUN_001f0eb8 = 0x1F0EB8; // type:func\nFUN_001f0f70 = 0x1F0F70; // type:func\nSetWmWms = 0x1F1050; // type:func\nShowWm = 0x1F1590; // type:func\nFUN_001f1610 = 0x1F1610; // type:func\nFUN_001f1648 = 0x1F1648; // type:func\nFUN_001f17a0 = 0x1F17A0; // type:func\nSetWmCursor = 0x1F18B0; // type:func\nFUN_001f1960 = 0x1F1960; // type:func\nFUN_001f1a08 = 0x1F1A08; // type:func\nFUN_001f1c90 = 0x1F1C90; // type:func\nFUN_001f1e38 = 0x1F1E38; // type:func\nFUN_001f20a8 = 0x1F20A8; // type:func\nFUN_001f2688 = 0x1F2688; // type:func\nFUN_001f2758 = 0x1F2758; // type:func\nApplyWrGlob = 0x1F2798; // type:func\nFUN_001f2840 = 0x1F2840; // type:func\nWarpWrTransform = 0x1F2EF0; // type:func\nGetWrBounds = 0x1F3140; // type:func\nUNoise = 0x1F31F8; // type:func\nUNoise1 = 0x1F3250; // type:func\nUBias = 0x1F3328; // type:func\nFUN_001f3358 = 0x1F3358; // type:func\nUpdateWrMatrixes = 0x1F3408; // type:func\nAddWrCircleWarp = 0x1F36E8; // type:func\nAddWrBendWarp = 0x1F3768; // type:func\nPwreGetWrCur = 0x1F37D8; // type:func\nFUN_001f3810 = 0x1F3810; // type:func\nFUN_001f3830 = 0x1F3830; // type:func\nFUN_001f3850 = 0x1F3850; // type:func\nFUN_001f38a0 = 0x1F38A0; // type:func\nAddOnzOnze = 0x1F38F0; // type:func\nFUN_001f3928 = 0x1F3928; // type:func\nFUN_001f3990 = 0x1F3990; // type:func\nInitXfm = 0x1F39F8; // type:func\nLoadXfmFromBrx = 0x1F3A40; // type:func\nFUN_001f3a90 = 0x1F3A90; // type:func\nFUN_001f3af0 = 0x1F3AF0; // type:func\nConvertXfmWorldToLocal = 0x1F3B48; // type:func\nGetXfmPos = 0x1F3BD8; // type:func\nFUN_001f3c08 = 0x1F3C08; // type:func\nPwarpFromOid = 0x1F3C38; // type:func\nLoadWarpFromBrx = 0x1F3D80; // type:func\nFUN_001f3ee0 = 0x1F3EE0; // type:func\nFUN_001f3f80 = 0x1F3F80; // type:func\nTriggerWarp = 0x1F4008; // type:func\nSetWarpRsmg = 0x1F42D0; // type:func\nTeleportSwPlayer = 0x1F4318; // type:func\nFUN_001f4378 = 0x1F4378; // type:func\nFUN_001f4408 = 0x1F4408; // type:func\nLoadExitFromBrx = 0x1F4500; // type:func\nFUN_001f4660 = 0x1F4660; // type:func\nSetExitExits = 0x1F4760; // type:func\nTriggerExitQMARK = 0x1F4808; // type:func\nenter_exit = 0x1F4A30; // type:func\nUpdateExit = 0x1F4AE0; // type:func\nFUN_001f4e18 = 0x1F4E18; // type:func\nPostCameraLoad = 0x1F4E48; // type:func\nFUN_001f4ed0 = 0x1F4ED0; // type:func\nFUN_001f4f20 = 0x1F4F20; // type:func\nFUN_001f4f70 = 0x1F4F70; // type:func\nFUN_001f4fd8 = 0x1F4FD8; // type:func\nFUN_001f5008 = 0x1F5008; // type:func\nFUN_001f51a0 = 0x1F51A0; // type:func\nFUN_001f51c8 = 0x1F51C8; // type:func\nFUN_001f51e8 = 0x1F51E8; // type:func\nFUN_001f5210 = 0x1F5210; // type:func\nFUN_001f5218 = 0x1F5218; // type:func\nUpdateVolzp = 0x1F5268; // type:func\nInitZpd = 0x1F5590; // type:func\nPostZpdLoad = 0x1F55A8; // type:func\nFUN_001f56d8 = 0x1F56D8; // type:func\nInflictZpdZap = 0x1F57E0; // type:func\nAddZpdZapLo = 0x1F5868; // type:func\nFUN_001f5930 = 0x1F5930; // type:func\nmemcmp = 0x1F59C4; // type:func\nmemcpy = 0x1F5A58; // type:func\nmemmove = 0x1F5B08; // type:func\nmemset = 0x1F5C0C; // type:func\nFUN_001f5cd0 = 0x1F5CD0; // type:func\nsrand = 0x1F66F8; // type:func\nrand = 0x1F6708; // type:func\nstrcmp = 0x1F6738; // type:func\nFUN_001f6880 = 0x1F6880; // type:func\nAddIntcHandler = 0x1F6950; // type:func\nRemoveIntcHandler = 0x1F6960; // type:func\nAddDmacHandler = 0x1F6970; // type:func\nAddDmacHandler1 = 0x1F6980; // type:func\nRemoveDmacHandler = 0x1F6990; // type:func\n_EnableIntc = 0x1F69A0; // type:func\n_DisableIntc = 0x1F69B0; // type:func\n_EnableDmac = 0x1F69C0; // type:func\n_DisableDmac = 0x1F69D0; // type:func\nSetAlarm = 0x1F69E0; // type:func\nCreateThread = 0x1F6A10; // type:func\nStartThread = 0x1F6A20; // type:func\nExitDeleteThread = 0x1F6A30; // type:func\nChangeThreadPriority = 0x1F6A50; // type:func\nRotateThreadReadyQueue = 0x1F6A70; // type:func\nGetThreadId = 0x1F6A90; // type:func\nReferThreadStatus = 0x1F6AA0; // type:func\nWakeupThread = 0x1F6AC0; // type:func\n_iWakeupThread = 0x1F6AD0; // type:func\nSuspendThread = 0x1F6AF0; // type:func\nCreateSema = 0x1F6B20; // type:func\nDeleteSema = 0x1F6B30; // type:func\nSignalSema = 0x1F6B40; // type:func\niSignalSema = 0x1F6B50; // type:func\nWaitSema = 0x1F6B60; // type:func\nPollSema = 0x1F6B70; // type:func\nSetOsdConfigParam = 0x1F6B90; // type:func\nGetOsdConfigParam = 0x1F6BA0; // type:func\nFlushCache = 0x1F6C20; // type:func\nsceSifStopDma = 0x1F6C40; // type:func\nGsGetIMR = 0x1F6C60; // type:func\nGsPutIMR = 0x1F6C70; // type:func\nsceSifDmaStat = 0x1F6C90; // type:func\nsceSifSetDma = 0x1F6CA0; // type:func\nisceSifSetDma = 0x1F6CB0; // type:func\nsceSifSetDChain = 0x1F6CC0; // type:func\nisceSifSetDChain = 0x1F6CD0; // type:func\nsceSifSetReg = 0x1F6CE0; // type:func\nsceSifGetReg = 0x1F6CF0; // type:func\nDeci2Call = 0x1F6D10; // type:func\nGetMemorySize = 0x1F6D20; // type:func\n_InitTLB = 0x1F6D30; // type:func\nFUN_001f6d40 = 0x1F6D40; // type:func\nEnableIntc = 0x1F6DA8; // type:func\nDisableDmac = 0x1F6E10; // type:func\nFUN_001f6e78 = 0x1F6E78; // type:func\nSetSyscall = 0x1F6EE0; // type:func\nFUN_001f6ef0 = 0x1F6EF0; // type:func\nRFU091 = 0x1F6F38; // type:func\nInitAlarm1 = 0x1F6F48; // type:func\ntopThread = 0x1F7020; // type:func\nInitThread = 0x1F70F8; // type:func\niWakeupThread = 0x1F71D0; // type:func\nkputchar = 0x1F7270; // type:func\ndeci2Putchar = 0x1F72A8; // type:func\nserialPutchar = 0x1F7358; // type:func\nftoi = 0x1F7390; // type:func\nFUN_001f7420 = 0x1F7420; // type:func\n_printf = 0x1F7588; // type:func\nkprintf = 0x1F7B50; // type:func\nprintf = 0x1F7B88; // type:func\nsceSifInitRpc = 0x1F7BE8; // type:func\nsceSifExitRpc = 0x1F7D88; // type:func\n_sceRpcGetPacket = 0x1F7DB0; // type:func\n_sceRpcFreePacket = 0x1F7E58; // type:func\n_sceRpcGetFPacket = 0x1F7E78; // type:func\n_request_end = 0x1F7EA8; // type:func\nFUN_001f7f60 = 0x1F7F60; // type:func\n_search_svdata = 0x1F7FC0; // type:func\n_request_bind = 0x1F8010; // type:func\nsceSifBindRpc = 0x1F80C0; // type:func\nsceSifCallRpc = 0x1F8290; // type:func\nsceSifCheckStatRpc = 0x1F8480; // type:func\n_sceFsIobSemaMK = 0x1F84D8; // type:func\nget_iob = 0x1F8538; // type:func\nFUN_001f85a8 = 0x1F85A8; // type:func\n_sceFsSemInit = 0x1F8968; // type:func\n_sceFsWaitS = 0x1F89B8; // type:func\n_sceFsSigSema = 0x1F89E8; // type:func\nFUN_001f8a28 = 0x1F8A28; // type:func\nsceFsReset = 0x1F8BF8; // type:func\nsceClose = 0x1F8C38; // type:func\nsceRead = 0x1F8DB8; // type:func\nFUN_001f9028 = 0x1F9028; // type:func\nsceIoctl = 0x1F92E8; // type:func\n_lf_bind = 0x1F9690; // type:func\n_lf_version = 0x1F9790; // type:func\nsceSifLoadFileReset = 0x1F9820; // type:func\n_sceSifLoadModule = 0x1F9868; // type:func\nsceSifLoadModule = 0x1F9A90; // type:func\nsceSifResetIop = 0x1F9AD8; // type:func\nsceSifSyncIop = 0x1F9C18; // type:func\nsceSifRebootIop = 0x1F9C50; // type:func\nDIntr = 0x1F9D60; // type:func\nEIntr = 0x1F9DA8; // type:func\nsupplement_crt0 = 0x1F9DC0; // type:func\nFindAddress = 0x1F9E40; // type:func\nGetSystemCallTableEntry = 0x1F9E50; // type:func\nSetSyscall1 = 0x1F9E90; // type:func\n_InitSys = 0x1F9EA8; // type:func\nSetSyscall2 = 0x1F9EE8; // type:func\nFUN_001f9ef8 = 0x1F9EF8; // type:func\nRFU0911 = 0x1F9F40; // type:func\nPatchIsNeeded = 0x1F9F50; // type:func\nInitExecPS2 = 0x1F9FB8; // type:func\nInitTLB = 0x1FA068; // type:func\nExit = 0x1FA078; // type:func\nsceResetttyinit = 0x1FA0A0; // type:func\nFUN_001fa0d8 = 0x1FA0D8; // type:func\nkill = 0x1FA0E0; // type:func\nkputs = 0x1FA140; // type:func\nsceSifGetSreg = 0x1FA1C0; // type:func\nsceSifInitCmd = 0x1FA1E8; // type:func\nsceSifExitCmd = 0x1FA468; // type:func\nsceSifAddCmdHandler = 0x1FA4A0; // type:func\nsceSifRemoveCmdHandler = 0x1FA4D0; // type:func\n_sceSifSendCmd = 0x1FA4F8; // type:func\nsceSifSendCmd = 0x1FA630; // type:func\n_sceSifCmdIntrHdlr = 0x1FA6B0; // type:func\nsceSifWriteBackDCache = 0x1FA7D8; // type:func\niReferEventFlagStatus = 0x1FA890; // type:func\nkCopy = 0x1FA8A0; // type:func\nRFU0912 = 0x1FA8D8; // type:func\nSetSyscall3 = 0x1FA8E8; // type:func\n_SetTLBEntry = 0x1FA9B0; // type:func\nInitTLB1 = 0x1FA9C0; // type:func\nInitTLB32MB = 0x1FAA00; // type:func\n_kExitTLBHandler = 0x1FAC40; // type:func\n__main = 0x1FAE18; // type:func\n__divdi3 = 0x1FAE38; // type:func\n__fixunsdfdi = 0x1FB528; // type:func\n__floatdidf = 0x1FB618; // type:func\n__floatdisf = 0x1FB6B0; // type:func\nFUN_001fb790 = 0x1FB790; // type:func\nFUN_001fbe00 = 0x1FBE00; // type:func\n__umoddi3 = 0x1FC3D0; // type:func\n__pack_d = 0x1FC910; // type:func\n__unpack_d = 0x1FCA40; // type:func\n_fpadd_parts = 0x1FCAE0; // type:func\ndpadd = 0x1FCD20; // type:func\ndpsub = 0x1FCD78; // type:func\ndpmul = 0x1FCDE0; // type:func\nFUN_001fd088 = 0x1FD088; // type:func\n__fpcmp_parts_d = 0x1FD1F0; // type:func\ndpcmp = 0x1FD308; // type:func\nlitodp = 0x1FD358; // type:func\ndptoli = 0x1FD410; // type:func\ndptoul = 0x1FD4A8; // type:func\n__make_dp = 0x1FD548; // type:func\ndptofp = 0x1FD578; // type:func\nFUN_001fd5d0 = 0x1FD5D0; // type:func\n__unpack_f = 0x1FD6E0; // type:func\nFUN_001fd7a0 = 0x1FD7A0; // type:func\n__make_fp = 0x1FD838; // type:func\nfptodp = 0x1FD868; // type:func\ngcc2_compiled.1 = 0x1FD8A8; // type:func\nFUN_001fd920 = 0x1FD920; // type:func\n__terminate = 0x1FD930; // type:func\n__throw_type_match = 0x1FD958; // type:func\nnew_eh_context = 0x1FD990; // type:func\nFUN_001fd9e8 = 0x1FD9E8; // type:func\n__get_eh_info = 0x1FDA10; // type:func\neh_context_initialize = 0x1FDA38; // type:func\neh_context_static = 0x1FDA60; // type:func\nFUN_001fdac8 = 0x1FDAC8; // type:func\nFUN_001fdaf0 = 0x1FDAF0; // type:func\nold_find_exception_handler = 0x1FDDD8; // type:func\nfind_exception_handler = 0x1FDEB0; // type:func\nget_reg_addr = 0x1FDFF8; // type:func\ncopy_reg = 0x1FE080; // type:func\nnext_stack_level = 0x1FE100; // type:func\n__unwinding_cleanup = 0x1FE190; // type:func\nthrow_helper = 0x1FE198; // type:func\nFUN_001fe4c8 = 0x1FE4C8; // type:func\nFUN_001fe6a8 = 0x1FE6A8; // type:func\ngcc2_compiled.2 = 0x1FE890; // type:func\nterminate = 0x1FE8F0; // type:func\nFUN_001fe908 = 0x1FE908; // type:func\nFUN_001fe938 = 0x1FE938; // type:func\n__cp_eh_info = 0x1FE978; // type:func\n__start_cp_handler = 0x1FE998; // type:func\n__eh_alloc = 0x1FE9D0; // type:func\n__eh_free = 0x1FE9F8; // type:func\n__cplus_type_matcher = 0x1FEA18; // type:func\n__cp_push_exception = 0x1FEA88; // type:func\n__cp_pop_exception = 0x1FEB18; // type:func\n__uncatch_exception = 0x1FEBE0; // type:func\nFUN_001fec10 = 0x1FEC10; // type:func\nexception__what = 0x1FEF00; // type:func\nFUN_001fef28 = 0x1FEF28; // type:func\nbad_exception_type_info_function = 0x1FEF70; // type:func\nFUN_001fefc0 = 0x1FEFC0; // type:func\nexception_type_info_function = 0x1FF008; // type:func\ndecode_uleb128 = 0x1FF048; // type:func\ndecode_sleb128 = 0x1FF090; // type:func\nfde_merge = 0x1FF0E0; // type:func\nend_fde_sort = 0x1FF1E0; // type:func\ncount_fdes = 0x1FF448; // type:func\nadd_fdes = 0x1FF490; // type:func\nframe_init = 0x1FF518; // type:func\nfind_fde = 0x1FF658; // type:func\nextract_cie_info = 0x1FF740; // type:func\nexecute_cfa_insn = 0x1FF848; // type:func\n__deregister_frame_info = 0x1FFC08; // type:func\n__frame_state_for = 0x1FFC80; // type:func\nfde_split = 0x1FFE58; // type:func\nbad_alloc_type_info_function = 0x200000; // type:func\nFUN_00200050 = 0x200050; // type:func\ntype_info__~type_info = 0x200080; // type:func\ntype_info__operatorEQEQ = 0x2000B0; // type:func\nFUN_00200118 = 0x200118; // type:func\nFUN_00200138 = 0x200138; // type:func\n__user_type_info__dcast = 0x200158; // type:func\n__si_type_info__dcast = 0x200188; // type:func\n__class_type_info__dcast = 0x200220; // type:func\n__class_type_info_type_info_function = 0x200418; // type:func\nFUN_00200468 = 0x200468; // type:func\n__si_type_info_type_info_function = 0x2004A8; // type:func\nFUN_002004f8 = 0x2004F8; // type:func\n__user_type_info_type_info_function = 0x200530; // type:func\nFUN_00200580 = 0x200580; // type:func\nFUN_002005a0 = 0x2005A0; // type:func\nbad_typeid_type_info_function = 0x2005E8; // type:func\nFUN_00200638 = 0x200638; // type:func\nbad_cast_type_info_function = 0x200680; // type:func\ntype_info__operator!EQ = 0x2006D0; // type:func\ntype_info_type_info_function = 0x200710; // type:func\ntype_info__before = 0x200750; // type:func\n__throw_type_match_rtti = 0x200778; // type:func\n__is_pointer = 0x200C40; // type:func\n__dynamic_cast = 0x200D58; // type:func\nFUN_00200e08 = 0x200E08; // type:func\n__array_type_info_type_info_function = 0x2011C0; // type:func\nFUN_00201210 = 0x201210; // type:func\n__ptmd_type_info_type_info_function = 0x201230; // type:func\nFUN_00201280 = 0x201280; // type:func\n__ptmf_type_info_type_info_function = 0x2012A0; // type:func\nFUN_002012f0 = 0x2012F0; // type:func\n__func_type_info_type_info_function = 0x201310; // type:func\nFUN_00201360 = 0x201360; // type:func\n__builtin_type_info_type_info_function = 0x201380; // type:func\nFUN_002013d0 = 0x2013D0; // type:func\n__attr_type_info_type_info_function = 0x2013F0; // type:func\nFUN_00201440 = 0x201440; // type:func\n__pointer_type_info_type_info_function = 0x201460; // type:func\nFUN_002014b0 = 0x2014B0; // type:func\nabort = 0x2014D0; // type:func\nget_ptr_rng = 0x2014F0; // type:func\n_init_signal_r = 0x201500; // type:func\n_raise_r = 0x201578; // type:func\nraise = 0x201668; // type:func\ngcc2_compiled.3 = 0x2016A0; // type:func\n_getpid_r = 0x201700; // type:func\nstrncpy = 0x201720; // type:func\nsceGsResetPath = 0x2018E8; // type:func\nsceGsSyncPath = 0x201988; // type:func\nsceGsResetGraph = 0x201A18; // type:func\nsceGsGetGParam = 0x201BA8; // type:func\nsceGsPutDispEnv = 0x201BB8; // type:func\nsceGsPutDrawEnv = 0x201C78; // type:func\nsceGsSetDefDBuff = 0x201D60; // type:func\nsceGsSwapDBuff = 0x201FF8; // type:func\nsceGsPutIMR = 0x202058; // type:func\nsceGsSetHalfOffset = 0x202098; // type:func\nFUN_00202120 = 0x202120; // type:func\nsceGsSetDefDispEnv = 0x202140; // type:func\nsceGszbufaddr = 0x2023B0; // type:func\nsceGsSetDefDrawEnv = 0x202478; // type:func\nsceGsSetDefClear = 0x202660; // type:func\nmemclr = 0x202768; // type:func\nsceDmaGetChan = 0x2027A0; // type:func\nsceDmaReset = 0x2027C8; // type:func\nsceDmaPutEnv = 0x2028A8; // type:func\nsceDmaSend = 0x202A80; // type:func\nsceDmaRecv = 0x202B68; // type:func\nsceDmaSync = 0x202C38; // type:func\nFUN_00202d08 = 0x202D08; // type:func\nsceCdDelayThread = 0x202D30; // type:func\ncmd_sem_init = 0x202EF0; // type:func\ncdvd_exit = 0x202F88; // type:func\nPowerOffCB = 0x203050; // type:func\n_sceCd_ncmd_prechk = 0x2030C0; // type:func\nsceCdNcmdDiskReady = 0x203230; // type:func\nsceCdSync = 0x2032C8; // type:func\nsceCdSyncS = 0x203368; // type:func\n_sceCd_scmd_prechk = 0x2033D8; // type:func\nsceCdInit = 0x203548; // type:func\nsceCdDiskReady = 0x203828; // type:func\nsceCdMmode = 0x203A20; // type:func\nsceCdGetReadPos = 0x203AE8; // type:func\nsceCdRead = 0x203B18; // type:func\nFUN_00203cf8 = 0x203CF8; // type:func\ncalls_cdCheckSCmd_etc = 0x203D90; // type:func\nsceCdBreak = 0x203E28; // type:func\nFUN_00203ee0 = 0x203EE0; // type:func\n__send_to_iop = 0x203FD0; // type:func\nscePadInit = 0x2040E8; // type:func\nscePadInit2 = 0x204228; // type:func\nscePadPortOpen = 0x2042C8; // type:func\nscePadGetDmaStr = 0x2044B0; // type:func\nscePadRead = 0x204510; // type:func\nscePadGetState = 0x204590; // type:func\nscePadSetReqState = 0x204610; // type:func\nscePadGetState1 = 0x204678; // type:func\nscePadInfoAct = 0x2046D0; // type:func\nscePadInfoMode = 0x2047F8; // type:func\nscePadSetMainMode = 0x204930; // type:func\nscePadSetActDirect = 0x2049E8; // type:func\nscePadSetActAlign = 0x204AA8; // type:func\nscePadGetButtonMask = 0x204B80; // type:func\nscePadSetButtonInfo = 0x204C38; // type:func\nscePadInfoPressMode = 0x204CE8; // type:func\nscePadEnterPressMode = 0x204D48; // type:func\nscePadGetModVersion = 0x204DB8; // type:func\n_sceSDC = 0x204E20; // type:func\nSyncDCache = 0x204EC8; // type:func\natanf = 0x204F68; // type:func\ncosf = 0x205210; // type:func\nfabsf = 0x2052F8; // type:func\nfloorf = 0x205318; // type:func\nsinf = 0x205400; // type:func\ntanf = 0x2054F0; // type:func\nacosf = 0x205578; // type:func\nasinf = 0x205678; // type:func\natan2f = 0x205778; // type:func\nfmodf = 0x2058A0; // type:func\nlogf = 0x2059E0; // type:func\nlog10f = 0x205B28; // type:func\npowf = 0x205C78; // type:func\nFUN_00206180 = 0x206180; // type:func\nFUN_00206298 = 0x206298; // type:func\n__ieee754_asinf = 0x2066C8; // type:func\n__ieee754_atan2f = 0x206A68; // type:func\n__ieee754_fmodf = 0x206D50; // type:func\n__ieee754_logf = 0x206FA0; // type:func\nFUN_002072c8 = 0x2072C8; // type:func\nFUN_002073f8 = 0x2073F8; // type:func\nFUN_00207c88 = 0x207C88; // type:func\n__ieee754_sqrtf = 0x208068; // type:func\n__kernel_cosf = 0x2081A0; // type:func\n__kernel_rem_pio2f = 0x2082F8; // type:func\n__kernel_sinf = 0x208C48; // type:func\nR_free = 0x208D50; // type:func\nmatherr = 0x208FE8; // type:func\nrint = 0x209010; // type:func\nfinitef = 0x209210; // type:func\nisnanf = 0x209238; // type:func\nscalbnf = 0x209260; // type:func\ncopysignf = 0x2093C0; // type:func\nFUN_002093f0 = 0x2093F0; // type:func\nFUN_002095b0 = 0x2095B0; // type:func\nFUN_002096e8 = 0x2096E8; // type:func\nFUN_00209720 = 0x209720; // type:func\nFUN_00209870 = 0x209870; // type:func\nFUN_00209990 = 0x209990; // type:func\nFUN_00209b10 = 0x209B10; // type:func\nFUN_00209b38 = 0x209B38; // type:func\nwait_for_sif_rpc_done_2QMARK = 0x209B80; // type:func\nFUN_00209cb8 = 0x209CB8; // type:func\nFUN_00209e48 = 0x209E48; // type:func\nFUN_00209fa8 = 0x209FA8; // type:func\nFUN_0020a078 = 0x20A078; // type:func\n_type2id = 0x20A190; // type:func\nsceMpegDemuxPssRing = 0x20A220; // type:func\nsceMpegDemuxPss = 0x20A518; // type:func\nsceMpegAddStrCallback = 0x20A538; // type:func\n_pack_header = 0x20A630; // type:func\n_system_header = 0x20A780; // type:func\n_PES_packet = 0x20A7F0; // type:func\nFUN_0020ada0 = 0x20ADA0; // type:func\nsceMpegCreate = 0x20AE40; // type:func\nSyncVBlank1 = 0x20B048; // type:func\nsceMpegGetPicture = 0x20B058; // type:func\nsceMpegIsEnd = 0x20B0B0; // type:func\nsceMpegReset = 0x20B0C0; // type:func\nsceMpegClearRefBuff = 0x20B110; // type:func\nsceMpegAddCallback = 0x20B168; // type:func\n_dispatchMpegCallback = 0x20B190; // type:func\n_dispatchMpegCbNodata = 0x20B1E0; // type:func\n_alalcInit = 0x20B240; // type:func\n_alalcSetDynamic = 0x20B258; // type:func\n_alalcFree = 0x20B268; // type:func\n_alalcAlloc = 0x20B278; // type:func\n_getpic = 0x20B2E8; // type:func\n_decodeOrSkipFrame = 0x20B458; // type:func\n_decodeOrSkip = 0x20B570; // type:func\n_decodeOrSkipField = 0x20B5B8; // type:func\n_sceMpegFlush = 0x20B718; // type:func\n_lastFrame = 0x20B790; // type:func\n_clearOnce = 0x20B810; // type:func\n_clearEach = 0x20B870; // type:func\n_ErrMessage = 0x20B930; // type:func\n_Error1 = 0x20B940; // type:func\n_Error = 0x20B978; // type:func\n_RefImageInit = 0x20B9D0; // type:func\n_sequenceHeader = 0x20B9F0; // type:func\n_initRefImages = 0x20BDC0; // type:func\n_setDefaultQM = 0x20BEA0; // type:func\n_sequenceExtension = 0x20BF78; // type:func\n_sequenceDisplayExtension = 0x20C0A8; // type:func\ngcc2_compiled.4 = 0x20C1A0; // type:func\n_getAllRefs = 0x20C3F0; // type:func\n_getRef0 = 0x20CAF8; // type:func\n_doMC = 0x20CF18; // type:func\n_ipuSetMPEG1 = 0x20DEE8; // type:func\n_waitBdecOut = 0x20DF10; // type:func\n_dmVector = 0x20E100; // type:func\n_dualPrimeVector = 0x20E120; // type:func\n_mbAddressIncrement = 0x20E2A8; // type:func\n_pictureData0 = 0x20E3B8; // type:func\n_sliceA0 = 0x20E4C0; // type:func\n_slice0 = 0x20E5F0; // type:func\n_skipMB0 = 0x20E7E0; // type:func\n_decMB0 = 0x20E8A0; // type:func\n_decode_motion_vector = 0x20ED48; // type:func\n_motionVectors = 0x20EDD0; // type:func\n_motionVector = 0x20EF70; // type:func\n_sendIpuCommand = 0x20F0C0; // type:func\n_waitIpuIdle = 0x20F0F0; // type:func\n_waitIpuIdle64 = 0x20F198; // type:func\n_ipuVdec = 0x20F248; // type:func\n_peepBit = 0x20F3C0; // type:func\n_flushBuf = 0x20F4C8; // type:func\n_sceMpegNextBit = 0x20F5B8; // type:func\n_nextStartCode = 0x20F708; // type:func\n_sliceB = 0x20F788; // type:func\n_nextHeader = 0x20F7F0; // type:func\n_pictureHeader = 0x20F900; // type:func\n_extensionAndUserData = 0x20F9C8; // type:func\n_pictureCodingExtension = 0x20FAF0; // type:func\n_extrainfo = 0x20FCE0; // type:func\n_groupOfPicturesHeader = 0x20FDA0; // type:func\n_quantMatrixExtension = 0x20FE40; // type:func\n_pictureDisplayExtension = 0x20FF08; // type:func\n_copyrightExtension = 0x210000; // type:func\n_decPicture = 0x210090; // type:func\n_outputFrame = 0x210160; // type:func\n_updateRefImage = 0x2101F0; // type:func\n_isOutSizeOK = 0x2104A8; // type:func\n_cpr8 = 0x210548; // type:func\n_getPtsDtsFlags = 0x2107E0; // type:func\n_dispRefImage = 0x210970; // type:func\n_dispRefImageField = 0x210A80; // type:func\ndmaRefImage = 0x210C38; // type:func\nreceiveDataFromIPU = 0x210D90; // type:func\n_doCSC = 0x210E00; // type:func\n_ch3dmaCSC = 0x210F18; // type:func\n_doCSC2 = 0x211090; // type:func\n_ch4dma = 0x211240; // type:func\n_csc_storeRefImage = 0x211348; // type:func\n_sysbitInit = 0x2115C0; // type:func\n_sysbitNext = 0x2115F8; // type:func\n_sysbitFlush = 0x211618; // type:func\n_sysbitGet = 0x2116B0; // type:func\n_sysbitMarker = 0x211700; // type:func\n_sysbitJump = 0x211748; // type:func\n_sysbitPtr = 0x2117A0; // type:func\nsetD3_CHCR = 0x2117D0; // type:func\nsetD4_CHCR = 0x211838; // type:func\nsceIpuRestartDMA = 0x211988; // type:func\nFUN_00211b40 = 0x211B40; // type:func\n"
  },
  {
    "path": "configure.py",
    "content": "\"\"\"\nConfigures the project for building. Invokes splat to split the binary and\ncreates build files for ninja.\n\"\"\"\n\n#! /usr/bin/env python3\nimport argparse\nimport os\nimport shutil\nimport sys\nimport json\nimport re\nfrom pathlib import Path\nfrom typing import List, Set\n\nimport ninja_syntax\nimport splat\nimport splat.scripts.split as split\nfrom splat.segtypes.linker_entry import LinkerEntry\n\n# MARK: Constants\nROOT = Path(__file__).parent.resolve()\nTOOLS_DIR = ROOT / \"tools\"\nOUTDIR = \"out\"\n\nYAML_FILE = Path(\"config/sly1.yaml\")\nBASENAME = \"SCUS_971.98\"\nLD_PATH = f\"{BASENAME}.ld\"\nELF_PATH = f\"{OUTDIR}/{BASENAME}\"\nMAP_PATH = f\"{OUTDIR}/{BASENAME}.map\"\nPRE_ELF_PATH = f\"{OUTDIR}/{BASENAME}.elf\"\n\nCOMMON_INCLUDES = \"-Iinclude -isystem include/sdk/ee -isystem include/gcc\"\n\nCC_DIR = f\"{TOOLS_DIR}/cc/bin\"\nCOMMON_COMPILE_FLAGS = (\n    f\"-x c++ -B{TOOLS_DIR}/cc/lib/gcc-lib/ee/2.95.2/ -O2 -G0 -ffast-math\"\n)\n\nWIBO = TOOLS_DIR / \"wibo-i686\"\nWINECMD = f\"{WIBO}\" if WIBO.exists() else \"WINEDEBUG=-all wine\"\n\nCOMPILE_CMD = f\"{CC_DIR}/ee-gcc.exe -c {COMMON_INCLUDES} {COMMON_COMPILE_FLAGS} $in\"\nif sys.platform == \"linux\":\n    COMPILE_CMD = (\n        f\"{WINECMD} {CC_DIR}/ee-gcc.exe -c {COMMON_INCLUDES} {COMMON_COMPILE_FLAGS} $in\"\n    )\n\nCATEGORY_MAP = {\n    \"P2\": \"Engine\",\n    \"splice\": \"Splice\",\n    \"ps2t\": \"Tooling\",\n    \"sce\": \"Libs\",\n    \"data\": \"Data\",\n}\n\n# Segment types that should be assembled\nASSEMBLABLE_TYPES = (\n    splat.segtypes.common.asm.CommonSegAsm,\n    splat.segtypes.common.data.CommonSegData,\n    splat.segtypes.common.databin.CommonSegDatabin,\n    splat.segtypes.common.rodatabin.CommonSegRodatabin,\n    splat.segtypes.common.textbin.CommonSegTextbin,\n    splat.segtypes.common.bin.CommonSegBin,\n)\n\n# Segment types that should be compiled\nCOMPILABLE_TYPES = (splat.segtypes.common.c.CommonSegC,)\n\n\ndef clean():\n    \"\"\"\n    Clean all products of the build process.\n    \"\"\"\n    files_to_clean = [\n        \".splache\",\n        \".ninja_log\",\n        \"build.ninja\",\n        \"permuter_settings.toml\",\n        \"objdiff.json\",\n        LD_PATH,\n    ]\n    for filename in files_to_clean:\n        if os.path.exists(filename):\n            os.remove(filename)\n\n    shutil.rmtree(\"asm\", ignore_errors=True)\n    shutil.rmtree(\"assets\", ignore_errors=True)\n    shutil.rmtree(\"obj\", ignore_errors=True)\n    shutil.rmtree(\"out\", ignore_errors=True)\n\n\ndef write_permuter_settings():\n    \"\"\"\n    Write the permuter settings file, comprising the compiler and assembler commands.\n    \"\"\"\n    with open(\"permuter_settings.toml\", \"w\", encoding=\"utf-8\") as f:\n        f.write(\n            f\"\"\"compiler_command = \"{COMPILE_CMD} -D__GNUC__\"\nassembler_command = \"mips-linux-gnu-as -march=r5900 -mabi=eabi -Iinclude\"\ncompiler_type = \"gcc\"\n\n[preserve_macros]\n\n[decompme.compilers]\n\"tools/build/cc/gcc/gcc\" = \"ee-gcc2.96\"\n\"\"\"\n        )\n\n\n# MARK: Build\ndef generate_ninja_build(\n    linker_entries: List[LinkerEntry],\n    skip_checksum=False,\n    objects_only=False,\n    dual_objects=False,\n):\n    \"\"\"\n    Generate ninja build rules for objects and the final ELF file.\n    If objects_only is True, only build objects and skip linking/checksum.\n    If dual_objects is True, build objects twice: once normally, once with -DSKIP_ASM.\n    \"\"\"\n    built_objects: Set[Path] = set()\n    objdiff_units = []  # For objdiff.json\n\n    def compute_object_path(obj_path: Path, out_dir: str = None) -> Path:\n        \"\"\"Compute the final object path, stripping .s or .c extensions if needed.\"\"\"\n        if not out_dir:\n            return obj_path\n\n        # Strip .s/.c extensions or handle .c.o/.s.o cases\n        if obj_path.suffix == \".o\" and obj_path.with_suffix(\"\").suffix in [\".s\", \".c\"]:\n            stem = obj_path.with_suffix(\"\").stem\n        else:\n            stem = obj_path.stem\n\n        return Path(out_dir) / (stem + \".o\")\n\n    def collect_objdiff_unit(object_path: Path, src_path: Path) -> None:\n        \"\"\"Collect objdiff metadata for a compilation unit.\"\"\"\n        if not src_path or \"target\" not in str(object_path):\n            return\n\n        # Compute relative path for name\n        try:\n            if src_path.parts[0] in [\"asm\", \"src\"]:\n                rel = Path(*src_path.parts[1:])\n            else:\n                rel = src_path\n            name = str(rel.with_suffix(\"\"))\n        except (IndexError, ValueError):\n            name = str(src_path.with_suffix(\"\"))\n\n        target_path = str(object_path)\n\n        # Check if source file exists in src/\n        src_base = rel.with_suffix(\"\")\n        has_src = any(Path(\"src\").rglob(src_base.name + ext) for ext in [\".c\", \".cpp\"])\n\n        # Determine categories\n        categories = [name.split(\"/\")[0]]\n        if \"P2/splice/\" in name:\n            categories.append(\"splice\")\n        elif \"P2/ps2t\" in name:\n            categories.append(\"ps2t\")\n\n        unit = {\n            \"name\": name,\n            \"target_path\": target_path,\n            \"metadata\": {\"progress_categories\": categories},\n        }\n\n        if has_src:\n            # Replace 'target' segment with 'current' in path\n            op = Path(object_path)\n            parts = list(op.parts)\n            for idx, part in enumerate(parts):\n                if part == \"target\":\n                    parts[idx] = \"current\"\n                    break\n            unit[\"base_path\"] = str(Path(*parts))\n\n        objdiff_units.append(unit)\n\n    def build_object(\n        object_path: Path,\n        src_paths: List[Path],\n        rule: str,\n        out_dir: str = None,\n        extra_flags: str = \"\",\n        collect_objdiff: bool = False,\n    ):\n        \"\"\"Build a single object file.\"\"\"\n        final_path = compute_object_path(object_path, out_dir)\n\n        if final_path.suffix == \".o\":\n            built_objects.add(final_path)\n\n        build_vars = {\"cflags\": extra_flags} if extra_flags else {}\n\n        ninja.build(\n            outputs=[str(final_path)],\n            rule=rule,\n            inputs=[str(s) for s in src_paths],\n            variables=build_vars,\n        )\n\n        if collect_objdiff and src_paths:\n            collect_objdiff_unit(final_path, src_paths[0])\n\n    with open(str(ROOT / \"build.ninja\"), \"w\", encoding=\"utf-8\") as f:\n        ninja = ninja_syntax.Writer(f, width=9999)\n\n        # MARK: Rules\n        cross = \"mips-linux-gnu-\"\n\n        ld_args = \"-EL -T config/undefined_syms_auto.txt -T config/undefined_funcs_auto.txt -Map $mapfile -T $in -o $out --no-warn-rwx-segments\"\n\n        ninja.rule(\n            \"as\",\n            description=\"as $in\",\n            command=f\"cpp {COMMON_INCLUDES} $in -o  - | {cross}as -no-pad-sections -EL -march=5900 -mabi=eabi -Iinclude -o $out\",\n        )\n\n        ninja.rule(\n            \"cc\",\n            description=\"cc $in\",\n            command=f\"{COMPILE_CMD} $cflags -o $out && {cross}strip $out -N dummy-symbol-name\",\n        )\n\n        ninja.rule(\n            \"ld\",\n            description=\"link $out\",\n            command=f\"{cross}ld {ld_args}\",\n        )\n\n        ninja.rule(\n            \"sha1sum\",\n            description=\"sha1sum $in\",\n            command=\"sha1sum -c $in && touch $out\",\n        )\n\n        ninja.rule(\n            \"elf\",\n            description=\"elf $out\",\n            command=f\"{cross}objcopy $in $out -O binary\",\n        )\n\n        # MARK: Object compilation\n        # Build all the objects\n        for entry in linker_entries:\n            seg = entry.segment\n\n            if seg.type[0] == \".\":\n                continue\n\n            if entry.object_path is None:\n                continue\n\n            # Determine rule based on segment type\n            rule = None\n            if isinstance(seg, COMPILABLE_TYPES):\n                rule = \"cc\"\n            elif isinstance(seg, ASSEMBLABLE_TYPES):\n                rule = \"as\"\n            else:\n                print(f\"ERROR: Unsupported build segment type {seg.type}\")\n                sys.exit(1)\n\n            # Build objects (single or dual mode)\n            if dual_objects:\n                build_object(\n                    entry.object_path,\n                    entry.src_paths,\n                    rule,\n                    out_dir=\"obj/target\",\n                    collect_objdiff=True,\n                )\n                build_object(\n                    entry.object_path,\n                    entry.src_paths,\n                    rule,\n                    out_dir=\"obj/current\",\n                    extra_flags=\"-DSKIP_ASM\",\n                )\n            else:\n                build_object(entry.object_path, entry.src_paths, rule)\n\n        if objects_only:\n            # Write objdiff.json if dual_objects (i.e. --objects)\n            if dual_objects:\n                objdiff = {\n                    \"$schema\": \"https://raw.githubusercontent.com/encounter/objdiff/main/config.schema.json\",\n                    \"custom_make\": \"ninja\",\n                    \"custom_args\": [],\n                    \"build_target\": False,\n                    \"build_base\": True,\n                    \"watch_patterns\": [\n                        \"src/**/*.c\",\n                        \"src/**/*.cp\",\n                        \"src/**/*.cpp\",\n                        \"src/**/*.cxx\",\n                        \"src/**/*.h\",\n                        \"src/**/*.hp\",\n                        \"src/**/*.hpp\",\n                        \"src/**/*.hxx\",\n                        \"src/**/*.s\",\n                        \"src/**/*.S\",\n                        \"src/**/*.asm\",\n                        \"src/**/*.inc\",\n                        \"src/**/*.py\",\n                        \"src/**/*.yml\",\n                        \"src/**/*.txt\",\n                        \"src/**/*.json\",\n                    ],\n                    \"units\": objdiff_units,\n                    \"progress_categories\": [\n                        {\"id\": id, \"name\": name} for id, name in CATEGORY_MAP.items()\n                    ],\n                }\n                with open(\"objdiff.json\", \"w\", encoding=\"utf-8\") as objdiff_file:\n                    json.dump(objdiff, objdiff_file, indent=2)\n            return\n\n        ninja.build(\n            PRE_ELF_PATH,\n            \"ld\",\n            LD_PATH,\n            implicit=[str(obj) for obj in built_objects],\n            variables={\"mapfile\": MAP_PATH},\n        )\n\n        ninja.build(\n            ELF_PATH,\n            \"elf\",\n            PRE_ELF_PATH,\n        )\n\n        if not skip_checksum:\n            ninja.build(\n                ELF_PATH + \".ok\",\n                \"sha1sum\",\n                \"config/checksum.sha1\",\n                implicit=[ELF_PATH],\n            )\n        else:\n            print(\"Skipping checksum step\")\n\n\n# MARK: Short loop fix\n# Pattern to workaround unintended nops around loops\nCOMMENT_PART = r\"\\/\\* (.+) ([0-9A-Z]{2})([0-9A-Z]{2})([0-9A-Z]{2})([0-9A-Z]{2}) \\*\\/\"\nINSTRUCTION_PART = r\"(\\b(bne|bnel|beq|beql|bnez|bnezl|beqzl|bgez|bgezl|bgtz|bgtzl|blez|blezl|bltz|bltzl|b)\\b.*)\"\nOPCODE_PATTERN = re.compile(f\"{COMMENT_PART}  {INSTRUCTION_PART}\")\n\nPROBLEMATIC_FUNCS = {\n    \"RefOpForEach__FiP4CRefP6CFrame\",             # P2/splice/bif\n    \"PredictAsegEffect__FP4ASEGffP3ALOT3iP6VECTORP7MATRIX3T6T6\", # P2/aseg\n    \"ProjectBlipgTransform__FP5BLIPGfi\",                         # P2/blip\n    \"ExplodeExplsExplso__FP5EXPLSP6EXPLSO\",                      # P2/emitter\n    \"ApplyDzg__FP3DZGiPiPPP2SOff\",                               # P2/dzg\n    \"UpdateJtActive__FP2JTP3JOYf\",                               # P2/jt\n    \"AddMatrix4Matrix4__FP7MATRIX4N20\",                          # P2/mat\n    \"FInvertMatrix__FiPfT1\",                                     # P2/mat\n    \"RenderMsGlobset__FP2MSP2CMP2RO\",                            # P2/ms\n    \"BounceRipgRips__FP4RIPG\",                                   # P2/rip\n    \"FUN_001aea70\",                                              # P2/screen\n    \"UpdateShadow__FP6SHADOWf\",                                  # P2/shadow\n    \"LoadShadersFromBrx__FP18CBinaryInputStream\",                # P2/shd\n    \"FillShaders__Fi\",                                           # P2/shd\n    \"UpdateStepPhys__FP4STEP\",                                   # P2/step\n    \"DrawTvBands__FP2TVR4GIFS\",                                  # P2/tv\n    \"FIgnoreUbgIntersection__FP3UBGP2SO\",                        # P2/ub\n    \"PwarpFromOid__F3OIDT0\",                                     # P2/xform\n    \"TriggerWarp__FP4WARP\"                                       # P2/xform\n}\n\ndef replace_instructions_with_opcodes(asm_folder: Path) -> None:\n    \"\"\"\n    Replace branch instructions with raw opcodes for functions that trigger the short loop bug.\n    \"\"\"\n    nm_folder = ROOT / asm_folder / \"nonmatchings\"\n\n    for p in nm_folder.rglob(\"*.s\"):\n        if p.stem not in PROBLEMATIC_FUNCS:\n            continue\n\n        with p.open(\"r\") as file:\n            content = file.read()\n\n        if re.search(OPCODE_PATTERN, content):\n            # Reference found\n            # Embed the opcode, we have to swap byte order for correct endianness\n            content = re.sub(\n                OPCODE_PATTERN,\n                r\"/* \\1 \\2\\3\\4\\5 */  .word      0x\\5\\4\\3\\2 /* \\6 */\",\n                content,\n            )\n\n            # Write the updated content back to the file\n            with p.open(\"w\") as file:\n                file.write(content)\n\n\n# MARK: Main\ndef main():\n    \"\"\"\n    Main function, parses arguments and runs the configuration.\n    \"\"\"\n    parser = argparse.ArgumentParser(description=\"Configure the project\")\n    parser.add_argument(\n        \"-c\",\n        \"--clean\",\n        help=\"Clean artifacts and build\",\n        action=\"store_true\",\n    )\n    parser.add_argument(\n        \"-C\",\n        \"--clean-only\",\n        help=\"Only clean artifacts\",\n        action=\"store_true\",\n    )\n    parser.add_argument(\n        \"-s\",\n        \"--skip-checksum\",\n        help=\"Skip the checksum step\",\n        action=\"store_true\",\n    )\n    parser.add_argument(\n        \"--objects\",\n        help=\"Build objects to obj/target and obj/current (with -DSKIP_ASM), skip linking and checksum\",\n        action=\"store_true\",\n    )\n    parser.add_argument(\n        \"-noloop\",\n        \"--no-short-loop-workaround\",\n        help=\"Do not replace branch instructions with raw opcodes for functions that trigger the short loop bug\",\n        action=\"store_true\",\n    )\n    args = parser.parse_args()\n\n    if args.clean or args.clean_only:\n        clean()\n        if args.clean_only:\n            return\n\n    split.main([YAML_FILE], modes=\"all\", verbose=False)\n\n    linker_entries = split.linker_writer.entries\n\n    if args.objects:\n        generate_ninja_build(\n            linker_entries, skip_checksum=True, objects_only=True, dual_objects=True\n        )\n    else:\n        generate_ninja_build(linker_entries, args.skip_checksum)\n\n    write_permuter_settings()\n\n    if not args.no_short_loop_workaround:\n        replace_instructions_with_opcodes(split.config[\"options\"][\"asm_path\"])\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "docs/BEGINNERSGUIDE.md",
    "content": "# Beginner's Guide\n\nIf you are new to using Git, follow these steps to get started. If you're already familiar with Git, go ahead and read the [contributing guide](/docs/CONTRIBUTING.md) instead.\n\n**1. Fork the repository on GitHub**\n\nClick the \"Fork\" button in the top-right corner of the [GitHub repository](https://github.com/theonlyzac/sly1). This will create a copy of the repository on your own GitHub account.\n\n**2. Clone the forked repository to your machine**\n\nUse a terminal or GitHub GUI to clone the forked repo to your machine.\n\n**3. Create a new branch for your changes**\n\nNavigate to the `sly1` directory in the terminal, and run the following command:\n\n```sh\ngit checkout -b branch-name\n```\n\nReplace `branch-name` with whatever you want to call your working branch. This will automatically create a new branch and switch to it.\n\n**4. Write & match your code**\n\nFollow the [Contributing Guide](/docs/CONTRIBUTING.md) to find functions to match, and write your code. You can use any text editor you like, but we recommend [VS Code](https://code.visualstudio.com/).\n\n**5. Commit the changes to your branch**\n\nWhenever you would like to save your progress to the fork, use these commands to add the files to a commit with a message describing what you did:\n\n```sh\ngit add file_you_changed.txt\ngit commit -m \"Describe what you did here\"\n```\n\nIf you don't care about adding specific files and just want to commit every file you changed, you can use this command instead:\n\n```sh\ngit commit -am \"Describe what you did here\"\n```\n\nThe commits are not backed up to GitHub until you `git push` to the repo in the next step.\n\n**6. Push the commits to your fork**\n\nWhen you are done making commits, push your branch to your forked repo.\n\n```sh\ngit push origin branch-name\n````\n\n**7. Create a pull request on GitHub**\n\nWhen you have pushed all commits to your fork and are ready to submit your code, create a pull request on GitHub.\n1. Go to your forked repository on GitHub and click the \"Pull requests\" tab.\n2. Click the \"New pull request\" button.\n3. Select your branch from the \"compare\" dropdown menu.\n4. Click \"Create pull request\".\n6. Add a title and brief description stating what you did for the person reviewing it.\n\n\n**8. Wait for someone to review your code**\n\nA code reviewer will review your PR and either merge it into the main branch, or let you know if there are any issues that need to be addressed. If you need to fix something, any commits you push to the same branch will be automatically added to the pull request until it is merged, at which point you will have to make another pull request if you continue working.\n"
  },
  {
    "path": "docs/CONTRIBUTING.md",
    "content": "# Contributing Guide\n\n## So you want to decompile Sly 1...\n\nYou've come to the right place! We welcome new contributors of all skill levels. This is a 100% volunteer-driven project, so all contributions are greatly appreciated. The current goal is to decompile and match as many game functions as possible.\n\nBy following this guide, you will learn how to fork the repo on GitHub, choose a function to reverse-engineer, write code to match it, and integrate that code into the project. Once your pull request is merged, you may get the Decomp Contributor role in the Discord Server.\n\nIf you're new to this, feel free to join our [Discord server](https://discord.gg/2GSXcEzPJA) and ask for help in #sly-research!\n\n## Contents\n\n1. [Getting Started](#getting-started)\n2. [Find a function to match](#find-a-function-to-match)\n3. [Match the function](#match-the-function)\n4. [Integrate the matched code](#integrate-the-matched-code)\n5. [Make a pull request](#make-a-pull-request)\n6. [Conclusion](#conclusion)\n\n## Getting started\n\nIf you haven't used Git before, follow the [Beginner's Guide](/docs/BEGINNERSGUIDE.md) to learn how to fork the repo, make changes, and create a pull request. Then follow the instructions in [README.md](/README.md) to build the project. If you see the following in the terminal, you're ready to start contributing:\n\n```bash\n[XXX/XXX] sha1sum config/checksum.sha1\nout/SCUS_971.98: OK\n```\n\n## Find a function to match\n\nFirst, find a function in the game that you want to match. There are a few ways to do this:\n\n* Browse Ghidra for interesting functions.\n* Look in the the source files in the `src` folder for non-matching functions (they have an `INCLUDE_ASM` macro as a placeholder).\n* Look in assembly files in the `asm/nonmatchings` folder.\n* Ask for suggestions on Discord.\n\n## Match the function\n\nOnce you have a function selected, you can start matching it using either **Objdiff** or **Decomp.me**. Both tools are used to match assembly code to C code, but they have different workflows.\n\n### Objdiff\n\n[Objdiff](https://github.com/encounter/objdiff), is a tool for showing the diff between a symbol in two object files. It is faster and more convenient then Decomp.me since it is included in the project, and doesn't require uploading anything to a website.\n\n1. Place your new function under the `INCLUDE_ASM` macro of the function you want to match wrapped in `#ifdef SKIP_ASM` like so:\n\n   ```cpp\n   INCLUDE_ASM(\"asm/nonmatchings/P2/difficulty\", OnDifficultyGameLoad__FP10DIFFICULTY);\n   #ifdef SKIP_ASM\n   void OnDifficultyGameLoad(DIFFICULTY *pdifficulty)\n   {\n      ...\n   }\n   #endif\n   ```\n2. From the project root, run `./scripts/diff.sh FunctionName [ObjectName]`.\n    * Replace `FunctionName` with the **mangled name** of the function you want to match.\n    * Optionally, provide `ObjectName` using the name of the object file (without extension) if you know which file contains the function.\n3. Edit the source code until the function matches. The CURRENT assembly will update every time you save the file.\n\n**Example:** To match `OnDifficultyGameLoad` defined in `P2/difficulty.c`, run this command:\n```bash\n./scripts/diff.sh OnDifficultyGameLoad__FP10DIFFICULTY P2/difficulty\n```\n\n### Decomp.me\n\n[decomp.me](https://decomp.me/) is a website for collaborative decompilation. It allows you to upload assembly code and create a \"scratch\" for matching the function. It is recommended if you are collaborating with others or need to ask for help with a function.\n\n1. Go to [the website](https://decomp.me) and click \"Start decomping\".\n2. Click \"PS2\" > \"Preset\" > \"Sly Cooper and the Thievius Raccoonus\".\n3. Under \"Diff label\", enter the name of the function.\n4. Find the `.s` file of the function you want to match in the `asm/nonmatchings` folder. Copy the contents of the file into the \"Target assembly\" box.\n5. If the function references any other  functions, global variables, or data types, copy those from the relevant headers into the \"Context\" box.\n   * E.g. For the function `void ResetClock(struct CLOCK* pclock, float t)`, you will need to include the definition of `CLOCK` struct, as well as the `TICK` datatype since it is used in the `CLOCK` struct.\n6. Click \"Create scratch\".\n7. **(Recommended)** Go to the \"Options\" tab and under \"Debug information\" select `-g3 (Macro expansions)`. This will show you which line numbers the source code correspond to each line in the assembly.\n\nThen start writing your code under the \"Source code\" tab. It will tell you what percent of the code matches the original. Tweak the code until it matches 100%. An example scratch can be found here: https://decomp.me/scratch/hmmyP\n\n## Integrate the matched code\n\nOnce the function matches 100%, follow these steps to integrate it into the project. If you used objdiff, you probably already did this.\n1. Replace the `INCLUDE_ASM` macro in the `.c` file with the matched function.\n   * If the function is in a new file, **do not create a new file**. Creating new `.c` files is done by editing the `config/sly1.yaml` file to change the file split from `asm` to `c`, then running `python3 configure.py` to generate the new file. If you don't know how to do this, feel free to ask for help in the Discord server.\n2. Check `config/symbol_addrs.txt` to see if the mangled name of the function is present.\n   * If it is not, add the **mangled name** of the function with its address. The mangled name of the function can be found in the debug symbols for the May 2002 prototype. If you don't know how to find it, ask for help in the Discord server; someone will be able to find it for you easily.\n   * The symbol_addrs.txt file is grouped alphabetically by filename, then sorted by address within the file.\n\nThe project should build and match. Here are some common troubleshooting tips:\n* `undefined reference error` usually means the entry in the symbol_addrs.txt is wrong. Make sure the function name is mangled in symbol_addrs.txt and unmangled in the source code, and the mangled version matches the signature of the function. Also ensure that the address is correct in symbol_addrs.txt.\n* `checksum failed` means the compiled elf with your added code doesn't match the original. If it matches on decomp.me but not in the project, it might be an issue with the compiler, so open an issue on GitHub or let someone know on Discord.\n* `ninja: no work to do` in diff.sh likely means the name of the function is wrong in your command and/or in symbol_addrs.txt. Make sure you are using the correct mangled name of the function in both places.\n\n<!--### CodeMatcher\n\nYou can use [CodeMatcher](https://github.com/felinis/CodeMatcher) to help match your code against the original code. It can compile and match the entire source tree or just one file at a time. Matching against the release elf is not fully set up yet, so for now we are matching against the [May 19 2002 prototype](https://hiddenpalace.org/Sly_Cooper_and_the_Thievius_Raccoonus_(May_19,_2002_prototype)). For instructions on using CodeMatcher, see the [Code Matching Guide](/tools/codematcher/README.md).\n\nIf you are adding new code, it is strongly recommended that you run CodeMatcher before submitting a pull request. We will accept pull requests that don't match as long as the code is clean and readable, but in the future we may require that your code matches before merging it into the main branch.-->\n\n## Make a pull request\n\nOnce you add your code to the project and it builds + matches, you can open a pull request to merge your fork into the main branch of the project. A code reviewer will need to approve it before it can be merged into the main branch.\n\nWe are a volunteer-driven project, so please be patient while we review your code. These are the main things we will look for in your code:\n\n* It compiles without any errors.\n* The compiled elf matches the original elf.\n\nIf everything looks good, we will merge your pull request as soon as possible. We may fix small typos and make style edits for you. If anything needs to be addressed, we will let you know.\n\n## Conclusion\n\nThank you for reading, and we appreciate any contributions you make to the project! The project is 100% volunteer-driven, so perfection is not required. The most important thing is to have fun and learn something new about the game.\n\nIf you have any questions or concerns, feel free to ask in the [Discord server](https://discord.gg/2GSXcEzPJA) or [open an issue](https://github.com/TheOnlyZac/sly1/issues/new) on GitHub.\n"
  },
  {
    "path": "docs/DISTROBOX.md",
    "content": "# Using Distrobox for Non-Debian Distributions\n\nIf you're using a non-Debian Linux distribution (such as Fedora, Arch, openSUSE, etc.), you can use [Distrobox](https://distrobox.it/) to create a Debian container and follow the standard setup instructions.\n\n## What is Distrobox?\n\nDistrobox is a tool that lets you create and manage containerized Linux environments that integrate seamlessly with your host system. Unlike traditional containers, Distrobox containers share your home directory to allow collaboration with the host system. You can edit the code in your favorite editor and build the project in the container using those same files.\n\nThis makes it perfect for development work where you need a specific distribution's tooling.\n\n## Installing Distrobox\n\n### Fedora:\n```bash\nsudo dnf install distrobox\n```\n\n### Arch Linux:\n```bash\nsudo pacman -S distrobox\n```\n\n### openSUSE:\n```bash\nsudo zypper install distrobox\n```\n\n## Setting up the Debian Container\n\n### 1. Create the container\n\nCreate a Debian container. It can be named anything but for this example we use `sly1-dev`:\n\n```bash\ndistrobox create --name sly1-dev --init --image debian:latest --additional-packages \"git\"\n```\n\nThis downloads the latest Debian image and creates a new container.\n\n### 2. Enter the container\n\n```bash\ndistrobox enter sly1-dev\n```\n\nThe first time you enter, Distrobox will set up the container environment.\n\n### 3. Verify you're in the container\n\nYour terminal prompt should change to indicate you're in the container (typically showing `user@sly1-dev`). You can further verify with:\n\n```bash\ncat /etc/os-release\n```\n\nWhich should show Debian information.\n\n## Following the Setup Instructions\n\nOnce inside the container, you can follow the [README instructions](../README.md#-quickstart).\n\nAgain, your home directory is shared between the host and container, so you can clone the repository using either.\n\n## Exiting the Container\n\nWhen you're done working, simply exit the container:\n\n```bash\nexit\n```\n\nOr press `Ctrl+D`.\n\n## Working with the Container\n\n### Re-entering the container\n\nWhenever you want to build the project, just enter the container again:\n\n```bash\ndistrobox enter sly1-dev\ncd ~/path/to/sly1\n```\n\n### Running commands from outside\n\nYou can also run commands inside the container without entering it:\n\n```bash\ndistrobox enter sly1-dev -- ./scripts/build.sh\n```\n\n### Stopping the container\n\nContainers are automatically stopped when not in use. To manually stop:\n\n```bash\ndistrobox stop sly1-dev\n```\n\n### Removing the container\n\nIf you need to start fresh:\n\n```bash\ndistrobox rm sly1-dev\n```\n\nThis deletes the container and any packages installed within it. You will need to complete the setup instructions again if you create a new container.\n\n## Troubleshooting\n\n### Run.sh is not finding PCSX2\n\nIf PCSX2 is installed on the host system via package manager the container will not be able to find it. Either exit the container or install PCSX2 in a way the container can access, such as the container package manager, Flatpak or AppImage.\n"
  },
  {
    "path": "docs/STYLEGUIDE.md",
    "content": "# Style Guide\n\n## Contents\n\n1. [General Rules](#general-rules)\n2. [Symbol Names](#symbol-names)\n3. [Documentation](#documentation)\n4. [Example Code](#example-code)\n\n\n## General Rules\n\nPlease try and follow these general rules when writing your code:\n\n* Indent with 4 spaces, not tabs.\n* Put opening curly braces on a new line.\n* Don't leave trailing whitespace at the end of lines.\n* End every file with a single blank line.\n* Keep lines between 80-100 characters long at most.\n\n## Symbol Names\n\nFor new symbols (i.e. classes, variables, and functions), use the official name from the [May 19 2002 demo](https://hiddenpalace.org/Sly_Cooper_and_the_Thievius_Raccoonus_(May_19,_2002_prototype)) if it is known. If it is not known, use a clear and descriptive name.\n\nWhen making up symbol names, mimic the style of the official symbol names, Official names use a variation of [Hungarian Notation](https://en.wikipedia.org/wiki/Hungarian_notation). The most important part is the prefixes used to denote the **type** and **scope** of a symbol, as shown below.\n\nThese prefixes denote the **type** of a symbol:\n\n| Prefix | Type                           | Examples                                                       |\n|--------|--------------------------------|----------------------------------------------------------------|\n| `p`    | Pointer                        | `CLOCK* pclock` - Pointer to an instance of the CLOCK struct   |\n| `n`    | Integer/numeric value          | `int nScore` - Numeric score value                             |\n| `c`    | Integer/count or quantity      | `int ccoin`- A quantity of coins                               |\n| `f`    | Flag (boolean)                 | `int fSneakyFeet` - Footstep noises flag                       |\n| `l`    | Long                           | `long lTime` - A time in seconds                               |\n| `d`    | Float                          | `float dTime` - A time in seconds                              |\n| `ch`   | Char                           | `char chCur` - Current character in a loop                     |\n| `b`    | Byte                           | `byte bData` - A single byte of data                           |\n| `u`    | Unsigned                       | `float uSuck` - Unsigned value representing the player's suck score |\n| `z`    | Zero-terminated string         | `char chzBuffer[64]` - Zero-terminated string buffer           |\n| `C`    | Class                          | `class CBinaryInputStream` - Class that reads data from binary streams |\n\nThese prefixes denote the **scope** of a variable:\n\n| Prefix | Type                           | Examples                                                       |\n|--------|--------------------------------|----------------------------------------------------------------|\n| `g_`   | Global variable                | `LM g_lmZeroOne` - A global LM struct                          |\n| `m_`   | Class member                   | `int m_cbRaw` - Count of raw bytes on a CBinaryInputStream     |\n| `s_`   | Static class member            | `TICK s_tickLastRaw` - Static value for last raw tick on CLOCK struct |\n\nExamples of combining these prefixes:\n* `g_pgsCur` - Pointer to the current global GS struct\n* `g_pchzArgs` - Pointer a global zero-terminated char array of arguments\n* `m_cbBulkData` - Class member variable that stores the count of bytes in a data block\n\n### Capitalization\n\nUse `ALLCAPS` for struct/enum names.\n* e.g. `struct DIFFICULTY`, `enum FLS`\n\nUse `UpperCamelCase` for function names, classes and enum values.\n* e.g. `void OnDifficultyGameLoad()`, `class CBinaryInputStream`, `FCHT_InfiniteCharms`\n\nUse `lowerCamelCase` for local variables, function parameters, and class members.\n* e.g. `char nextXorChar`, `Coin* pcoin`, `float m_rxScale`\n\n\n## Documentation\n\nComment your code with [Doxygen-style comments](http://micro-os-plus.github.io/develop/doxygen-style-guide/). They will be used to automatically generate a [documentation website](https://theonlyzac.github.io/sly1). You don't need to read the whole Doxygen style guide, just follow these rules.\n\n### File Comments\n\nPut file comments at the top of each file, before any includes.\n```c\n/**\n * @file filename.xyz\n * @brief A brief description of the file.\n *\n * @details A longer description of the file that goes into more detail\n * if you feel it is necessary.\n */\n```\n\n### Function Comments\n\nPut function comments before the declaration of each function in the header files.\n```c\n/**\n * @brief A brief summary of the function.\n *\n * @details A longer summary of the function that goes into more detail\n * if you feel it is necessary.\n *\n * @param param1 Description of the first parameter\n * @param param2 Description of the second parameter\n * ...\n *\n * @return What the function returns, if not void\n */\nint ExampleFunction(param1, param2, ...);\n```\n\nDocument all parameters and return values using `@param` and `@return`/`@retval`, even if they are obvious. You can omit them if the function has no parameters or returns void.\n\n#### Class Comments\n\nPut class (and struct) comments before the class declaration in the header file.\n```c\n/**\n * @brief Full name of the struct/class.\n *\n * @details A longer summary of the struct/class that goes into more detail\n * if you feel it is necessary.\n */\n```\n\n### Todo and Notes\n\nUse `@todo` to mark something that needs to be done in the future.\n```c\n/**\n * ...\n * @todo Implement this function.\n * ...\n */\n```\n\nUse `@note` to add a note which will be differentiated from the rest of the comment.\n```c\n/**\n * ...\n * @note The name of this struct is not official.\n * ...\n */\n```\n\n\n## Example Code\n\nThis code is clear and conforms to the style guide:\n```c\n// joy.h\n\n/**\n * @brief Activates a cheat code.\n *\n * @details Sets the given flag on the global fcht variable. Also reloads the\n * level if it is a reload code.\n *\n * @param nparam Cheat code to check\n*/\nvoid AddFcht(int nParam);\n\n\n// joy.cpp\n\nvoid AddFcht(int nParam)\n{\n    g_grfcht |= nParam & ~(int)FCHT_ResetWorld;\n\n    // Check if reload flag is set\n    if ((nParam & 0x4000) != 0)\n    {\n        ResetWorld(FTRANS_None);\n    }\n}\n```\n\nThis code does **not** conform to the style guide and should be rewritten:\n```cpp\n// vec.h\n\n// Sets the vector cylinder\nvoid SetVectorCylind(float x, float y, float z, VECTOR* pvec);\n\n\n// vec.cpp\n\nvoid SetVectorCylind(float param_1, float param_2, float param_3, VECTOR* param_4)\n{\n    float local_40;\n    float local_3c;\n\n    //CalculateSinCos(param_1, &local_40, (float*)((uint32_t)&local_40 | 4));\n    param_4->z = param_3;\n    param_4->x = local_3c * param_2;\n    param_4->y = local_40 * param_2;\n    return;\n}\n```\n"
  },
  {
    "path": "include/989snd.h",
    "content": "/**\n * @file 989snd.h\n *\n * @brief 989snd sound driver.\n */\n#ifndef SND989_H\n#define SND989_H\n\n#include \"sdk/libcdvd.h\"\n\ntypedef unsigned int u_int;\ntypedef unsigned long u_long;\n\nextern \"C\" {\n\ntypedef void (*SndCompleteProc)(int, u_long);\ntypedef void* SoundBankPtr;\n\nvoid snd_StartSoundSystem(void);\nint snd_FlushSoundCommands(void);\nSoundBankPtr snd_BankLoadByLoc(int loc, int offset);\nvoid snd_BankLoadByLoc_CB(int loc, int offset, SndCompleteProc cb, u_long user_data);\nvoid snd_ResolveBankXREFS(void);\nvoid snd_UnloadBank(SoundBankPtr bank);\nvoid snd_SetMasterVolume(int which, int vol);\nint snd_GetMasterVolume(int which);\nvoid snd_SetPlaybackMode(int mode);\nvoid snd_SetMixerMode(int channel_mode, int reverb_mode);\nvoid snd_SetGroupVoiceRange(int group, int min, int max);\nu_int snd_PlaySoundVolPanPMPB(SoundBankPtr bank, int sound, int vol, int pan, int pitch_mod, int bend);\nvoid snd_StopSound(u_int handle);\nvoid snd_PauseSound(u_int handle);\nvoid snd_ContinueSound(u_int handle);\nvoid snd_PauseAllSoundsInGroup(u_int groups);\nvoid snd_ContinueAllSoundsInGroup(u_int groups);\nu_int snd_SoundIsStillPlaying(u_int handle);\nvoid snd_SoundIsStillPlaying_CB(u_int handle, SndCompleteProc cb, u_long user_data);\nint snd_IsSoundALooper(SoundBankPtr bank, u_int sound);\nvoid snd_SetSoundVolPan(u_int handle, int vol, int pan);\nint snd_GetSoundOriginalPitch(SoundBankPtr bank, int index);\nvoid snd_SetSoundPitch(u_int handle, int pitch);\nvoid snd_AutoVol(u_int handle, int vol, int delta_time, int delta_from);\nvoid snd_SetMIDIRegister(u_int handle, int reg, int value);\nint snd_GetMIDIRegister(u_int handle, int reg);\nvoid snd_SetGlobalExcite(int value);\nint snd_InitVAGStreamingEx(int num_channels, int buffer_size, unsigned int read_mode, int enable_streamsafe_from_ee);\nvoid snd_StopAllStreams(void);\nu_int snd_PlayVAGStreamByLoc(int loc1, int loc2, int offset1, int offset2, int vol, int pan, int vol_group, u_int queue, u_int flags);\nvoid snd_ContinueVAGStream(u_int stream);\nvoid snd_IsVAGStreamBuffered_CB(u_int stream, SndCompleteProc cb, u_long user_data);\nint snd_StreamSafeCheckCDIdle(int block_ee_iop);\nint snd_StreamSafeCdRead(u_int lbn, u_int sectors, void* buf, sceCdRMode* mode);\nint snd_StreamSafeCdSync(int mode);\nint snd_StreamSafeCdBreak(void);\nint snd_StreamSafeCdGetError(void);\nvoid snd_SetReverbType(int core, int type);\nvoid snd_SetReverbDepth(int core, int left, int right);\nvoid snd_PreAllocReverbWorkArea(int core, int type);\nint snd_InitMovieSound(int sizeOfIOPBuffer, int volumeLevel, int panCenter, int volumeGroup, int unk);\nvoid snd_ResetMovieSound(void);\nvoid snd_CloseMovieSound(void);\nvoid snd_StartMovieSound(int iopBuffer, int iopBufferSize, int iopPausePosition, u_int sr, int ch);\nint snd_GetTransStatus(void);\nint snd_GetDopplerPitchMod(int approaching_mph);\n}\n\n#endif // SND989_H\n"
  },
  {
    "path": "include/ac.h",
    "content": "/**\n * @file ac.h\n *\n * @todo Implement the structs.\n */\n#ifndef AC_H\n#define AC_H\n\n#include \"common.h\"\n#include <vec.h>\n#include <mat.h>\n#include <bis.h>\n#include <alo.h>\n\ntypedef int GRFEVAL;\n\n/**\n * @brief (?) kind.\n */\nenum ACVK\n{\n    ACVK_Nil = -1,\n    ACVK_Component = 0,\n    ACVK_Bezier = 1,\n    ACVK_Blend = 2,\n    ACVK_Max = 3\n};\n\n/**\n * @brief (?) kind.\n */\nenum ACGK\n{\n    ACGK_Nil = -1,\n    ACGK_Bezier = 0,\n    ACGK_BezierWeighted = 1,\n    ACGK_Linear = 2,\n    ACGK_BlendTwist = 3,\n    ACGK_BlendPose = 4,\n    ACGK_Max = 5,\n};\n\n/**\n * @brief Unknown.\n */\nstruct KVB\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACR\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACS\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACG\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACPBL : public ACP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACPC : public ACP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACPB : public ACP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACRC : public ACR\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACRB : public ACR\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACRBL : public ACR\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACSC : public ACS\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACSB : public ACS\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACGB : public ACG\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACGBW : public ACG\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACGL : public ACG\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACGBLT : public ACG\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ACGBLP : public ACG\n{\n    // ...\n};\n\nvoid FindKey(float t, GRFEVAL grfeval, int cbKey, int ckey, char *abKey, float *pdt, float *pdtSeg, void **ppv);\n\nvoid EvaluateAcp(ACP *pacp, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *ppos, VECTOR *pv);\n\nvoid GetAcpTimes(ACP *pacp, int *pct, float **pat);\n\nvoid EvaluateAcr(ACR *pacr, ALO *palo, float t, float svt, GRFEVAL grfeval, MATRIX3 *pmat, VECTOR *pw);\n\nvoid EvaluateAcrEul(ACR *pacr, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *peul, VECTOR *pdeul);\n\nvoid GetAcrTimes(ACR *pacr, int *pct, float **pat);\n\nvoid EvaluateAcs(ACS *pacs, ALO *palo, float t, GRFEVAL grfeval, MATRIX3 *pmat);\n\nvoid GetAcsTimes(ACS *pacs, int *pct, float **pat);\n\nvoid EvaluateAcg(ACG *pacg, ALO *palo, float t, float svt, GRFEVAL grfeval, float *pg, float *pdg);\n\nvoid GetAcgTimes(ACG *pacg, int *pct, float **pat);\n\nvoid LoadAcgbFromBrx(ACGB *pacgb, CBinaryInputStream *pbis);\n\nvoid EvaluateAcgb(ACGB *pacgb, ALO *palo, float t, float svt, GRFEVAL grfeval, float *pg, float *pdg);\n\nvoid GetAcgbTimes(ACGB *pacgb, int *pct, float **pat);\n\nvoid LoadAcgbwFromBrx(ACGBW *pacgbw, CBinaryInputStream *pbis);\n\nvoid EvaluateAcgbw(ACGBW *pacgbw, ALO *palo, float t, float svt, GRFEVAL grfeval, float *pg, float *pdg);\n\nvoid GetAcgbwTimes(ACGBW *pacgbw, int *pct, float **pat);\n\nvoid EvaluateAcgl(ACGL *pacgl, ALO *palo, float t, float svt, GRFEVAL grfeval, float *pg, float *pdg);\n\nvoid LoadAcglFromBrx(ACGL *pacgl, CBinaryInputStream *pbis);\n\nvoid GetAcglTimes(ACGL *pacgl, int *pct, float **pat);\n\nvoid EvaluateApacg(ACG **apacg, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *pvecDefault, VECTOR *pvec, VECTOR *pdvec);\n\nvoid LoadApacgFromBrx(ACG **apacg, VECTOR *pvecDefault, CBinaryInputStream *pbis);\n\nvoid GetApacgTimes(ACG **apacg, int *pct, float **pat);\n\nvoid EvaluateAkvb(int ckvb, KVB *akvb, float t, float svt, GRFEVAL grfeval, VECTOR *pvec, VECTOR *pdvec);\n\nvoid LoadAkvbFromBrx(int *pckvb, KVB **pakvb, CBinaryInputStream *pbis);\n\nvoid GetAkvbTimes(int ckvb, KVB *akvb, int *pct, float **pat);\n\nvoid EvaluateAcpc(ACPC *pacpc, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *ppos, VECTOR *pv);\n\nvoid LoadAcpcFromBrx(ACPC *pacpc, CBinaryInputStream *pbis);\n\nvoid GetAcpcTimes(ACPC *pacpc, int *pct, float **pat);\n\nvoid EvaluateAcpb(ACPB *pacpb, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *ppos, VECTOR *pv);\n\nvoid LoadAcpbFromBrx(ACPB *pacpb, CBinaryInputStream *pbis);\n\nvoid GetAcpbTimes(ACPB *pacpb, int *pct, float **pat);\n\nvoid EvaluateAcrc(ACRC *pacrc, ALO *palo, float t, float svt, GRFEVAL grfeval, MATRIX3 *pmat, VECTOR *pw);\n\nvoid EvaluateAcrcEul(ACRC *pacrc, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *peul, VECTOR *pdeul);\n\nvoid LoadAcrcFromBrx(ACRC *pacrc, CBinaryInputStream *pbis);\n\nvoid GetAcrcTimes(ACRC *pacrc, int *pct, float **pat);\n\nvoid EvaluateAcrb(ACRB *pacrb, ALO *palo, float t, float svt, GRFEVAL grfeval, MATRIX3 *pmat, VECTOR *pw);\n\nvoid EvaluateAcrbEul(ACRB *pacrb, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *peul, VECTOR *pdeul);\n\nvoid LoadAcrbFromBrx(ACRB *pacrb, CBinaryInputStream *pbis);\n\nvoid GetAcrbTimes(ACRB *pacrb, int *pct, float **pat);\n\nvoid EvaluateAcsc(ACSC *pacsc, ALO *palo, float t, GRFEVAL grfeval, MATRIX3 *pmat);\n\nvoid LoadAcscFromBrx(ACSC *pacsc, CBinaryInputStream *pbis);\n\nvoid GetAcscTimes(ACSC *pacsc, int *pct, float **pat);\n\nvoid EvaluateAcsb(ACSB *pacsb, ALO *palo, float t, GRFEVAL grfeval, MATRIX3 *pmat);\n\nvoid LoadAcsbFromBrx(ACSB *pacsb, CBinaryInputStream *pbis);\n\nvoid GetAcsbTimes(ACSB *pacsb, int *pct, float **pat);\n\nvoid EvaluateAcpbl(ACPBL *pacpbl, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *ppos, VECTOR *pv);\n\nvoid EvaluateAcrbl(ACRBL *pacrbl, ALO *palo, float t, float svt, GRFEVAL grfeval, MATRIX3 *pmat, VECTOR *pw);\n\nvoid EvaluateAcgblt(ACGBLT *pacgblt, ALO *palo, float t, float svt, GRFEVAL grfeval, float *pg, float *pdg);\n\nvoid EvaluateAcgblp(ACGBLP *pacgblp, ALO *palo, float t, float svt, GRFEVAL grfeval, float *pg, float *pdg);\n\nACP *PacpNew(ACVK acvk);\n\nACR *PacrNew(ACVK acvk);\n\nACS *PacsNew(ACVK acvk);\n\nACG *PacgNew(ACGK acgk);\n\n#endif // AC_H\n"
  },
  {
    "path": "include/act.h",
    "content": "/**\n * @file act.h\n */\n#ifndef ACT_H\n#define ACT_H\n\n#include \"common.h\"\n#include <vec.h>\n#include <mat.h>\n#include <dl.h>\n\n// Forward.\nstruct SW;\nstruct ALO;\n\ntypedef int GRFRA;\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ACT\n{\n    /* 0x00 */ STRUCT_PADDING(1); // TODO: Add vtables\n    /* 0x04 */ ALO *palo;\n    /* 0x08 */ DLE dleAlo;\n    /* 0x10 */ STRUCT_PADDING(1);\n    /* 0x14 */ int nPriority;\n    /* 0x18 */ float tMatch;\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ACTVAL : public ACT\n{\n    /* 0x1c */ STRUCT_PADDING(25);\n    /* 0x80 */ float radTwistGoal;\n    /* 0x84 */ float dradTwistGoal;\n    /* 0x88 */ STRUCT_PADDING(15);\n    /* 0xc4 */ float *agPoses;\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ACTREF : public ACT\n{\n    /* 0x1c */ STRUCT_PADDING(4);\n    /* 0x2c */ float *pradTwistGoal;\n    /* 0x30 */ float *pdradTwistGoal;\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ACTADJ : public ACT\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ACTBANK : public ACT\n{\n    /* 0x1c */ float uBank;\n    /* 0x20 */ float dtPredict;\n};\n\nACT *PactNew(SW *psw, ALO *palo, VTACT *pvtact);\n\nACT *PactNewClone(ACT *pactBase, SW *psw, ALO *palo);\n\nvoid CloneAct(ACT *pact, ACT *pactBase);\n\nvoid InitAct(ACT *pact, ALO *palo);\n\nvoid RetractAct(ACT *pact, GRFRA grfra);\n\nvoid GetActPositionGoal(ACT *pact, float dtOffset, VECTOR *ppos, VECTOR *pv);\n\nvoid GetActRotationGoal(ACT *pact, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\nvoid GetActTwistGoal(ACT *pact, float *pradTwist, float *pdradTwist);\n\nvoid GetActScale(ACT *pact, MATRIX3 *pmat);\n\nfloat GGetActPoseGoal(ACT *pact, int ipose);\n\nvoid CalculateActDefaultAck(ACT *pact);\n\nvoid SnapAct(ACT *pact, int fForce);\n\nvoid CalculateAloPositionSpring(ALO *palo, float dt, VECTOR *pposGoal, VECTOR *pvGoal, VECTOR *pdv);\n\nvoid ProjectActPosition(ACT *pact);\n\nvoid CalculateAloRotationSpring(ALO *palo, float dt, MATRIX3 *pmatGoal, VECTOR *pwGoal, VECTOR *pdw);\n\nvoid ProjectActRotation(ACT *pact);\n\nvoid ProjectActPose(ACT *pact, int ipose);\n\nvoid PredictAloPosition(ALO *palo, float dtOffset, VECTOR *ppos, VECTOR *pv);\n\nvoid PredictAloRotation(ALO *palo, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\nvoid AdaptAct(ACT *pact);\n\nvoid InitActval(ACTVAL *pactval, ALO *palo);\n\nvoid GetActvalPositionGoal(ACTVAL *pactval, float dtOffset, VECTOR *ppos, VECTOR *pv);\n\nvoid GetActvalRotationGoal(ACTVAL *pactval, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\nvoid GetActvalTwistGoal(ACTVAL *pactval, float *pradTwist, float *pdradTwist);\n\nvoid GetActvalScale(ACTVAL *pactval, MATRIX3 *pmat);\n\nfloat GGetActvalPoseGoal(ACTVAL *pactval, int ipose);\n\nvoid InitActref(ACTREF *pactref, ALO *palo);\n\nvoid GetActrefPositionGoal(ACTREF *pactref, float dtOffset, VECTOR *ppos, VECTOR *pv);\n\nvoid GetActrefRotationGoal(ACTREF *pactref, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\nvoid GetActrefTwistGoal(ACTREF *pactref, float *pradTwist, float *pdradTwist);\n\nvoid GetActrefScale(ACTREF *pactref, MATRIX3 *pmat);\n\nfloat GGetActrefPoseGoal(ACTREF *pactref, int ipose);\n\nvoid InitActadj(ACTADJ *pactadj, ALO *palo);\n\nvoid GetActadjPositionGoal(ACTADJ *pactadj, float dtOffset, VECTOR *ppos, VECTOR *pv);\n\nvoid GetActadjRotationGoal(ACTADJ *pactadj, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\nvoid GetActadjTwistGoal(ACTADJ *pactadj, float *pradTwist, float *pdradTwist);\n\nvoid GetActadjScale(ACTADJ *pactadj, MATRIX3 *pmat);\n\nfloat GGetActadjPoseGoal(ACTADJ *pactadj, int ipose);\n\nvoid InitActbank(ACTBANK *pactbank, ALO *palo);\n\nvoid GetActbankRotationGoal(ACTBANK *pactbank, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\n#endif // ACT_H\n"
  },
  {
    "path": "include/actseg.h",
    "content": "/**\n * @file actseg.h\n *\n * @brief Declarations for actor segments.\n*/\n#ifndef ACTSEG_H\n#define ACTSEG_H\n\n#include \"common.h\"\n#include <act.h>\n#include <vec.h>\n#include <mat.h>\n\n// Forward.\nstruct ASEGA;\n\n/**\n * @brief Actor segment.\n * @todo Implement the struct.\n */\nstruct ACTSEG : public ACT\n{\n    /* 0x1c */ ASEGA *pasega;\n    /* 0x20 */ DLE dleAsega;\n    // ...\n};\n\nvoid RetractActseg(ACTSEG *pactseg, GRFRA grfra);\n\nvoid CloneActseg(ACTSEG *pactseg, ACTSEG *pactsegBase);\n\nvoid GetActsegPositionGoal(ACTSEG *pactseg, float dtOffset, VECTOR *ppos, VECTOR *pv);\n\nvoid GetActsegRotationGoal(ACTSEG *pactseg, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\nvoid GetActsegTwistGoal(ACTSEG *pactseg, float *pradTwist, float *pdradTwist);\n\nvoid GetActsegScale(ACTSEG *pactseg, MATRIX3 *pmat);\n\nfloat GGetActsegPoseGoal(ACTSEG *pactseg, int ipose);\n\n#endif // ACTSEG_H\n"
  },
  {
    "path": "include/alarm.h",
    "content": "/**\n * @file alarm.h\n *\n * @brief Alarm system.\n */\n#ifndef ALARM_H\n#define ALARM_H\n\n#include \"common.h\"\n#include <break.h>\n#include <sound.h>\n#include <oid.h>\n#include <dl.h>\n#include <so.h>\n\n// Forward.\nstruct SENSOR;\n\n/**\n * @brief Alarm state.\n */\nenum ALARMS\n{\n    ALARMS_Nil = -1,\n    ALARMS_Enabled = 0,\n    ALARMS_Disabled = 1,\n    ALARMS_Triggered = 2,\n    ALARMS_Max = 3\n};\n\n/**\n * @brief Alarm trigger kind.\n */\nenum ALTK\n{\n    ALTK_Nil = -1,\n    ALTK_Trigger = 0,\n    ALTK_Untrigger = 1,\n    ALTK_Disable = 2,\n    ALTK_Max = 3\n};\n\n/**\n * @class ALARM\n * @brief Alarm object that controls some sensors.\n */\nstruct ALARM : public SO\n{\n    /* 0x550 */ ALARMS alarms; // current alarm state\n    float tAlarms;\n    SM *psm;\n    SMA *psma;\n    float dtReset;\n    /* 0x564 */ int calbrks;       // count of breakables\n    /* 0x568 */ OID aoidAlbrks[4]; // array of breakable OIDs\n    int coidSensors;\n    OID aoidSensors[16];\n    int cpsensors;\n    SENSOR *apsensors[16];\n    int coidStepguards;\n    OID aoidStepguards[6];\n    int calbrksDisabled;\n    AMB *pambSiren;\n    EXC *pexc;\n    int fSilent;\n    int crsmg;\n    RSMG arsmg[8];\n    /* 0x6b0 */ int ichkDisabled;\n};\n\n/**\n * @class ALARM_BREAKABLE\n * @brief Breakable alarm.\n */\nstruct ALBRK : public BRK\n{\n    // ...\n    /* 0x6c0 */ ALARM *palarm;\n};\n\nvoid BreakAlbrk(ALBRK *palbrk);\n\nvoid SetAlbrkAlarm(ALBRK *palbrk, ALARM *palarm);\n\nvoid InitAlarm(ALARM *palarm);\n\nvoid PostAlarmLoad(ALARM *palarm);\n\nvoid CloneAlarm(ALARM *palarm, ALARM *palarmBase);\n\nvoid UpdateAlarm(ALARM *palarm, float dt);\n\nvoid PostAlarmLoadCallbackHookup(ALARM *palarm, MSGID msgid, void *pv);\n\nvoid SetAlarmAlarms(ALARM *palarm, ALARMS alarms);\n\nvoid TriggerAlarm(ALARM *palarm, ALTK altk);\n\nvoid DisableAlarmAlbrk(ALARM *palarm);\n\nvoid EnableAlarmSensors(ALARM *palarm);\n\nvoid DisableAlarmSensors(ALARM *palarm);\n\nvoid NotifyAlarmSensorsOnTrigger(ALARM *palarm);\n\n/**\n * @brief Adds a breakable alarm object to the alarm's list.\n *\n * @param palarm Pointer to the alarm.\n * @param oid Object ID of the breakable alarm to add (max 4).\n */\nvoid AddAlarmAlbrk(ALARM *palarm, OID oid);\n\n/**\n * @brief Adds a sensor object to the alarm's sensor list.\n *\n * @param palarm Pointer to the alarm.\n * @param oid Object ID of the sensor to add (max 16).\n */\nvoid AddAlarmSensor(ALARM *palarm, OID oid);\n\n/**\n * @brief Adds a stepguard object to the alarm's stepguard list.\n *\n * @param palarm Pointer to the alarm.\n * @param oid Object ID of the stepguard to add (max 6).\n */\nvoid AddAlarmStepguard(ALARM *palarm, OID oid);\n\nvoid SetAlarmRsmg(ALARM *palarm, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal);\n\nint FGetAlarmSensorList(ALARM *palarm, void *pvstate);\n\n#endif // ALARM_H\n"
  },
  {
    "path": "include/alo.h",
    "content": "/**\n * @file alo.h\n */\n#ifndef ALO_H\n#define ALO_H\n\n#include \"common.h\"\n#include <sound.h>\n#include <vec.h>\n#include <mat.h>\n#include <lo.h>\n#include <dl.h>\n\n// Forward\nstruct CBinaryInputStream;\nstruct SFX;\nstruct SMPA;\nstruct MRG;\nstruct ASEGA;\nstruct ASEGD;\nstruct ACT;\nstruct ACTLY;\nstruct ACTSEG;\nstruct ACTADJ;\nstruct ACTBANK;\nstruct IKH;\nstruct ALOX;\nstruct SHADOW;\nstruct THROB;\nstruct POSEC;\nstruct ACTREF;\nstruct FADER;\nstruct PROXY;\nstruct RO;\nstruct CM;\nstruct SMA;\nstruct TARGET;\n\ntypedef int GRFIC;\ntypedef int GRFTAK;\ntypedef int GRFSNIP;\n\n/**\n * @todo Unknown.\n */\nenum ACK\n{\n    ACK_Nil = -1,\n    ACK_None = 0,\n    ACK_Spring = 1,\n    ACK_Velocity = 2,\n    ACK_Smooth = 3,\n    ACK_Spline = 4,\n    ACK_Drive = 5,\n    ACK_SmoothForce = 6,\n    ACK_SmoothLock = 7,\n    ACK_SpringLock = 8,\n    ACK_SmoothNoLock = 9,\n    ACK_Max = 10\n};\n\n/**\n * @brief Unknown.\n */\nenum RTCK\n{\n    RTCK_Nil = -1,\n    RTCK_None = 0,\n    RTCK_All = 1,\n    RTCK_WorldZ = 2,\n    RTCK_LocalX = 3,\n    RTCK_LocalY = 4,\n    RTCK_LocalZ = 5,\n    RTCK_Max = 6\n};\n\n/**\n * @brief Unknown.\n */\nenum THROBK\n{\n    THROBK_Nil = -1,\n    THROBK_Pipe = 0,\n    THROBK_Ninja = 1,\n    THROBK_Rail = 2,\n    THROBK_Hide = 3,\n    THROBK_Foo = 4,\n    THROBK_Bar = 5,\n    THROBK_Max = 6\n};\n\n/**\n * @brief Unknown.\n */\nstruct THROB\n{\n    /* 0x00 */ THROBK throbk;\n    /* 0x04 */ STRUCT_PADDING(11);\n    /* 0x30 */ float dtInOut;\n};\n\n/**\n * @brief Unknown.\n */\nstruct WKR\n{\n    LO *ploSource;\n    LO *ploTarget;\n    float sftMax;\n    /* 0x0c */ GRFIC grfic;\n    GRFTAK grftak;\n    float gSort;\n};\n\n/**\n * @todo Unknown.\n */\nstruct FICG\n{\n    uchar grficSweep;\n    uchar grficRush;\n    uchar grficSmash;\n    uchar grficBomb;\n    uchar grficShock;\n};\n\n/**\n * @todo Unknown.\n*/\nstruct SNIP\n{\n    /* 0x00 */ GRFSNIP grfsnip;\n    OID oid;\n    int ib;\n};\n\n/**\n * @brief Transform.\n */\nstruct XF\n{\n    MATRIX3 mat;\n    VECTOR pos;\n    MATRIX3 matWorld;\n    VECTOR posWorld;\n    VECTOR v;\n    VECTOR w;\n    VECTOR dv;\n    VECTOR dw;\n};\n\n/**\n * @class LIGHTWEIGHT\n * @brief Unknown, probably used for instancing LOs.\n *\n * @todo Finish implementing struct.\n */\nstruct ALO : public LO\n{\n    /* 0x34 */ DL dlChild;\n    DLE dleBusy;\n    /* 0x54 */ DLE dleMRD;\n    ALO *paloRoot;\n    ALO *paloFreezeRoot;\n    DLE dleFreeze;\n    /* 0x60 */ DL dlFreeze;\n    int cpmrg;\n    MRG *apmrg;\n    /* 0x80 */ float sMRD;\n    /* 0x84 */ float sCelBorderMRD;\n    /* 0x88 */ int grfzon;\n    float dsMRDSnap;\n    undefined4 unk_0x9c;\n    STRUCT_PADDING(10); // int frz[10];\n    XF xf;\n    VECTOR posOrig;\n    MATRIX3 matOrig;\n    VECTOR eulOrig;\n    /* 0x1e0 */ DL dlAct;\n    ACT *pactPos;\n    ACT *pactRot;\n    ACT *pactScale;\n    ACT **apactPost;\n    ACT *pactRestore;\n    ACTLY *pactla;\n    ACTBANK *pactbank;\n    IKH *pikh;\n    CLQ *pclqPosSpring;\n    CLQ *pclwPosDamping;\n    CLQ *pclqRotSpring;\n    CLQ *pclqRotDamping;\n    SMPA *psmpaPos;\n    SMPA *psmapaRot;\n    ALOX *palox;\n    /* 0x228 */ int cframeStatic;\n    /* 0x22c */ STRUCT_PADDING(22); // GLOBSET globset;\n    /* 0x284 */ SHADOW *pshadow;\n    /* 0x288 */ THROB *pthrob;\n    /* 0x28c */ float sFastShadowRadius;\n    /* 0x290 */ float sFastShadowDepth;\n    int fRealClock;\n    FADER *pfader;\n    float dtUpdatePause;\n    ASEGD *pasegd;\n    float sRadiusRenderSelf;\n    float sRadiusRenderAll;\n    /* 0x2ac */ SFX *psfx;\n    STRUCT_PADDING(25);\n    FICG ficg;\n    STRUCT_PADDING(1); // ???\n    int cposed;\n    POSEC *aposec;\n    ACTREF *pactrefCombo;\n    /* 0x2c4 */ DLR *pdlrFirst;\n    // ???\n    ACK ackRot;\n    // ???\n    // ...\n};\n\nint FIsZeroV(VECTOR *pv);\n\nint FIsZeroW(VECTOR *pw);\n\nint FIsZeroDv(VECTOR *pdv);\n\nint FIsZeroDw(VECTOR *pdw);\n\n/**\n * @brief Initializes an ALO.\n *\n * @param palo ALO to initialize.\n */\nvoid InitAlo(ALO *palo);\n\nvoid AddAloHierarchy(ALO *palo);\n\n/**\n * @brief Adds an ALO.\n *\n * @param palo ALO to add.\n */\nvoid OnAloAdd(ALO *palo);\n\nvoid RemoveAloHierarchy(ALO *palo);\n\n/**\n * @brief Removes an ALO.\n *\n * @param palo ALO to remove.\n */\nvoid OnAloRemove(ALO *palo);\n\nvoid UpdateAloOrig(ALO *palo);\n\nvoid SetAloParent(ALO *palo, ALO *paloParent);\n\nvoid ApplyAloProxy(ALO *palo, PROXY *pproxyApply);\n\nvoid BindAlo(ALO *palo);\n\nvoid PostAloLoad(ALO *palo);\n\nvoid PostAloLoadCallback(ALO *palo, MSGID msgid, void *pvData);\n\nvoid SnipAloObjects(ALO *palo, int csnip, SNIP *asnip);\n\nvoid UpdateAloHierarchy(ALO *palo, float dt);\n\n/**\n * @brief Updates an ALO.\n *\n * @param palo ALO to initialize\n */\nvoid UpdateAlo(ALO *palo, float dt);\n\nvoid InvalidateAloLighting(ALO *palo);\n\nvoid UpdateAloXfWorld__FP3ALO(ALO * palo);\n\nvoid UpdateAloXfWorldHierarchy(ALO *palo);\n\nvoid PresetAloAccel(ALO *palo, float dt);\n\nvoid ProjectAloTransform(ALO *palo, float dt, int fParentDirty);\n\nvoid PredictAloTransform(ALO *paloLeaf, ALO *paloBasis, float dtOffset, VECTOR *ppos, MATRIX3 *pmat, VECTOR *pv, VECTOR *pw);\n\nvoid PredictAloTransformAdjust(ALO *paloLeaf, ALO *paloBasis, float dtOffset, VECTOR *ppos, MATRIX3 *pmat, VECTOR *pv, VECTOR *pw);\n\nvoid DupAloRo(ALO *palo, RO *proOrig, RO *proDup);\n\nvoid RenderFastShadow(ALO *palo, CM *pcm, RO *pro);\n\nvoid RenderAloAll(ALO *palo, CM *pcm, RO *pro);\n\nvoid RenderAloSelf(ALO *palo, CM *pcm, RO *pro);\n\nvoid RenderAloGlobset(ALO *palo, CM *pcm, RO *pro);\n\nvoid RenderAloLine(ALO *palo, CM *pcm, VECTOR *ppos0, VECTOR *ppos1, float rWidth, float uAlpha);\n\nvoid SetAloOverrideCel(ALO *palo, RGBA *rgba);\n\nvoid UpdateAloThrob(ALO *palo, float dt);\n\nvoid SetAloBlotContext(ALO *palo, BLOT *pblot);\n\nvoid EnsureAloFader(ALO *palo);\n\n/**\n * @brief Fades in an ALO.\n *\n * @param palo ALO to fade in.\n * @param dtFade Time to fade in over.\n */\nvoid FadeAloIn(ALO *palo, float dtFade);\n\n/**\n * @brief Fades out an ALO.\n *\n * @param palo ALO to fade out.\n * @param dtFade Time to fade out over.\n */\nvoid FadeAloOut(ALO *palo, float dtFade);\n\nvoid AdjustAloRtckMat(ALO *palo, CM *pcm, RTCK rtck, VECTOR *pposCenter, MATRIX4 *pmat);\n\nvoid CloneAloHierarchy(ALO *palo, ALO *paloBase);\n\n/**\n * @brief Clones an ALO.\n *\n * @param palo ALO to clone to.\n * @param paloBase Base ALO to clone from.\n */\nvoid CloneAlo(ALO *palo, ALO *paloBase);\n\nvoid HandleAloMessage(ALO *palo, MSGID msgid, void *pv);\n\nvoid TranslateAloToPos(ALO *palo, VECTOR *ppos);\n\nvoid RotateAloToMat(ALO *palo, MATRIX3 *pmat);\n\nvoid SetAloVelocityVec(ALO *palo, VECTOR *pv);\n\nvoid SetAloVelocityXYZ(ALO *palo, float x, float y, float z);\n\nvoid SetAloAngularVelocityVec(ALO *palo, VECTOR *pw);\n\nvoid SetAloAngularVelocityXYZ(ALO *palo, float x, float y, float z);\n\nvoid SetAloVelocityLocal(ALO *palo, VECTOR *pvec);\n\nvoid GetAloVelocityLocal(ALO *palo, VECTOR *pvec);\n\nvoid MatchAloOtherObject(ALO *palo, ALO *paloOther);\n\nvoid CalculateAloMovement(ALO *paloLeaf, ALO *paloBasis, VECTOR *ppos, VECTOR *pv, VECTOR *pw, VECTOR *pdv, VECTOR *pdw);\n\nvoid CalculateAloTransform(ALO *paloLeaf, ALO *paloBasis, int cpaloPredict, VECTOR *apos, MATRIX3 *amat, VECTOR *av, VECTOR *aw);\n\nvoid CalculateAloTransformAdjust(ALO *paloLeaf, ALO *paloBasis, VECTOR *ppos, MATRIX3 *pmat, VECTOR *pv, VECTOR *pw);\n\nvoid ConvertAloPos(ALO *paloFrom, ALO *paloTo, VECTOR *pposFrom, VECTOR *pposTo);\n\nvoid ConvertAloVec(ALO *paloFrom, ALO *paloTo, VECTOR *pvecFrom, VECTOR *pvecTo);\n\nvoid ConvertAloMat(ALO *paloFrom, ALO *paloTo, MATRIX3 *pmatFrom, MATRIX3 *pmatTo);\n\nint FDrivenAlo(ALO *palo);\n\nvoid RetractAloDrive(ALO *palo);\n\nvoid ConvertAloMovement(ALO *paloFrom, ALO *paloTo, VECTOR *ppos, VECTOR *pvFrom, VECTOR *pwFrom, VECTOR *pdvFrom, VECTOR *pdwFrom, VECTOR *pvTo, VECTOR *pwTo, VECTOR *pdvTo, VECTOR *pdwTo);\n\nvoid CalculateAloDrive(ALO *palo, CLQ *pclqHoming, LM *plmHoming, float dt, float radPanCur, float *pradPanTarget, float *pradTiltTarget, float *psvTarget);\n\nint FGetAloChildrenList(ALO *palo, void *pvstate);\n\nACTSEG *PactsegNewAlo(ALO *palo);\n\n/**\n * @brief Loads an ALO from a BRX file.\n *\n * @param palo ALO to load into.\n * @param pbis Binary input stream to read from.\n */\nvoid LoadAloFromBrx(ALO *palo, CBinaryInputStream *pbis);\n\nvoid LoadAloAloxFromBrx(ALO *palo, CBinaryInputStream *pbis);\n\nvoid BindAloAlox(ALO *palo);\n\nvoid AdjustAloRotation(ALO *palo, MATRIX3 *pmat, VECTOR *pw);\n\nvoid UnadjustAloRotation(ALO *palo, MATRIX3 *pmat);\n\nvoid SetAloInitialVelocity(ALO *palo, VECTOR *pv);\n\nvoid SetAloInitialAngularVelocity(ALO *palo, VECTOR *pw);\n\nASEGD *PasegdEnsureAlo(ALO *palo);\n\nvoid SetAloFastShadowRadius(ALO *palo, float sRadius);\n\nvoid GetAloFastShadowRadius(ALO *palo, float *psRadius);\n\nvoid SetAloFastShadowDepth(ALO *palo, float sDepth);\n\nvoid GetAloFastShadowDepth(ALO *palo, float *psDepth);\n\nSHADOW *PshadowAloEnsure(ALO *palo);\n\nvoid SetAloCastShadow(ALO *palo, int fCastShadow);\n\nvoid SetAloShadowShader(ALO *palo, OID oidShdShadow);\n\nvoid SetAloShadowNearRadius(ALO *palo, float sNearRadius);\n\nvoid SetAloShadowFarRadius(ALO *palo, float sFarRadius);\n\nvoid SetAloShadowNearCast(ALO *palo, float sNearCast);\n\nvoid SetAloShadowFarCast(ALO *palo, float sFarCast);\n\nvoid SetAloShadowConeAngle(ALO *palo, float degConeAngle);\n\nvoid SetAloShadowFrustrumUp(ALO *palo, VECTOR *pvecUp);\n\nvoid SetAloDynamicShadowObject(ALO *palo, OID oidDysh);\n\nSHADOW *PshadowInferAlo(ALO *palo);\n\nvoid GetAloCastShadow(ALO *palo, int *pfCastShadow);\n\nvoid GetAloShadowShader(ALO *palo, OID *poidShdShadow);\n\nvoid GetAloShadowNearRadius(ALO *palo, float *psNearRadius);\n\nvoid GetAloShadowFarRadius(ALO *palo, float *psFarRadius);\n\nvoid GetAloShadowNearCast(ALO *palo, float *psNearCast);\n\nvoid GetAloShadowFarCast(ALO *palo, float *psFarCast);\n\nvoid GetAloShadowConeAngle(ALO *palo, float *pdegConeAngle);\n\nvoid GetAloShadowFrustrumUp(ALO *palo, VECTOR *pvecUp);\n\nvoid GetAloEuler(ALO *palo, VECTOR *peul);\n\nvoid SetAloEuler(ALO *palo, VECTOR *peul);\n\nvoid EnsureAloActRestore(ALO *palo);\n\nvoid EnsureAloActla(ALO *palo);\n\nvoid RecacheAloActList(ALO *palo);\n\nvoid InsertAloAct(ALO *palo, ACT *pact);\n\nvoid ResortAloActList(ALO *palo);\n\nASEGA *PasegaFindAlo(ALO *palo, OID oidAseg);\n\nSMA *PsmaFindAlo(ALO *palo, OID oidSm);\n\nASEGA *PasegaFindAloNearest(ALO *paloLeaf);\n\nvoid CreateAloActadj(ALO *palo, int nPriority, ACTADJ **ppactadj);\n\nint FIsAloStatic(ALO *palo);\n\nvoid ResolveAlo(ALO *palo);\n\nvoid SetAloPositionSpring(ALO *palo, float r);\n\nvoid SetAloPositionSpringDetail(ALO *palo, CLQ *pclq);\n\nvoid SetAloPositionDamping(ALO *palo, float r);\n\nvoid SetAloPositionDampingDetail(ALO *palo, CLQ *pclq);\n\nvoid SetAloRotationSpring(ALO *palo, float r);\n\nvoid SetAloRotationSpringDetail(ALO *palo, CLQ *pclq);\n\nvoid SetAloRotationDamping(ALO *palo, float r);\n\nvoid SetAloRotationDampingDetail(ALO *palo, CLQ *pclq);\n\nvoid SetAloPositionSmooth(ALO *palo, float r);\n\nvoid SetAloPositionSmoothMaxAccel(ALO *palo, float r);\n\nvoid SetAloPositionSmoothDetail(ALO *palo, SMPA *psmpa);\n\nvoid SetAloRotationSmooth(ALO *palo, float r);\n\nvoid SetAloRotationSmoothMaxAccel(ALO *palo, float r);\n\nvoid SetAloRotationSmoothDetail(ALO *palo, SMPA *psmpa);\n\nvoid SetAloDefaultAckPos(ALO *palo, ACK ack);\n\nvoid SetAloDefaultAckRot(ALO *palo, ACK ack);\n\nvoid SetAloRestorePosition(ALO *palo, int fRestore);\n\nvoid SetAloNoFreeze(ALO *palo, int fNoFreeze);\n\nvoid SetAloRestorePositionAck(ALO *palo, ACK ack);\n\nvoid SetAloRestoreRotation(ALO *palo, int fRestore);\n\nvoid SetAloRestoreRotationAck(ALO *palo, ACK ack);\n\nvoid SetAloLookAt(ALO *palo, ACK ack);\n\nvoid SetAloLookAtIgnore(ALO *palo, float sIgnore);\n\nvoid GetAloLookAtIgnore(ALO *palo, float *psIgnore);\n\nvoid SetAloLookAtPanFunction(ALO *palo, CLQ *pclq);\n\nvoid GetAloLookAtPanFunction(ALO *palo, CLQ *pclq);\n\nvoid SetAloLookAtPanLimits(ALO *palo, LM *plm);\n\nvoid GetAloLookAtPanLimits(ALO *palo, LM *plm);\n\nvoid SetAloLookAtTiltFunction(ALO *palo, CLQ *pclq);\n\nvoid GetAloLookAtTiltFunction(ALO *palo, CLQ *pclq);\n\nvoid SetAloLookAtTiltLimits(ALO *palo, LM *plm);\n\nvoid GetAloLookAtTiltLimits(ALO *palo, LM *plm);\n\nvoid SetAloLookAtEnabledPriority(ALO *palo, int nPriority);\n\nvoid GetAloLookAtEnabledPriority(ALO *palo, int *pnPriority);\n\nvoid SetAloLookAtDisabledPriority(ALO *palo, int nPriority);\n\nvoid GetAloLookAtDisabledPriority(ALO *palo, int *pnPriority);\n\nvoid SetAloRotationMatchesVelocity(ALO *palo, float uBank, float dtPredict, ACK ackRot);\n\nTARGET *PtargetEnsureAlo(ALO *palo);\n\nvoid SetAloTargetAttacks(ALO *palo, GRFTAK grftak);\n\nvoid SetAloTargetRadius(ALO *palo, float sRadiusTarget);\n\nvoid SetAloTargetHitTest(ALO *palo, int fHitTest);\n\nvoid SetAloScrollingMasterSpeeds(ALO *palo, float svu, float svv);\n\nvoid SetAloEyesClosed(ALO *palo, float uClosed);\n\nvoid EnsureAloSfx(ALO *palo);\n\nvoid SetAloSfxid(ALO *palo, SFXID sfxid);\n\nvoid SetAloSfxidSpl(ALO *palo, SFXID sfxid);\n\nvoid GetAloSfxid(ALO *palo, SFXID *psfxid);\n\nvoid SetAloSStart(ALO *palo, float sStart);\n\nvoid GetAloSStart(ALO *palo, float *psStart);\n\nvoid SetAloSFull(ALO *palo, float sFull);\n\nvoid SetAloSndRepeat(ALO *palo, LM *plm);\n\nvoid GetAloSFull(ALO *palo, float *psFull);\n\nvoid SetAloUVolume(ALO *palo, float uVol);\n\nvoid SetAloUDoppler(ALO *palo, float uDoppler);\n\nvoid GetAloUDoppler(ALO *palo, float *puDoppler);\n\nvoid SetAloUVolumeSpl(ALO *palo, float uVol);\n\nvoid GetAloUVolume(ALO *palo, float *puVol);\n\nvoid SetAloUPitch(ALO *palo, float uPitch);\n\nvoid SetAloUPitchSpl(ALO *palo, float uPitch);\n\nvoid GetAloUPitch(ALO *palo, float *puPitch);\n\nvoid GetAloSndRepeat(ALO *palo, LM *plmRepeat);\n\nvoid StartAloSound(ALO *palo, SFXID sfxid, float sStart, float sFull, float uVol, LM *plmRepeat);\n\nvoid StopAloSound(ALO *palo);\n\nvoid EnsureAloThrob(ALO *palo);\n\nvoid SetAloThrobKind(ALO *palo, THROBK throbk);\n\nvoid GetAloThrobKind(ALO *palo, THROBK *pthrobk);\n\nvoid SetAloThrobInColor(ALO *palo, VECTOR *phsvInColor);\n\nvoid GetAloThrobInColor(ALO *palo, VECTOR *phsvInColor);\n\nvoid SetAloThrobOutColor(ALO *palo, VECTOR *phsvOutColor);\n\nvoid GetAloThrobOutColor(ALO *palo, VECTOR *phsvOutColor);\n\nvoid SetAloThrobDtInOut(ALO *palo, float dtInOut);\n\nvoid GetAloThrobDtInOut(ALO *palo, float *pdtInOut);\n\nvoid SetAloInteractCane(ALO *palo, GRFIC grfic);\n\nvoid GetAloInteractCane(ALO *palo, GRFIC *pgrfic);\n\nvoid SetAloInteractCaneSweep(ALO *palo, GRFIC grfic);\n\nvoid GetAloInteractCaneSweep(ALO *palo, GRFIC *pgrfic);\n\nvoid SetAloInteractCaneRush(ALO *palo, GRFIC grfic);\n\nvoid GetAloInteractCaneRush(ALO *palo, GRFIC *pgrfic);\n\nvoid SetAloInteractCaneSmash(ALO *palo, GRFIC grfic);\n\nvoid GetAloInteractCaneSmash(ALO *palo, GRFIC *pgrfic);\n\nvoid SetAloInteractBomb(ALO *palo, GRFIC grfic);\n\nvoid GetAloInteractBomb(ALO *palo, GRFIC *pgrfic);\n\nvoid SetAloInteractShock(ALO *palo, GRFIC grfic);\n\nvoid GetAloInteractShock(ALO *palo, GRFIC *pgrfic);\n\nint FAbsorbAloWkr(ALO *palo, WKR *pwkr);\n\nvoid SetAloPoseCombo(ALO *palo, OID oidCombo);\n\nvoid SetAloForceCameraFade(ALO *palo, int fFade);\n\nvoid SetAloRealClock(ALO *palo, int fRealClock);\n\n#endif // ALO_H\n"
  },
  {
    "path": "include/aseg.h",
    "content": "/**\n * @file aseg.h\n */\n#ifndef ASEG_H\n#define ASEG_H\n\n#include \"common.h\"\n#include <waypoint.h>\n#include <util.h>\n#include <sm.h>\n\n// Forward.\nstruct OVR;\nstruct CHN;\nstruct ASEGA;\n\n/**\n * @brief Unknown.\n */\nenum IAK\n{\n    IAK_Nil = -1,\n    IAK_Time = 0,\n    IAK_Proportion = 1,\n    IAK_Nearest = 2,\n    IAK_Max = 3\n};\n\n/**\n * @brief Unknown.\n */\nenum SEEK\n{\n    SEEK_Nil = -1,\n    SEEK_Start = 0,\n    SEEK_Current = 1,\n    SEEK_End = 2,\n    SEEK_EndDoEvents = 3,\n    SEEK_Max = 4\n};\n\n/**\n * @brief Unknown.\n */\nstruct CHN\n{\n    // ...\n};\n\n/**\n * @class ANIMATION_SEGMENT\n * @brief Object representing an animation segment.\n */\nstruct ASEG : public LO\n{\n    /* 0x34 */ STRUCT_PADDING(14);\n    /* 0x6c */ DL dlAsega;\n    /* 0x78 */ STRUCT_PADDING(2);\n    /* 0x80 */ CLQ clqMasterSuck;\n    /* 0x90 */ LM lmMasterSuck;\n    /* 0x98 */ float svtMasterSuck;\n    /* 0x9c */ CHN *pchnStrip;\n};\n\n/**\n * @brief Animation segment something(?).\n */\nstruct ASEGD\n{\n    /* 0x00 */ ASEG *paseg;\n    /* 0x04 */ OID oidAseg;\n    /* 0x08 */ IAK iak;\n    /* 0x0c */ float tLocal;\n    /* 0x10 */ float svtLocal;\n};\n\n/**\n * @class ASEGBL\n * @brief Animation segment blend(?).\n */\nstruct ASEGBL : public ASEG\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct EA\n{\n    float tLocal;\n};\n\n/**\n * @brief Supposed to start the ASEG system, but it doesn't do anything.\n */\nvoid StartupAseg();\n\nvoid InitAseg(ASEG *paseg);\n\nvoid LoadAsegFromBrx(ASEG *paseg, CBinaryInputStream *pbis);\n\nvoid LoadAsegEventsFromBrx(ASEG *paseg, CBinaryInputStream *pbis, int fFrame, int *pcea, EA **paea);\n\nvoid CloneAseg(ASEG *paseg, LO *ploBase);\n\nvoid PostAsegLoad(ASEG *paseg);\n\nvoid PostAsegLoadCallback(ASEG *paseg, MSGID msgid, void *pvData);\n\nvoid ApplyAsegOvr(ASEG *paseg, ALO *paloAsegRoot, int covr, OVR *aovr, float tLocal, float svtLocal, GRFAPL grfapl, ASEGA **ppasega);\n\nvoid ApplyAseg(ASEG *paseg, ALO *paloAsegRoot, float tLocal, float svtLocal, GRFAPL grfapl, ASEGA **ppasega);\n\nASEGA *PasegaApplyAseg(ASEG *paseg, ALO *paloAsegRoot, float tLocal, float svtLocal, GRFAPL grfapl);\n\nASEGA *PasegaFindAseg(ASEG *paseg, ALO *paloRoot);\n\nvoid EnsureAseg(ASEG *paseg, ALO *paloRoot, SEEK seek, float t, float svt, GRFAPL grfapl, ASEGA **ppasega);\n\nASEGA *PasegaEnsureAseg(ASEG *paseg, ALO *paloRoot, SEEK seek, float t, float svt, GRFAPL grfapl);\n\nvoid ApplyAsegCur(ASEG *paseg, ALO *paloRoot, float t, float svt, GRFAPL grfapl, ASEGA **ppasega);\n\nint FWipingAseg(ASEG *paseg);\n\nvoid FindAsegClosestPoint(ASEG *paseg, ALO *palo, VECTOR *ppos, float t, float *ptClosest, VECTOR *pposClosest, VECTOR *pvClosest);\n\nEA *PeaFindAsegLabel(ASEG *paseg, OID oidLabel);\n\nfloat TFindAsegLabel(ASEG *paseg, OID oidLabel);\n\nCHN *PchnFindAseg(ASEG *paseg, ALO *palo);\n\nvoid PredictAsegEffect(ASEG *paseg, float t, float svt, ALO *paloLeaf, ALO *paloBasis, int cpaloPredict, VECTOR *apos, MATRIX3 *amat, VECTOR *av, VECTOR *aw);\n\nvoid GetAsegWaypoints(ASEG *paseg, ALO *paloContext, int *pcpwaypoint, WAYPOINT ***papwaypoint);\n\nvoid StripAsegChn(ASEG *paseg, CHN *pchn);\n\nvoid StripAsegAlo(ASEG *paseg, ALO *palo);\n\n/**\n * @brief Does nothing.\n */\nvoid LoadAsegblFromBrx(ASEGBL *pasegbl, CBinaryInputStream *pbis);\n\n/**\n * @brief Does nothing.\n */\nvoid PostAsegblLoad(ASEGBL *pasegbl);\n\n/**\n * @brief Does nothing.\n */\nvoid CloneAsegbl(ASEGBL *pasegbl, LO *ploBase);\n\n#endif // ASEG_H\n"
  },
  {
    "path": "include/asega.h",
    "content": "/**\n * @file asega.h\n */\n#ifndef ASEGA_H\n#define ASEGA_H\n\n#include \"common.h\"\n#include <basic.h>\n#include <dl.h>\n\n// Forward.\nstruct ACTSEG;\n\n/**\n * @class ANIMATION_SEGMENT_APPLICATION\n * @brief Unknown.\n */\nstruct ASEGA : public BASIC\n{\n    /* 0x08 */ STRUCT_PADDING(7);\n    /* 0x24 */ char fHandsOff;\n    /* 0x25 */ undefined1 unk1;\n    /* 0x26 */ undefined1 unk2;\n    /* 0x27 */ undefined1 unk3;\n    /* 0x28 */ ACTSEG *pactsegError;\n    /* 0x2c */ STRUCT_PADDING(6);\n    /* 0x44 */ DL dlActseg;\n    // ...\n};\n\n// ...\n\nvoid RetractAsega(ASEGA *pasega);\n\n#endif // ASEGA_H\n"
  },
  {
    "path": "include/barrier.h",
    "content": "/**\n * @file barrier.h\n */\n#ifndef BARRIER_H\n#define BARRIER_H\n\n#include \"common.h\"\n#include <so.h>\n\n// Forward.\nstruct XP;\n\n/**\n * @brief Barrier.\n * @todo Implement the struct.\n */\nstruct BARRIER : public SO\n{\n    // ...\n    /* 0x554 */ int coid;\n    /* 0x558 */ OID aoid[4];\n    /* 0x568 */ int ccid;\n    /* 0x56c */ CID acid[4];\n    // ...\n};\n\nvoid InitBarrier(BARRIER *pbarrier);\n\nvoid CloneBarrier(BARRIER *pbarrier, BARRIER *pbarrierBase);\n\nvoid PostBarrierLoad(BARRIER *pbarrier);\n\nvoid UpdateBarrier(BARRIER *pbarrier, float dt);\n\nint FIgnoreBarrierIntersection(BARRIER *pbarrier, SO *psoOther);\n\nvoid NotifyBarrierImpact(BARRIER *pbarrier, XP *pxp, int ixpd);\n\nvoid AddBarrierObject(BARRIER *pbarrier, OID oid);\n\nvoid AddBarrierClass(BARRIER *pbarrier, CID cid);\n\n#endif // BARRIER_H\n"
  },
  {
    "path": "include/bas.h",
    "content": "/**\n * @file bas.h\n *\n * @brief Binary Async Stream.\n*/\n#ifndef BAS_H\n#define BAS_H\n\n#include \"common.h\"\n#include <util.h>\n#include <cat.h>\n\n/**\n * @brief Binary Async Stream Kind.\n*/\nenum BASK\n{\n    BASK_Nil = -1,\n    BASK_Host = 0,\n    BASK_Cd = 1,\n    BASK_Max = 2\n};\n\n/**\n * @brief Binary Async Stream.\n */\nclass CBinaryAsyncStream\n{\npublic:\n    BASK m_bask;\n    int m_fd;\n    uint m_isector;\n    int m_cbSpooling;\n    byte *m_pbSpooling;\n    byte *m_abSpool;\n    int m_cb;\n    byte *m_pb;\n    int m_ibCur;\n    int m_cbUnspooled;\n    int m_cbFile;\n\n    /**\n     * @brief Constructs a new CBinaryAsyncStream.\n     *\n     * @param pvSpool Pointer to the spool.\n     */\n    CBinaryAsyncStream(void *pvSpool);\n\n    /**\n     * @brief Destroys the CBinaryAsyncStream.\n     */\n    ~CBinaryAsyncStream();\n\n    /**\n     * @brief Opens the file at the given location.\n     *\n     * First checks if the file is open and the CD is available.\n     *\n     * @param pfl Pointer to the file location.\n     *\n     * @retval false File is not open.\n     * @retval true File is open.\n     */\n    bool FOpenFile(CFileLocation *pfl);\n\n    /**\n     * @brief Opens the sector at the given location.\n     *\n     * @param isector Sector to open.\n     * @param cb Number of bytes to read.\n     *\n     * @retval false Sector is not open.\n     * @retval true Sector is open.\n     */\n    bool FOpenSector(uint isector, uint cb);\n\n    /**\n     * @brief Closes the stream.\n     */\n    void Close();\n\n    /**\n     * @brief Start spooling.\n     */\n    void StartSpooling();\n\n    /**\n     * @brief TODO.\n     */\n    bool FSpooling();\n\n    /**\n     * @brief Check if spooling is complete.\n     */\n    bool FSpoolingComplete();\n\n    /**\n     * @brief Finish spooling.\n     */\n    void FinishSpooling();\n\n    /**\n     * @brief TODO.\n     */\n    void Spool();\n\n    /**\n     * @brief Skip bytes.\n\t *\n\t * @param cb Number of bytes to skip.\n     */\n    void Skip(int cb);\n};\n\n#endif // BAS_H\n"
  },
  {
    "path": "include/basic.h",
    "content": "/**\n * @file basic.h\n *\n * @brief Basic object.\n */\n#ifndef BASIC_H\n#define BASIC_H\n\n#include \"common.h\"\n#include <splice/sidebag.h>\n\n/**\n * @class BASIC\n * @brief Base object for most other kinds of objects.\n */\nstruct BASIC\n{\n    union\n    {\n        /* 0x00 */ VTBASIC *pvtbasic;\n        /* 0x00 */ VTLO *pvtlo;\n    };\n    /* 0x04 */ CSidebag *psidebag;\n};\n\n/**\n * @brief Check if the basic object is derived from the given class ID.\n *\n * @param pbasic The object.\n * @param cid The class ID to check.\n *\n * @retval 1 if the object is derived from the class.\n * @retval 0 if the object is not derived from the class.\n */\nint FIsBasicDerivedFrom(BASIC *pbasic, CID cid);\n\n/**\n * @brief Check if the basic has a sidebag, and if not, create one.\n *\n * @param pbasic The object.\n */\nvoid EnsureBasicSidebag(BASIC *pbasic);\n\n/**\n * @brief Get the basic object's CID.\n *\n * @param pbasic The object.\n * @param pcid Return CID.\n */\nvoid GetBasicCid(BASIC *pbasic, CID *pcid);\n\n#endif // BASIC_H\n"
  },
  {
    "path": "include/bbmark.h",
    "content": "/**\n * @file bbmark.h\n */\n#ifndef BBMARK_H\n#define BBMARK_H\n\n#include \"common.h\"\n\ntypedef int GRFPVA;\n\n// Forward.\nstruct SW;\nstruct SO;\n\n// TODO: Implement structs.\nstruct XP;\nstruct OXA;\nstruct OXF;\n\n/**\n * @brief Unknown.\n */\nstruct OX\n{\n    XP *pxp;\n    OX *poxNext;\n    OX *poxOther;\n    SO *psoOther;\n};\n\n/**\n * @brief Unknown.\n */\nstruct OXA\n{\n    OX *pox;\n    SO *pso;\n    OXA *poxaNext;\n    OXA *poxaPrev;\n};\n\nvoid UpdateSwPox(SW *psw, OXA *poxa0, OXA *poxa1, OXF oxfAdd, OXF oxfRemove);\n\nOX *PoxAddSw(SW *psw, OXA *poxa, OXA *poxaOther);\n\nOX *PoxRemoveSw(SW *psw, OXA *poxa, OXA *poxaOther);\n\nOX *PoxFromSoSo(SO *pso, SO *psoOther);\n\nXP *PxpFirstFromSoSo(SO *pso, SO *psoOther);\n\nvoid AddSwAaobrObject(SW *psw, SO *pso);\n\nvoid RemoveSwAaobrObject(SW *psw, SO *pso);\n\nvoid InvalidateSwAaox(SW *psw);\n\nvoid UpdateSwAaox(SW *psw);\n\nvoid InvalidateSwXpForObject(SW *psw, SO *pso, GRFPVA grfpvaInvalid);\n\nvoid RecalcSwXpAll(SW *psw, int fCenterXp);\n\nvoid RecalcSwOxfFilterForObject(SW *psw, SO *pso);\n\n#endif // BBMARK_H\n"
  },
  {
    "path": "include/bez.h",
    "content": "/**\n * @file bez.h\n *\n * @brief Bezier curves.\n *\n * @todo Add function parameters and documentation.\n */\n#ifndef BEZ_H\n#define BEZ_H\n\n#include \"common.h\"\n#include <vec.h>\n#include <mat.h>\n\nvoid EvaluateBezierWeightedFloat(float, float, float, float, float, float, float, float, float, float *, float *, float *);\nvoid EvaluateBezierFloat(float, float, float, float, float, float, float, float *, float *, float *);\nvoid EvaluateBezierPos(float, float, float, VECTOR *, VECTOR *, VECTOR *, VECTOR *, VECTOR *, VECTOR *, VECTOR *);\nvoid EvaluateBezierMat(float, float, float, MATRIX3 *, VECTOR *, MATRIX3 *, VECTOR *, MATRIX3 *, VECTOR *, VECTOR *);\nvoid TesselateBezier(float, float, float, VECTOR *, VECTOR *, VECTOR *, VECTOR *, int, VECTOR *);\nfloat SBezierPosLength(float, float, VECTOR *, VECTOR *, VECTOR *, VECTOR *);\n\nvoid LimitBezierMulti(int c, ...);\n\n#endif // BEZ_H\n"
  },
  {
    "path": "include/binoc.h",
    "content": "/**\n * @file binoc.h\n *\n * @brief Binoc-u-com.\n */\n#ifndef BINOC_H\n#define BINOC_H\n\n#include \"common.h\"\n#include <screen.h>\n#include <util.h>\n\nstruct ALO;\n\n/**\n * @brief Binocular Edge Info (?)\n * \n * @note Used for binocular outline rendering\n */\nstruct BEI\n{\n    /* 0x00 */ CLQ clq;             // Quadratic curve parameters\n    /* 0x10 */ float cseg;          // Total number of segments\n    /* 0x14 */ float csegNotchHalf; // Half the number of segments in the notch\n    /* 0x18 */ int isegNotchFirst;  // First segment index of the notch\n    /* 0x1c */ int isegNotchMid;    // Middle segment index of the notch\n    /* 0x20 */ int isegNotchLast;   // Last segment index of the notch\n    /* 0x24 */ float gNotchEdge;    // Y value at the notch edges\n    /* 0x28 */ float gNotchCenter;  // Y value at the notch center\n};\n\nstruct BINOC : public BLOT\n{\n    STRUCT_PADDING(36);\n    float unk0;\n    undefined4 unk1; // RGBA color value?\n    undefined4 unk2;\n    ALO *paloLookat;\n    float zoom;\n    float dxReticle;\n    float dyReticle;\n    undefined4 unk3;\n    undefined4 unk4;\n    float uCompassBarOffset;\n};\n\n/**\n * @brief Initializes a BEI struct for binocular outline rendering.\n *\n * @details Sets up the quadratic curve parameters and calculates segment indices for the\n *          notch region in the binocular outline. The notch is positioned at the midpoint\n *          of the curve for UI elements like the compass.\n *\n * @param pbei Pointer to the BEI struct to initialize.\n * @param pclq Pointer to the quadratic curve (CLQ) defining the outline shape.\n * @param duWidth Width of the notch.\n * @param dgHeight Vertical offset for the notch center.\n * @param cseg Total number of segments to divide the curve into.\n */\nvoid InitBei(BEI *pbei, CLQ *pclq, float duWidth, float dgHeight, int cseg);\n\n/**\n * @brief Evaluates the binocular edge curve at a given segment.\n *\n * @details Returns the Y-coordinate for the outline at segment index iseg. For segments\n *          outside the notch region, evaluates the quadratic curve directly. Within the\n *          notch, performs linear interpolation between edge and center values to create\n *          a V shaped cutout.\n *\n * @param pbei Pointer to the BEI struct containing curve and notch parameters.\n * @param iseg Segment index along the outline.\n * @return Y-coordinate value for the outline at this segment.\n */\nfloat GEvaluateBei(BEI *pbei, int iseg);\n\n/**\n * @brief Checks if the binocular text reveal animation is complete.\n *\n * @param pbinoc Pointer to BINOC instance.\n * @return true if the text animation is complete, false otherwise.\n */\nbool FDoneBinocAchz(BINOC *pbinoc);\n\nvoid SetBinocLookat(BINOC *binoc, ALO *paloLookat);\n\n/**\n * @brief Horizontal text justification.\n */\ntypedef enum JH\n{\n    JH_Nil = -1,\n    JH_Left = 0,\n    JH_Center = 1,\n    JH_Right = 2,\n    JH_Max = 3\n} JH;\n\n/**\n * @brief Vertical text justification.\n */\ntypedef enum JV\n{\n    JV_Nil = -1,\n    JV_Top = 0,\n    JV_Center = 1,\n    JV_Bottom = 2,\n    JV_Max = 3\n} JV;\n\nclass CTextBox\n{\npublic:\n    /**\n     * @brief Sets the position of the text box.\n     *\n     * @param x X position.\n     * @param y Y position.\n     */\n    void SetPos(float x, float y);\n\n    /**\n     * @brief Sets the size of the text box.\n     *\n     * @param dx Width.\n     * @param dy Height.\n     */\n    void SetSize(float dx, float dy);\n\n    /**\n     * @brief Sets the text color.\n     *\n     * @param rgba RGBA color value.\n     */\n    void SetTextColor(RGBA *rgba);\n\n    /**\n     * @brief Sets the horizontal text justification.\n     *\n     * @param jh Horizontal text justification.\n     */\n    void SetHorizontalJust(JH jh);\n\n    /**\n     * @brief Sets the vertical text justification.\n     *\n     * @param jv Vertical text justification.\n     */\n    void SetVerticalJust(JV jv);\n\nprivate:\n    float m_x;    // X position.\n    float m_y;    // Y position.\n    float m_dx;   // Width.\n    float m_dy;   // Height.\n    RGBA m_rgba;  // Text color.\n    enum JH m_jh; // Horizontal text justification.\n    enum JV m_jv; // Vertical text justification;\n};\n\n#endif /* BINOC_H */\n"
  },
  {
    "path": "include/bis.h",
    "content": "/**\n * @file bis.h\n *\n * @brief Binary Input Stream.\n */\n#ifndef BIS_H\n#define BIS_H\n\n#include \"common.h\"\n#include <prog.h>\n#include <clock.h>\n#include <vec.h>\n#include <mat.h>\n#include <geom.h>\n#include <cat.h>\n#include <bsp.h>\n\n/**\n * @brief Binary Input Stream Kind.\n *\n * Types of binary stream that can be opened.\n */\nenum BISK\n{\n    BISK_Nil = -1,\n    BISK_Host = 0,\n    BISK_Cd = 1,\n    BISK_Mem = 2,\n    BISK_Max = 3\n};\n/**\n * @brief Binary Input Stream Flags numeric type.\n *\n * Flags for the binary input stream.\n */\ntypedef int GRFBIS;\n\n/**\n * @brief Binary Input Stream\n *\n * Used to read binary data from files on the disc.\n */\nclass CBinaryInputStream\n{\npublic:\n    int m_grfbis;\n    BISK m_bisk;\n    byte *m_abSpool;\n    int m_cbSpool;\n    int m_cbFile;\n    int m_cbRemaining; /* File Stream Remaining Bytes. */\n    byte *m_pb;        /* File Stream Position */\n    int m_cb;          /* File Stream Size */\n    byte *m_pbRaw;\n    int m_cbRaw;\n    int m_grfDecomp;\n    int m_cbSpillOver;\n    CProg *m_pprog;\n    TICK m_tickWait;\n    int m_fd;\n    int m_cbAsyncComplete;\n    int m_cbAsyncRequest;\n    int m_cbAsyncRemaining;\n    int m_cbPartialRead;\n    uint m_isector; /* Sector Offset in ISO */\n    int m_cbuf;\n    int m_cbufFill;\n    int m_ibufMic;\n    int m_ibufMac;\n\n    /**\n     * @brief Constructs a new CBinaryInputStream.\n     *\n     * @param pvSpool Pointer to data.\n     * @param cbSpool Size of data in bytes.\n     * @param grfbis  Flags.\n     *\n     * @todo Implement this constructor.\n     */\n    CBinaryInputStream(void *pvSpool, int cbSpool, GRFBIS grfbis);\n\n    /**\n     * @brief Destroys the CBinaryInputStream.\n     */\n    ~CBinaryInputStream();\n\n    /**\n     * @brief Opens the sector at the given location.\n     *\n     * @param isector Sector to open.\n     * @param cb Number of bytes to read.\n     *\n     * @retval 0 Sector is not open.\n     * @retval 1 Sector is open.\n     */\n    int FOpenSector(uint isector, uint cb);\n\n    /**\n     * @brief Opens a certain number of bytes in memory.\n     *\n     * @param cb Number of bytes to open.\n     * @param pv Pointer to the memory location.\n     */\n    void OpenMemory(int cb, void *pv);\n\n    /**\n     * @brief Opens the file at the given location.\n     *\n     * First checks if the file is open and the CD is available.\n     *\n     * @param pfl Pointer to the file location.\n     *\n     * @retval 0 File is not open.\n     * @retval 1 File is open.\n     */\n    int FOpenFile(CFileLocation *pfl);\n\n    /**\n     * @brief Closes the stream.\n     */\n    void Close();\n\n    /**\n     * @brief Decrements the number of async bytes remaining.\n     *\n     * @param cb Number of bytes to decrement.\n     */\n    void DecrementCdReadLimit(int cb);\n\n    /**\n     * @brief Pumps data from the CD.\n     */\n    void PumpCd();\n\n    /**\n     * @brief Pumps data from the host pc.\n     */\n    void PumpHost();\n\n    /**\n     * @brief Pumps data from either the host or the CD.\n     */\n    void Pump();\n\n    /**\n     * @brief TBD.\n     */\n    void Decompress();\n\n    /**\n     * @brief Reads a certain number of bytes from the stream.\n     *\n     * Will read a certain number of bytes from the stream and store them at the\n     * given location.\n     *\n     * @param cb Number of bytes to read.\n     * @param pv Pointer to the memory location.\n     */\n    void Read(int cb, void *pv);\n\n    /**\n     * @brief Aligns the stream to a certain number of bytes.\n     *\n     * @param n Number of bytes to align to.\n     */\n    void Align(int n);\n\n    /**\n     * @brief Reads a 8-bit unsigned integer from the stream.\n     *\n     * @return The byte read.\n     */\n    uchar U8Read();\n\n    /**\n     * @brief Reads a 16-bit unsigned integer from the stream.\n     *\n     * @return The 16-bit unsigned integer read\n     */\n    ushort U16Read();\n\n    /**\n     * @brief Reads a 32-bit unsigned integer from the stream.\n     *\n     * @return The 32-bit unsigned integer read\n     */\n    uint U32Read();\n\n    /**\n     * @brief Reads a 8-bit signed integer from the stream.\n     *\n     * @return The 8-bit signed integer read\n     */\n    char S8Read();\n\n    /**\n     * @brief Reads a 16-bit signed integer from the stream.\n     *\n     * @return The 16-bit signed integer read\n     */\n    short S16Read();\n\n    /**\n     * @brief Reads a 32-bit signed integer from the stream.\n     *\n     * @return The 32-bit signed integer read\n     */\n    int S32Read();\n\n    /**\n     * @brief Reads a 32-bit floating point number from the stream.\n     *\n     * @return The 32-bit floating point number read\n     */\n    float F32Read();\n\n    /**\n     * @brief Reads a vector from the stream.\n     *\n     * @param pv Pointer to the vector to store the data.\n     */\n    void ReadVector(VECTOR *pvec);\n\n    /**\n     * @brief Reads a 4D vector from the stream.\n     *\n     * @param pv Pointer to the vector to store the data.\n     */\n    void ReadVector4(VECTOR4 *pvec);\n\n    /**\n     * @brief Reads a matrix from the stream.\n     *\n     * @param pmat Pointer to the matrix to store the data.\n     */\n    void ReadMatrix(MATRIX3 *pmat);\n\n    /**\n     * @brief Reads a 4x4 matrix from the stream.\n     *\n     * @param pmat Pointer to the matrix to store the data.\n     */\n    void ReadMatrix4(MATRIX4 *pmat);\n\n    /**\n     * @brief Reads geometry data from the stream.\n     *\n     * @param pgeom Pointer to the geometry data structure to store the data.\n     * @param pbspb Pointer to a BSP tree (?).\n     */\n    void ReadGeom(GEOM *pgeom, BSPC *pbspc);\n\n    /**\n     * @brief Reads the given number of VBSPs from the stream.\n     *\n     * @param pcvbsp Pointer to an integer that will store the number of VBSP entries read.\n     * @param apvbsp Pointer to the array of VBSP data structures to store the data.\n     */\n    void ReadVbsp(int *pcvbsp, VBSP **apvbsp);\n\n    /**\n     * @brief Reads a string from the stream.\n     *\n     * @param pachz Pointer where the string will be stored.\n     */\n    void ReadStringSw(char **pachz);\n\n    /**\n     * @brief Reads a short from the stream and then skips the number of bytes it represents.\n     */\n    void Unknown1();\n\n    /**\n     * @brief Reads 32 bytes of data from the stream then it checks\n     * two values and either copies the data or gives back a nullptr.\n     *\n     * @param ppv Pointer to the destination.\n     */\n    void Unknown2(void **ppv);\n};\n\n#endif // BIS_H\n"
  },
  {
    "path": "include/blend.h",
    "content": "/**\n * @file blend.h\n */\n#ifndef BLEND_H\n#define BLEND_H\n\n#include \"common.h\"\n#include <alo.h>\n#include <oid.h>\n\n// Forward.\nstruct ASEGBL;\nstruct EA;\n\n/**\n * @brief Unknown.\n */\nstruct MRSG\n{\n    float t;\n    float dt;\n};\n\nvoid VerifyAeaEquivalence(int cea0, EA *aea0, int cea1, EA *aea1);\n\nvoid EnsureAsegBlendDynamic(ALO *palo, int cbBl, int cbl, void *abl, int cmrsgc, int *mpimrsgcib, int *mpimrsgccmrsg, ASEGBL **ppasegbl);\n\nvoid FillBlAmrsg(int cbBl, int cbl, void *abl, int ibMrsg, int coid, OID *aoid);\n\nvoid CalculateBlendAmrsg(int cbBl, int cbl, void *abl, int ibMrsg, int cmrsg, MRSG *amrsg, float *ptMax);\n\nint ImrsgLookUp(float t, float tMax, int cmrsg, MRSG *amrsg, float *pdtBest);\n\nvoid ReblendAsegbl(ASEGBL *pasegbl, int cbBl, int cbl, void *abl);\n\nvoid SetAsegblSlerp(ASEGBL *pasegbl, ALO *palo);\n\n#endif // BLEND_H\n"
  },
  {
    "path": "include/blip.h",
    "content": "/**\n * @file blip.h\n */\n#ifndef BLIP_H\n#define BLIP_H\n\n#include \"common.h\"\n#include <flash.h>\n#include <mat.h>\n#include <vec.h>\n#include <oid.h>\n#include <shd.h>\n#include <sw.h>\n#include <cm.h>\n\n// Forward.\nstruct EMITB;\nstruct RPL;\n\ntypedef int GRFZON;\n\n/**\n * @todo Move elsewhere?\n */\nstruct VU_FLOAT\n{\n    uint16_t data;\n};\n\n/**\n * @brief Unknown.\n */\nenum BLIPOK\n{\n    BLIPOK_Nil = -1,\n    BLIPOK_Fixed = 0,\n    BLIPOK_Flying = 1,\n    BLIPOK_Rolling = 2,\n    BLIPOK_Max = 3\n};\n\n/**\n * @brief Unknown.\n */\nstruct BLIP\n{\n    // ...\n};\n\n/**\n * @class BLIPG\n * @brief Unknown.\n */\nstruct BLIPG\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct BLIPP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct BLIPV\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct BLIPX\n{\n    // ...\n};\n\nvoid BuildBlipAqwGifs(int alpha_b, QW **paqw);\n\nvoid StartupBlips();\n\nBLIP *PblipNew(BLIPG *pblipg);\n\nvoid RemoveBlip(BLIP *pblip);\n\nBLIPG *PblipgNew(SW *psw);\n\nvoid InitBlipg(BLIPG *pblipg);\n\nvoid OnBlipgAdd(BLIPG *pblipg);\n\nvoid OnBlipgRemove(BLIPG *pblipg);\n\nvoid SetBlipgShader(BLIPG *pblipg, OID oid);\n\nvoid PropagateBlipgShader(BLIPG *pblipg);\n\nvoid SetBlipgEmitb(BLIPG *pblipg, EMITB *pemitb);\n\nvoid UpdateBlipg(BLIPG *pblipg, float dt);\n\nvoid SubscribeBlipgObject(BLIPG *pblipg, LO *ploTarget);\n\nint CblipeProjectBlipTransformAccel(MATRIX4 *pmat4Dv, VU_FLOAT dt, BLIPP *ablipp, BLIPV *ablipv, BLIPX *ablipx, int cblipe, BLIPOK blipok, VECTOR *pposMin, VECTOR *pposMax);\n\nvoid ProjectBlipgTransformAccel(BLIPG *pblipg, float dt);\n\nvoid ProjectBlipgTransform(BLIPG *pblipg, float dt, int fForce);\n\nvoid RenderBlipgSelf(BLIPG *pblipg, CM *pcm, RO *pro);\n\nvoid DrawBlipg(RPL *prpl);\n\nvoid PropagateBlipgShaders(GRFZON grfzon);\n\n#endif // BLIP_H\n"
  },
  {
    "path": "include/bomb.h",
    "content": "/**\n * @file bomb.h\n */\n#ifndef BOMB_H\n#define BOMB_H\n\n#include \"common.h\"\n#include <difficulty.h>\n#include <sound.h>\n#include <so.h>\n#include <po.h>\n#include <mq.h>\n\n// Forward.\nstruct WKR;\n\n/**\n * @class BOMB\n * @brief Bomb (?).\n * @todo Implement the struct.\n */\nstruct BOMB : public SO\n{\n    // ...\n    /* 0x554 */ float tDetonate;\n    // ...\n    /* 0x680 */ SFX *psfxDet;\n    // ...\n};\n\nvoid InitBomb(BOMB *pbomb);\n\nvoid LoadBombFromBrx(BOMB *pbomb, CBinaryInputStream *pbis);\n\nvoid CloneBomb(BOMB *pbomb, BOMB *pbombBase);\n\nvoid PostBombLoad(BOMB *pbomb);\n\nvoid HandleBombMessage(BOMB *pbomb, MSGID msgid, void *pv);\n\nvoid UpdateBomb(BOMB *pbomb, float dt);\n\nint FAbsorbBombWkr(BOMB *pbomb, WKR *pwkr);\n\nvoid PrimeBomb(BOMB *pbomb, float dt);\n\nvoid ApplyBombThrow(BOMB *pbomb, PO *ppo);\n\nvoid DetonateBomb(BOMB *pbomb);\n\nSFX *PsfxEnsureBomb(BOMB *pbomb, ENSK ensk);\n\n#endif // BOMB_H\n"
  },
  {
    "path": "include/bq.h",
    "content": "/**\n * @file bq.h\n *\n * @brief Byte queue.\n*/\n#ifndef BQ_H\n#define BQ_H\n\n#include \"common.h\"\n\n/**\n * @brief TODO.\n */\nclass CQueueInput\n{\npublic:\n    virtual int CbRead(int cb, void *pv);\n};\n\n/**\n * @brief TODO.\n */\nclass CQueueOutput\n{\n    // ...\n};\n\n/**\n * @brief TODO.\n */\nclass CQueueInputMemory : public CQueueInput\n{\npublic:\n    int CbRead(int cb, void *pv);\n};\n\n/**\n * @brief TODO.\n */\nclass CQueueInputFile : public CQueueInput\n{\npublic:\n    int CbRead(int cb, void *pv);\n};\n\n/**\n * @brief Byte Queue.\n*/\nclass CByteQueue\n{\npublic:\n    byte *m_ab;\n    int m_cb;\n    int m_ibFree;\n    int m_ibAlloc;\n    int m_cbFree;\n    int m_cbAlloc;\n    int m_cbDrain;\n    int m_cbTotal;\n\n    /**\n     * @brief Initialize the byte queue.\n     *\n     * @param cb Number of bytes.\n     * @param pv Pointer to the data.\n     */\n    void Init(int cb, void *pv);\n\n    /**\n     * @brief Reset the byte queue.\n     */\n    void Reset();\n\n    /**\n     * @brief TODO.\n     *\n     * @param cb Number of bytes.\n     * @param pqi Pointer to the input.\n     */\n    int CbFill(int cb, CQueueInput *pqi);\n\n    /**\n     * @brief TODO.\n     *\n     * @param cb Number of bytes.\n     * @param pqo Pointer to the output.\n     */\n    int CbDrain(int cb, CQueueOutput *pqo);\n\n    /**\n     * @brief TODO.\n     *\n     * @param cb Number of bytes.\n     * @param pb Pointer to the data.\n     */\n    int CbFill(int cb, byte *pb);\n\n    /**\n     * @brief Drain bytes from the byte queue.\n     *\n     * @param cb Number of bytes to drain.\n     */\n    void FreeDrain(int cb);\n};\n\n#endif // BQ_H\n"
  },
  {
    "path": "include/break.h",
    "content": "/**\n * @file break.h\n */\n#ifndef BREAK_H\n#define BREAK_H\n\n#include \"common.h\"\n#include <so.h>\n#include <bis.h>\n#include <oid.h>\n#include <sound.h>\n#include <difficulty.h>\n\ntypedef int GRFBRK;\n\n/**\n * @brief Breakable piece state.\n */\nenum BRKPS\n{\n    BRKPS_Nil = -1,\n    BRKPS_Idle = 0,\n    BRKPS_Pending = 1,\n    BRKPS_Fading = 2,\n    BRKPS_Max = 3\n};\n\n/**\n * @brief Unknown.\n */\nenum BRPT\n{\n    BRPT_Nil = -1,\n    BRPT_Disappear = 0,\n    BRPT_Remain = 1,\n    BRPT_Fixed = 2,\n    BRPT_RemainFixed = 3,\n    BRPT_Appear = 4,\n    BRPT_Max = 5\n};\n\n/**\n * @brief Unknown.\n */\nstruct BRP\n{\n    /* 0x00 */ BRPT brpt;\n    /* 0x04 */ OID oid;\n    /* 0x08 */ LO *plo;\n};\n\n/**\n * @class (_BRK)\n * @brief Breakable base.\n */\nstruct BRK : public SO\n{\n    // ...\n    /* 0x550 */ int cbrp;\n    /* 0x554 */ BRP abrp[16];\n    // ...\n    /* 0x63c */ GRFBRK grfbrk;\n    // ...\n};\n\n/**\n * @brief BREAKABLE_PIECE\n * @brief Shards of breakables that appear when it's broken.\n */\nstruct BRKP\n{\n    // ...\n};\n\n/**\n * @class BREAKABLE\n * @brief Breakable object.\n */\nstruct BREAK : BRK\n{\n    // ...\n};\n\n/**\n * @class ZAPBREAK\n * @brief Unknown.\n *\n * @todo Move to zap.h?\n */\nstruct ZAPBREAK\n{\n    // ...\n};\n\n/**\n * @class FRAGILE.\n * @brief Unknown.\n */\nstruct FRAGILE\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n *\n * @todo Should this be somewhere else?\n */\nstruct XP\n{\n    // ...\n};\n\nvoid InitBrk(BRK *pbrk);\n\nvoid LoadBrkFromBrx(BRK *pbrk, CBinaryInputStream *pbis);\n\nvoid CloneBrk(BRK *pbrk, BRK *pbrkBase);\n\nvoid PostBrkLoad(BRK *pbrk);\n\nvoid PostBrkLoadCallbackHookup(BRK *pbrk, MSGID msgid, void *pv);\n\nvoid UpdateBrk(BRK *pbrk, float dt);\n\nint FAbsorbBrkWkr(BRK *pbrk, WKR *pwkr);\n\nvoid BreakBrk(BRK *pbrk);\n\nvoid SetBrkBroken(BRK *pbrk, int fBroken);\n\nvoid SetBrkExclude(BRK *pbrk, OID oid);\n\nvoid SetBrkRemain(BRK *pbrk, OID oid);\n\nvoid SetBrkFixed(BRK *pbrk, OID oid);\n\nvoid SetBrkRemainFixed(BRK *pbrk, OID oid);\n\nvoid SetBrkOnPlayer(BRK *pbrk, int fBreakOnPlayer);\n\nvoid GetBrkOnPlayer(BRK *pbrk, int *pfBreakOnPlayer);\n\nvoid SetBrkOnBomb(BRK *pbrk, int fBreakOnBomb);\n\nvoid GetBrkOnBomb(BRK *pbrk, int *pfBreakOnBomb);\n\nvoid AddBrkTouchObject(BRK *pbrk, OID oid);\n\nvoid AddBrkTouchClass(BRK *pbrk, CID cid);\n\n/**\n * @todo Rename function.\n */\nvoid FUN_0013DAB8();\n\nSFX *PsfxEnsureBrk(BRK *pbrk, ENSK ensk);\n\nint FCheckBrkTouchObject(BRK *pbrk, SO *psoRoot);\n\nvoid UpdateBrkp(BRKP *pbrkp, float dt);\n\nvoid HandleBrkpMessage(BRKP *pbrkp, MSGID msgid, void *pv);\n\nint FIgnoreBrkpIntersection(BRKP *pbrkp, SO *psoOther);\n\nvoid SetBrkpBrkps(BRKP *pbrkp, BRKPS brkps);\n\nvoid InitBreak(BREAK *pbreak);\n\nvoid InitFragile(FRAGILE *pfragile);\n\nvoid AdjustFragileNewXp(FRAGILE *pfragile, XP *pxp, int ixpd);\n\nvoid AdjustZapbreakNewXp(ZAPBREAK *pzapbreak, XP *pxp, int ixpd);\n\nvoid UpdateZapbreak(ZAPBREAK *pzapbreak, float dt);\n\n#endif // BREAK_H\n"
  },
  {
    "path": "include/brx.h",
    "content": "/**\n * @file brx.h\n *\n * @brief Binary Resource Archive.\n */\n#ifndef BRX_H\n#define BRX_H\n\n#include \"common.h\"\n#include <sw.h>\n\ntypedef int GRFEOPID;\n\n/**\n * @brief Object Type?\n * @todo Populate the enum with values from the prototype.\n */\nenum OTYP\n{\n    OTYP_Nil = -1\n};\n\n/**\n * @brief Optional Data?\n */\nstruct OPTDAT\n{\n    undefined4 unknown1;\n    undefined4 unknown2[2];\n    undefined4 unknown3;\n    undefined4 unknown4;\n    undefined4 unknown5;\n};\n\n/**\n * @brief Unknown.\n */\nstruct EOPID\n{\n    OTYP otyp;\n    GRFEOPID grfeopid;\n    OPTDAT optdat;\n};\n\n/**\n * @brief Builds the eopids array.\n */\nvoid StartupBrx();\n\n/**\n * @brief Creates a new LO from the given parameters.\n *\n * @param cid Class ID.\n * @param psw Pointer to the SW object.\n * @param paloParent Pointer to the parent ALO object.\n * @param oid Object ID.\n * @param isplice Splice index.\n *\n * @return Pointer to the new LO object.\n */\nLO *PloNew(CID cid, SW *psw, ALO *paloParent, OID oid, int isplice);\n\n/**\n * @brief TODO.\n */\nvoid LoadOptionFromBrx(void *pvStruct, EOPID *peopid, CBinaryInputStream *pbis);\n\n/**\n * @brief Loads the options from a BRX file.\n *\n * @param pvStruct Pointer to the structure to load options into.\n * @param pbis Pointer to the binary input stream.\n */\nvoid LoadOptionsFromBrx(void *pvStruct, CBinaryInputStream *pbis);\n\n/**\n * @brief Get the PLO index from a stock OID.\n *\n * @param oid The OID to get the index of.\n *\n * @return The level object index.\n */\nuint IploFromStockOid(int oid);\n\n/**\n * @brief TODO.\n */\nvoid LoadSwObjectsFromBrx(SW *psw, ALO *paloParent, CBinaryInputStream *pbis);\n\n/**\n * @brief TODO.\n */\nvoid SetLoDefaults(LO *plo);\n\n#endif // BRX_H\n"
  },
  {
    "path": "include/bsp.h",
    "content": "/**\n * @file bsp.h\n *\n * @brief Binary Space Partitioning.\n *\n * @note At the time of writing all structs are based on\n * the May 19 prototype, so they could be inaccurate.\n */\n#ifndef BSP_H\n#define BSP_H\n\n#include \"common.h\"\n#include <geom.h>\n#include <vec.h>\n\n/**\n * @brief Line Segment Kind (?)\n */\nenum LSGK\n{\n    LSGK_Nil = -1,\n    LSGK_EdgeToBsp = 0,\n    LSGK_EdgeToSphere = 1,\n    LSGK_EdgeToCylinder = 2,\n    LSGK_EdgeToCbsp = 3,\n    LSGK_Merge = 4,\n    LSGK_Max = 5,\n};\n\n/**\n * @brief Unknown.\n */\nenum PRUNE\n{\n    PRUNE_Neg = 0,\n    PRUNE_Pos = 1,\n    PRUNE_Mixed = 2\n};\n\n/**\n * @brief BSP tree node.\n */\nstruct BSP\n{\n    SURF *psurf;\n    BSP *pbspNeg;\n    BSP *pbspPos;\n};\n\n/**\n * @brief BSP Collection (?).\n */\nstruct BSPC\n{\n    int cbsp;\n    int cbspFull;\n    BSP *absp;\n};\n\n/**\n * @brief Visibility BSP.\n */\nstruct VBSP\n{\n    /* 0x00 */ VECTOR normal;\n    /* 0x0c */ uint padding; // TODO: Remove once VECTOR is 16 bytes long.\n    /* 0x10 */ float gDot;\n    /* 0x14 */ VBSP *pvbspNeg;\n    /* 0x18 */ VBSP *pvbspPos;\n    /* 0x1c */ uint unk;\n};\n\n/**\n * @brief Line Segment Group?\n */\nstruct LSG\n{\n    VECTOR apos[2];\n    VECTOR anormal[2];\n    float au[2];\n    LSGK lsgk;\n    undefined4 unk1;\n    undefined8 unk2;\n    EDGE *pedge;\n    int iiposSwap;\n    LSG *plsgNext;\n};\n\n/**\n * @brief Unknown.\n */\nint ClsgClipEdgeToBsp(BSP *pbspRoot, VECTOR *ppos1, VECTOR *ppos2, int *mpibspn, int clsgMax, LSG *alsg);\n\n/**\n * @brief Unknown.\n */\nPRUNE PruneBsp(BSP *pbsp, VECTOR *ppos, float sRadius, BSP **ppbspNext);\n\n/**\n * @brief Unknown.\n */\nBSP *PbspPointInBspQuick(VECTOR *ppos, BSP *pbsp);\n\n/**\n * @brief Unknown.\n */\nvoid CloneBspc(GEOM *pgeomSrc, BSPC *pbspcSrc, GEOM *pbspcDst, BSPC *pbspcDst);\n\n#endif // BSP_H\n"
  },
  {
    "path": "include/button.h",
    "content": "/**\n * @file button.h\n *\n * @brief Button.\n */\n#ifndef BUTTON_H\n#define BUTTON_H\n\n#include \"common.h\"\n#include <oid.h>\n#include <so.h>\n#include <rs.h>\n\n// Forward.\nstruct ASEG;\n\n/**\n * @brief Unknown.\n */\nenum IASH\n{\n    IASH_On = 0,\n    IASH_Off = 1,\n    IASH_Max = 2\n};\n\n/**\n * @brief Unknown.\n */\nstruct ASH\n{\n    int coid;\n    OID aoid[16];\n    int cpaseg;\n    ASEG *apaseg[16];\n};\n\n/**\n * @brief Button state.\n */\nenum BUTTONS\n{\n    BUTTONS_Nil = -1,\n    BUTTONS_NoContact = 0,\n    BUTTONS_Contact = 1,\n    BUTTONS_Pushed = 2,\n    BUTTONS_Disabled = 3,\n    BUTTONS_Reset = 4,\n    BUTTONS_Max = 5\n};\n\n/**\n * @brief Button.\n *\n * @todo Migrated from May 19 prototype. May be incorrect.\n */\nstruct BTN\n{\n    int unknown;\n    ALO *paloOwner;\n    ASH aash[2];\n    float svtAnimation;\n    /* 0x11C */ int fCheckpointed;\n    /* 0x120 */ int ichkPushed;\n    float tButtons;\n    float dtRepush;\n    BUTTONS buttons;\n    int fEnabled;\n    int fSilent;\n    int fReapplyAseg;\n    int fManualReset;\n    /* 0x140 */ OID oidDialog;\n    // DIALOG *pdialog;\n    int crsmg;\n    RSMG arsmg[8];\n};\n\n/**\n * @class VOL_BUTTON\n * @brief Volume button.\n */\nstruct VOLBTN : public SO\n{\n    // ...\n    /* 0x550 */ int coidPush;\n    /* 0x554 */ OID aoidPush[8];\n    //...\n    /* 0x5c0 */ BTN btn;\n    // ...\n};\n\n/**\n * @class BUTTON\n * @brief Button.\n */\nstruct BUTTON : public SO\n{\n    // ...\n    /* 0x554 */ BTN btn;\n    // ...\n};\n\nvoid PostAshLoad(SW *psw, ASH *pash, ALO *paloOwner);\n\nint FFoundAshAseg(ASH *pash, ASEG *paseg);\n\nint FAddAshAseg(ASH *pash, ASEG *paseg);\n\nint FAddAshOid(ASH *pash, OID oid);\n\nvoid InitBtn(BTN *pbtn);\n\nvoid LoadBtn(BTN *pbtn, ALO *paloOwner);\n\nvoid PostBtnLoad(BTN *pbtn);\n\nvoid RestoreBtnFromCheckpointCallback(BTN *pbtn, MSGID msgid, void *pv);\n\nvoid SetBtnRsmg(BTN *pbtn, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal);\n\nvoid SetBtnButtons(BTN *pbtn, BUTTONS buttons);\n\nint FAddRsmg(RSMG *arsmg, int crsmgMax, int *pcrsmg, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal);\n\nvoid TriggerRsmg(SW *psw, int crsmg, RSMG *arsmg, LO *ploContext, int fTrigger);\n\nvoid RunBtnAsegs(BTN *pbtn, IASH asht, int fSeekToEnd, int fUnknown);\n\nvoid TriggerBtn(BTN *pbtn, int fSeekToEnd, int fChkTrigger);\n\nvoid UntriggerBtn(BTN *pbtn, int fSeekToEnd);\n\nvoid InitButton(BUTTON *pbutton);\n\nvoid LoadButtonFromBrx(BUTTON *pbutton, CBinaryInputStream *pbis);\n\nvoid InsertButtonPos(BUTTON *pbutton, PNT *ppnt, VECTOR *ppos);\n\nvoid InsertButtonMat(BUTTON *pbutton, XFM *pxfm, MATRIX3 *pmat);\n\nvoid PostButtonLoad(BUTTON *pbutton);\n\nvoid CloneButton(BUTTON *pbutton, BUTTON *pbuttonBase);\n\nvoid SetButtonButtons(BUTTON *pbutton, BUTTONS buttons);\n\nint FCheckButtonObject(BUTTON *pbutton, SO *psoOther);\n\nint IposFindButtonClosest(BUTTON *pbutton, float *psDist);\n\nint ImatFindButtonClosest(BUTTON *pbutton, float *prad);\n\nvoid PresetButtonAccel(BUTTON *pbutton, float dt);\n\nvoid UpdateButtonInternalXps(BUTTON *pbutton);\n\nvoid UpdateButton(BUTTON *pbutton, float dt);\n\nint FAbsorbButtonWkr(BUTTON *pbutton, WKR *pwkr);\n\nvoid InitVolbtn(VOLBTN *pvolbtn);\n\nvoid LoadVolbtnFromBrx(VOLBTN *pvolbtn, CBinaryInputStream *pbis);\n\nvoid PostVolbtnLoad(VOLBTN *pvolbtn);\n\nvoid CloneVolbtn(VOLBTN *pvolbtn, VOLBTN *pvolbtnBase);\n\nvoid SetVolbtnButtons(VOLBTN *pvolbtn, BUTTONS buttons);\n\nvoid UpdateVolbtn(VOLBTN *pvolbtn, float dt);\n\nint FGetVolbtnPushObjectsWithinList(VOLBTN *pvolbtn, void *pvstate);\n\nvoid AddBtnAseg(BTN *pbtn, ALO *palo, OID oid);\n\nvoid AddButtonAseg(BUTTON *pbutton, OID oid);\n\nvoid AddVolbtnAseg(VOLBTN *pvolbtn, OID oid);\n\nvoid AddBtnOffAseg(BTN *pbtn, ALO *palo, OID oid);\n\nvoid AddButtonOffAseg(BUTTON *pbutton, OID oid);\n\nvoid AddVolbtnOffAseg(VOLBTN *pvolbtn, OID oid);\n\nvoid AddButtonPushObject(BUTTON *pbutton, OID oid);\n\nvoid AddButtonNoPushObject(BUTTON *pbutton, OID oid);\n\nvoid AddButtonPushClass(BUTTON *pbutton, CID cid);\n\nvoid AddButtonNoPushClass(BUTTON *pbutton, CID cid);\n\nvoid AddVolbtnPushObject(VOLBTN *pvolbtn, OID oid);\n\nvoid SetButtonRsmg(BUTTON *pbutton, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal);\n\nvoid SetVolbtnRsmg(VOLBTN *pvolbtn, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal);\n\n#endif // BUTTON_H\n"
  },
  {
    "path": "include/cat.h",
    "content": "/**\n * @file cat.h\n *\n * @brief WAL catalog.\n */\n#ifndef CAT_H\n#define CAT_H\n\n#include \"common.h\"\n\n/**\n * @brief Related to file location.\n */\nstruct FCL\n{\n    uint isector;\n    uint cb;\n};\n\n/**\n * @brief File Key.\n *\n * Used to identify the file type.\n */\nenum FK\n{\n    FK_Nil = -1,\n    FK_BrxWorld = 0,   // Level File\n    FK_IcoIcon = 1,    // Icon File\n    FK_BnkEffects = 2, // Sound Effect File\n    FK_BnkMusic = 3,   // Music File\n    FK_VagDialog = 4,  // Dialog File\n    FK_VagAnimation = 5,\n    FK_PssMovie = 6, // Video File\n    FK_Max = 7\n};\n\n/**\n * @brief WAL Entry.\n *\n * Stores the file key and file location & size.\n */\nstruct WALE\n{\n    char *pchzKey;    // File Name used for searching for file to load\n    struct FCL *pfcl; // File location and size.\n};\n\n/**\n * @brief File location.\n */\nclass CFileLocation\n{\npublic:\n    FCL m_fcl; // File sector and size.\n\n    // void Clear();\n};\n\n/**\n * @brief Used to startup the catalog system,\n * now it only sets the CD state to ready.\n */\nvoid StartupCatalog();\n\n/**\n * @brief Unknown purpose. Returns the second integer of the given array.\n * Called only once in FUN_0018C1E8 near P2/memcard (?).\n */\nint FUN_001407A0(uint *pui);\n\n#endif // CAT_H\n"
  },
  {
    "path": "include/cd.h",
    "content": "/**\n * @file cd.h\n *\n * @brief CD system.\n */\n#ifndef CD_H\n#define CD_H\n\n#include \"common.h\"\n\n/**\n * @brief CD State.\n */\nenum CDS\n{\n    CDS_Initing = 0,\n    CDS_Searching = 1,\n    CDS_Waiting = 2,\n    CDS_Ready = 3,\n    CDS_Dead = 4,\n    CDS_Max = 5\n};\n\n/**\n * @todo Unknown.\n */\nvoid CpchzTokenizePath(char *pchzPath);\n\n/**\n * @brief Checks if the disc is a PS2 DVD.\n */\nbool FValidCdMmode(void);\n\n/**\n * @brief Sets the disc media mode.\n */\nvoid SetCdMmode(void);\n\n/**\n * @brief Used to startup the CD system in earlier builds, but now it's empty.\n */\nvoid StartupCd(void);\n\n/**\n * @brief Updates the CD system.\n *\n * @todo Implement this function.\n */\nvoid UpdateCd(void);\n\n/**\n * @todo Unknown.\n */\nvoid CdPath(char *pchzDest, char *pchzPath, int fIncludeDevice);\n\n/**\n * @brief Reads sectors from the CD using the 989snd functions.\n *\n * @param isector Starting sector.\n * @param csector Number of sectors to read.\n * @param pv Pointer to destination.\n */\nvoid ReadCd(uint isector, uint csector, void *pv);\n\n/**\n * @brief Reads sectors from the CD using sce functions.\n *\n * @param isector Starting sector.\n * @param csector Number of sectors to read.\n * @param pv Pointer to destination.\n */\nvoid ReadCdDirect(uint isector, uint csector, void *pv);\n\n/**\n * @brief Checks if the CD operation has completed.\n *\n * @param fBlock Non-zero if should block other CD operations.\n *\n * @return true If completed.\n * @return False If not completed.\n */\nbool FCdCompleted(int fBlock);\n\n// TODO: This might not exist?\n// void ErrCdLatest(void);\n\n// Global variables\nextern CDS g_cds;\n\n#endif // CD_H\n"
  },
  {
    "path": "include/chkpnt.h",
    "content": "/**\n * @file chkpnt.h\n *\n * @brief Checkpoint system.\n */\n#ifndef CHKPNT_H\n#define CHKPNT_H\n\n#include \"common.h\"\n#include <vec.h>\n#include <vol.h>\n#include <bis.h>\n\n/**\n * @class CHECK_POINT\n * @brief Checkpoints used throughout platforming levels.\n *\n * @todo Define struct.\n */\nstruct CHKPNT : public ALO\n{\n    // ...\n};\n\ntypedef struct VTCHKMGR; // todo move to vtables header\n\n/**\n * @brief Checkpoint Manager.\n *\n * @todo Fill in missing fields.\n */\nstruct CHKMGR\n{\n    VTCHKMGR *pvtchkmgr;\n    int cbitChk;      // Count of values in abitChk.\n    int *abitChk;     // Unknown, name/type may be wrong.\n    undefined4 unk_0x8;\n    STRUCT_PADDING(127);\n    int fChkDirty;\n    VECTOR posVolChkpnt;\n    int csSaved[129]; // type may be wrong\n    OID unk_oid_0x424;\n    OID unk_oid_0x428;\n    int fCheckpoint;\n};\nextern CHKMGR g_chkmgr;\n\nvoid ResetChkmgrCheckpoints(CHKMGR *pchkmgr);\n\nvoid SaveChkmgrCheckpoint(CHKMGR *pchkmgr, OID oidWarp, OID oidWarpContext);\n\nvoid ReturnChkmgrToCheckpoint(CHKMGR *pchkmgr);\n\nvoid RestoreChkmgrFromCheckpoint(CHKMGR *pchkmgr);\n\nint IchkAllocChkmgr(CHKMGR *pchkmgr);\n\nint FGetChkmgrIchk(CHKMGR *pchkmgr, int ichk);\n\nvoid SetChkmgrIchk(CHKMGR *pchkmgr, int ichk);\n\nvoid ClearChkmgrIchk(CHKMGR *pchkmgr, int ichk);\n\nvoid LoadVolFromBrx(VOL *pvol, CBinaryInputStream *pbis);\n\nint FCheckVolPoint(VOL *pvol, VECTOR *ppos);\n\nvoid InitChkpnt(CHKPNT *pchkpnt);\n\nvoid LoadChkpntFromBrx(CHKPNT *pchkpnt, CBinaryInputStream *pbis);\n\nvoid BindChkpnt(CHKPNT *pchkpnt);\n\nvoid PostChkpntLoad(CHKPNT *pchkpnt);\n\nvoid CloneChkpnt(CHKPNT *pchkpnt, CHKPNT *pchkpntBase);\n\nvoid UpdateChkpnt(CHKPNT *pchkpnt, float dt);\n\n// ? tbd\nvoid FUN_001417f0();\n\nvoid TriggerChkpnt(CHKPNT *pchkpnt);\n\n#endif /* CHKPNT_H */\n"
  },
  {
    "path": "include/cid.h",
    "content": "/**\n * @file cid.h\n *\n * @brief Class IDs.\n */\n#ifndef CID_H\n#define CID_H\n\n#include \"common.h\"\n\n/**\n * @brief Class ID.\n *\n * @note Values are based on May 19 build so are likely incomplete and/or inaccurate.\n */\nenum CID\n{\n    CID_Nil      = -1,  // None\n\n    // Classes present in prototype build\n    CID_BASIC    = 0,   // BASIC\n    CID_LO       = 1,   // LO\n    CID_ALO      = 2,   // LIGHTWEIGHT\n    CID_SO       = 3,   // OBJECT\n    CID_MS       = 4,   // MERGED_STATICS\n    CID_PO       = 5,   // PO\n    CID_STEP     = 6,   // STEP_FIGURE\n    CID_JT       = 7,   // JT\n    CID_STEPGUARD= 8,   // STEP_GUARD\n    CID_SMARTGUARD=9,   // SMART_GUARD\n    CID_GOMER    = 10,  // GOMER\n    CID_UBG      = 11,  // UW_BOSS_GOMER\n    CID_MBG      = 12,  // MS_BOSS_GUARD\n    CID_BHG      = 13,  // BLOODHOUND\n    CID_MURRAY   = 14,  // MURRAY\n    CID_PUFFC    = 15,  // PUFFER_COLLECTION\n    CID_CRFOD    = 16,  // CRUSHER_FODDER\n    CID_CRFODB   = 17,  // CRUSHER_FODDER_BAIT\n    CID_CRFODK   = 18,  // CRUSHER_FODDER_KAM\n    CID_TANK     = 19,  // HOVER_TANK\n    CID_JP       = 20,  // JET_PACK\n    CID_HG       = 21,  // HANG_GLIDER\n    CID_MECHA    = 22,  // MECHA\n    CID_ROV      = 23,  // RIP_OFF_VEHICLE\n    CID_TURRET   = 24,  // TURRET\n    CID_VAULT    = 25,  // VAULT\n    CID_PUFFER   = 26,  // PUFFER\n    // CID_MGV      = 27,  // MOUTH_GAME_VEHICLE\n    CID_SUV      = 28,  // SMASHUP_VEHICLE\n    // CID_CYCLE    = 29,  // CYCLE\n    CID_LGN      = 30,  // LIGHT_GUN\n    // CID_JACK     = 31,  // JACK_HAMMER\n    CID_RIPG     = 32,  // RIPG\n    CID_WATER    = 33,  // WATER\n    CID_BRK      = 34,  // _BRK\n    CID_BREAK    = 35,  // BREAKABLE\n    CID_ALBRK    = 36,  // ALARM_BREAKABLE\n    CID_CAN      = 37,  // CANNON\n    CID_DARTGUN  = 38,  // DARTGUN\n    CID_SWP      = 39,  // SWOOPER\n    CID_FRAGILE  = 40,  // FRAGILE\n    CID_ZAPBREAK = 41,  // ZAPBREAK\n    CID_BRKP     = 42,  // BREAKABLE_PIECE\n    CID_BUTTON   = 43,  // BUTTON\n    CID_VOLBTN   = 44,  // VOL_BUTTON\n    CID_JLOVOL   = 45,  // JLO_VOLUME\n    CID_SQUISH   = 46,  // SQUISH\n    CID_BONE     = 47,  // BONE\n    CID_SPRIZE   = 48,  // _SPRIZE\n    CID_SCPRIZE  = 49,  // _SCPRIZE\n    CID_LIFETKN  = 50,  // EXTRA_LIFE_TOKEN\n    CID_CLUE     = 51,  // CLUE\n    CID_ALARM    = 52,  // ALARM\n    CID_SENSOR   = 53,  // _SENSOR\n    CID_LASEN    = 54,  // LASER_SENSOR\n    CID_CAMSEN   = 55,  // CAMERA_SENSOR\n    CID_PRSEN    = 56,  // PRESSURE_SENSOR\n    CID_BARRIER  = 57,  // BARRIER\n    CID_IKH      = 58,  // IK_HANDLE\n    CID_TZP      = 59,  // TOUCH_ZAPPER\n    CID_VOLZP    = 60,  // VOL_ZAPPER\n    CID_CNVO     = 61,  // CONVEYOR\n    CID_HBSK     = 62,  // HIDE_BASKET\n    CID_BOMB     = 63,  // BOMB\n    CID_MISSILE  = 64,  // MISSILE\n    CID_ACCMISS  = 65,  // ACCEL_MISSILE\n    CID_TARMISS  = 66,  // TARGET_MISSILE\n    CID_SPLMISS  = 67,  // SPLINE_MISSILE\n    CID_GROUNDMISS=68,  // GROUND_MISSILE\n    CID_FLY      = 69,  // FLY\n    CID_RAT      = 70,  // RAT\n    CID_ROH      = 71,  // RIP_OFF_HARVESTER\n    CID_ROC      = 72,  // RIP_OFF_COLLECTIBLE\n    CID_ROST     = 73,  // RIP_OFF_SPAWN_TUNN\n    CID_ROP      = 74,  // RIP_OFF_PRIZE\n    CID_DART     = 75,  // DART\n    CID_UBV      = 76,  // UW_BOSS_VEHICLE\n    CID_UBP      = 77,  // UW_BOSS_PAD\n    CID_DSP      = 78,  // OBJECT_DISPENSER\n    CID_JLO      = 79,  // JLO\n    CID_PUFFT    = 80,  // PUFFER_TORCH\n    CID_MRKV     = 81,  // MURK_VOLUME\n    CID_LGNB     = 82,  // LIGHT_GUN_BOSS\n    CID_BLIPG    = 83,  // BLIPG\n    CID_CAMERA   = 84,  // CAMERA\n    CID_LBONE    = 85,  // LIGHTWEIGHT_BONE\n    CID_EMITTER  = 86,  // EMITTER\n    CID_LIGHT    = 87,  // LIGHT\n    CID_SCH      = 88,  // SPLINE_CONSTRAINT_\n    CID_LIKH     = 89,  // LIGHTWEIGHT_IK_HAN\n    CID_CHKPNT   = 90,  // CHECK_POINT\n    CID_PROXY    = 91,  // PROXY\n    CID_SKY      = 92,  // SKY\n    CID_DPRIZE   = 93,  // _DPRIZE\n    CID_CHARM    = 94,  // CHARM\n    CID_COIN     = 95,  // COIN\n    CID_KEY      = 96,  // KEY\n    CID_GOLD     = 97,  // GOLD\n    CID_LOCK     = 98,  // LOCK\n    CID_LOCKG    = 99,  // LOCK_GROUP\n    CID_TAIL     = 100, // TAIL\n    CID_ROB      = 101, // RIP_OFF_BRAIN\n    CID_FLASH    = 102, // FLASHLIGHT\n    CID_DYSH     = 103, // DYNAMIC_SHADOW\n    CID_SCENTMAP = 104, // SCENT_MAP\n    CID_WAYPOINT = 105, // WAY_POINT\n    CID_TN       = 106, // NEW_TUNNEL\n    CID_JLOC     = 107, // JLO_CLUSTER\n    CID_DIALOG   = 108, // DIALOG\n    CID_SPEAKER  = 109, // SPEAKER\n    CID_ROPE     = 110, // ROPE\n    CID_WM       = 111, // WORLD_MAP\n    CID_PUFFB    = 112, // PUFFER_BRAIN\n    CID_CRBRAIN  = 113, // CRUSHER_BRAIN\n    // CID_MGC      = 114, // MOUTH_GAME_COLLECT\n    // CID_JACKB    = 115, // JACK_BOSS\n    // CID_JACKN    = 116, // JACK_NPC\n    // CID_JACKF    = 117, // JACK_FRAGMENT\n    CID_SW       = 118, // WORLD\n    CID_CM       = 119, // _CAMERA\n    CID_SHAPE    = 120, // SHAPE\n    CID_HSHAPE   = 121, // HIDE_SHAPE\n    CID_PIPE     = 122, // PIPE\n    CID_RAIL     = 123, // RAIL\n    CID_LANDING  = 124, // LANDING\n    CID_XFM      = 125, // TRANSFORM\n    CID_WARP     = 126, // WARP\n    CID_TARGET   = 127, // TARGET\n    CID_HND      = 128, // HANDLE\n    CID_EXPL     = 129, // _EXPLODE_BASE\n    CID_EXPLG    = 130, // EXPLODE_GROUP\n    CID_EXPLO    = 131, // BLACK_HOLE\n    CID_EXPLS    = 132, // EXPLODE_STYLE\n    CID_VOL      = 133, // VOLUME\n    CID_RATHOLE  = 134, // RATHOLE\n    CID_PUFFV    = 135, // PUFFER_VOLUME\n    CID_EXIT     = 136, // EXIT\n    CID_PNT      = 137, // POINT\n    CID_PNTSV    = 138, // POINT_WITH_SPEED\n    CID_PNTS     = 139, // POINT_WITH_DISTANCE\n    CID_PNTVEC   = 140, // POINT_WITH_VECTOR\n    CID_HPNT     = 141, // HIDE_POINT\n    CID_JMT      = 142, // JUMP_TARGET\n    CID_SPIRE    = 143, // SPIRE\n    CID_SCAN     = 144, // SCAN_ITEM\n    CID_ASEG     = 145, // ANIMATION_SEGMENT\n    CID_ASEGBL   = 146, // ASEGBL\n    CID_MAP      = 147, // MAP_2D\n    CID__VISZONE = 148, // VISIBILITY_ZONE\n    CID_VISMAP   = 149, // VISMAP\n    CID_FRZG     = 150, // FREEZE_GROUP\n    CID_SM       = 151, // STATE_MACHINE\n    CID_SGG      = 152, // STEP_GUARD_GROUP\n    CID_PATHZONE = 153, // PATH_ZONE\n    CID_RCHM     = 154, // REACH_MAP\n    CID_RWM      = 155, // AMMO_MANAGER\n    CID_WR       = 156, // SPACE_WARP\n    CID_KEYHOLE  = 157, // KEYHOLE\n    CID_JSG      = 158, // SCRIPT\n    CID_ASEGA    = 159, // ANIMATION_SEGMENT_APPLICATION\n    CID_SMA      = 160, // STATE_MACHINE_APPLICATION\n    CID__FCST    = 161, // FOSTER_CONSTRAINT\n\n    // Classes only present in release build (IDs may be inaccurate)\n    CID_SBG      = 162, // S_BOSS_GUARD\n    CID_VBG      = 163, // V_BOSS_GUARD\n\n    CID_Max      = 164 // Max value\n};\n\n#endif // CID_H\n"
  },
  {
    "path": "include/clip.h",
    "content": "/**\n * @file clip.h\n */\n#ifndef CLIP_H\n#define CLIP_H\n\n#include \"common.h\"\n#include <geom.h>\n#include <bsp.h>\n#include <vec.h>\n#include <so.h>\n\ntypedef int GRFHTL;\n\n/**\n * @brief Unknown.\n * @todo Based on the may prototype,\n * so this can be incorrect.\n */\nstruct MAA\n{\n    float u;\n    int iu;\n    undefined1 unk[8];\n    VECTOR pos;\n    VECTOR normal;\n};\n\nSO *PsoHitTestLineObjects(GRFHTL grfhtl, VECTOR *ppos0, VECTOR *ppos1, int cpso, SO **apso, LSG *plsgBest);\n\nint ClsgClipEdgeToObject(SO *pso, VECTOR *ppos0, VECTOR *ppos1, int clsgMax, LSG *alsg);\n\nint ClsgClipEdgeToObjectPruned(SO *pso, BSP *pbspPruned, VECTOR *ppos0, VECTOR *ppos1, int clsgMax, LSG *alsg);\n\nint ClsgClipCylinderToObject(SO *pso, VECTOR *ppos0, VECTOR *ppos1, float sRadius, int clsgMax, LSG *alsg);\n\nint ClsgClipLineToSphere(VECTOR *pposSphere, float sRadius, VECTOR *ppos0, VECTOR *ppos1, int clsgMax, LSG *alsg);\n\nint ClsgClipEdgeToSphere(VECTOR *pposSphere, float sRadius, VECTOR *ppos0, VECTOR *ppos1, int clsgMax, LSG *alsg);\n\nint ClsgClipCylinderToSphere(VECTOR *pposSphere, float sRadiusSphere, VECTOR *ppos0, VECTOR *ppos1, float sRadiusCylinder, int clsgMax, LSG *alsg);\n\nint ClsgClipEdgeToCylinder(VECTOR *pposCylinder0, VECTOR *pposCylinder1, float sRadiusCylinder, VECTOR *pposEdge0, VECTOR *pposEdge1, int clsgMax, LSG *alsg);\n\nint SgnCompareMaa(MAA *pmaa1, MAA *pmaa2);\n\nint ClsgMergeAlsg(int clsg, LSG *alsg);\n\nint ClsgClipCylinderToBsp(BSPC *pbspc, GEOM *pgeom, VECTOR *ppos0, VECTOR *ppos1, float sRadiusCylinder, int clsgMax, LSG *alsg);\n\n#endif // CLIP_H\n"
  },
  {
    "path": "include/clock.h",
    "content": "/**\n * @file clock.h\n *\n * @brief Engine clock.\n */\n#ifndef CLOCK_H\n#define CLOCK_H\n\n#include \"common.h\"\n\ntypedef unsigned long long TICK;\n\n/**\n * @brief Engine clock.\n */\nstruct CLOCK\n{\n    int fEnabled; // clock enabled flag\n    float t;      // current time\n    float dt;     // time since last frame\n    float dtPrev; // dt from previous frame\n    float tReal;  // t factoring in EE clock cyclerate\n    float dtReal; // dt factoring in EE clock cyclerate\n    TICK tickFrame;\n};\n\nextern float D_0024CD4C;\n\nextern float g_rtClock;\nextern float g_rtClockPowerUp;\nextern CLOCK g_clock;\n// extern TICK s_tickLastRaw; // Should be static.\nextern ulong cWrapAround; // Should be static, and not initialized. Replace once bss section of the TU is migrated.\n\n/**\n * @brief Sets the global clock rate multiplier and enables/disables the clock.\n *\n * @param rt The new clock rate multiplier (1.0 = normal, > 1.0 = faster).\n */\nvoid SetClockRate(float rt);\n\n/**\n * @brief Updates clock state based on elapsed time, with clamping and scaling.\n *\n * @details Clamps delta time to 1-2 frames, applies rate multipliers if enabled.\n *\n * @param pclock Pointer to the clock to update.\n */\nvoid MarkClockTick(CLOCK *pclock);\n\n/**\n * @brief Updates clock with raw elapsed time only (no clamping or scaling).\n *\n * @param pclock Pointer to the clock to update.\n */\nvoid MarkClockTickRealOnly(CLOCK *pclock);\n\n/**\n * @brief Resets the clock's accumulated time to a specific value.\n *\n * @param pclock Pointer to the clock to reset.\n * @param t Time value in seconds to set.\n */\nvoid ResetClock(CLOCK *pclock, float t);\n\n/**\n * @brief Enables or disables a clock instance.\n *\n * @param pclock Pointer to the clock.\n * @param fEnabled Non-zero to enable, zero to disable.\n */\nvoid SetClockEnabled(CLOCK *pclock, int fEnabled);\n\n/**\n * @brief Initializes the clock system.\n */\nvoid StartupClock();\n\n/**\n * @brief Returns a 64-bit tick count derived from the 32-bit hardware counter.\n *\n * @details Extends the 32-bit CP0 Count register to 64 bits by tracking overflows.\n *\n * @return 64-bit tick value: upper 32 bits = wraparound count, lower 32 bits =\n * Count register.\n */\nconst TICK TickNow();\n\n#endif // CLOCK_H\n"
  },
  {
    "path": "include/cm.h",
    "content": "/**\n * @file cm.h\n *\n * @brief Game camera.\n */\n#ifndef CM_H\n#define CM_H\n\n#include \"common.h\"\n#include <lo.h>\n#include <util.h>\n#include <binoc.h> // only for RGBA\n#include <xform.h>\n#include <sound.h>\n#include <clock.h>\n\nstruct CM; // Forward declaration\nstruct TN;\n\ntypedef int GRFRCP;\n\n/**\n * @brief Camera (?) kind?\n */\nenum CMK\n{\n    CMK_Nil = -1,\n    CMK_Translucent = 0,\n    CMK_Fade = 1,\n    CMK_Opaque = 2,\n    CMK_Max = 3\n};\n\n/**\n * @brief Unknown Kind.\n */\nenum CFK\n{\n    CFK_Nil = -1,\n    CFK_Behind = 0,\n    CFK_Side = 1,\n    CFK_Max = 2\n};\n\n/**\n * @brief Unknown, may be wrong.\n */\nenum CPP\n{\n    CPP_Nil = -1,\n    CPP_Base = 0,\n    CPP_Default = 1,\n    CPP_Tunnel_Pri0 = 2,\n    CPP_Tunnel_Pri1 = 3,\n    CPP_Tunnel_Pri2 = 4,\n    CPP_Tunnel_Pri3 = 5,\n    CPP_LookAround = 6,\n    CPP_Animated = 7,\n    CPP_ManualOverride = 8,\n    CPP_UserTestWalkthrough = 9,\n    CPP_Max = 10\n};\n\n/**\n * @brief Unknown.\n */\nenum CPMT\n{\n    CPMT_Truck = 0,\n    CPMT_Pan = 1,\n    CPMT_Slide = 2,\n    CPMT_Orbit = 3,\n    CPMT_Align = 4,\n    CPMT_Walkthrough = 5,\n    CPMT_Max = 6\n};\n\n/**\n * @brief Look kind.\n */\nenum LOOKK\n{\n    LOOKK_Nil = -1,\n    LOOKK_User = 0,\n    LOOKK_Sniper = 1,\n    LOOKK_Dialog = 2,\n    LOOKK_Confront = 3,\n    LOOKK_Max = 4\n};\n\n/**\n * @brief Unknown.\n * @todo Move to tn.h?\n */\nenum FTND\n{\n    FTND_Nil = -1,\n    FTND_Forward = 1,\n    FTND_Reverse = 2,\n    FTND_Manual = 4,\n    FTND_Max = 5\n};\n\n/**\n * @brief Fog parameters.\n */\nstruct FGFN\n{\n    float duFogBias;\n    float ruFog;\n    float sNearFog;\n    float duFogPlusClipBias;\n};\n\n/**\n * @brief Unknown.\n */\nstruct CPDEFI\n{\n    int grfcpd;\n    undefined4 field1_0x4;\n    undefined4 field2_0x8;\n    undefined4 field3_0xc;\n    VECTOR posBase;\n    VECTOR vBase;\n    float radHome;\n    float sAdjust;\n    float tMoveLast;\n    CFK cfk;\n    VECTOR posAdjust;\n};\n\n/**\n * @brief Camera policy.\n */\nstruct CPLCY\n{\n    undefined4 vtable; // TODO: implement methods on this struct\n    CM *pcm;\n};\n\n/**\n * @brief Camera policy: manual.\n *\n * Normal orbit camera.\n */\nstruct CPMAN : public CPLCY\n{\n    CPMT cpmt;\n    ALO *paloOrbit;\n    int cframeStatus;\n};\n\n/**\n * @brief Camera policy: look.\n *\n * Used for binoc-u-com, and probably sniper mode.\n */\nstruct CPLOOK : public CPLCY\n{\n    float radPan;\n    float swPan;\n    float radTilt;\n    float swTilt;\n    float uZoom;\n    float svuZoom;\n    float rZoomMax;\n    LM lmFOV;\n    LOOKK alookk[4];\n    int clookk;\n    int fSoundPaused;\n    AMB *pambBinoc;\n    AMB *pambAmbient;\n    ALO *paloFocusSniper;\n    PNT *ppntAnchor;\n    float sRadiusSniper;\n    float rScreenSniper;\n};\n\n/**\n * @brief Camera policy: align\n *\n * Unknown usage.\n */\nstruct CPALIGN : public CPLCY\n{\n    undefined4 field_1_0x0;\n    undefined4 field_2_0x4;\n    VECTOR posLocal;\n    undefined4 field_4_0xc;\n    undefined4 field_5_0x10;\n    undefined4 field_6_0x14;\n    float field_7_0x18;\n    float field_8_0x1c;\n};\n\n/**\n * @brief Camera policy: animation segment(?)\n *\n * Unknown usage.\n */\nstruct CPASEG : public CPLCY\n{\n    CAMERA *pcamera;\n};\n\n/**\n * @brief Camera policy: tunnel.\n *\n * Unknown usage.\n *\n * @note Might be unused in release build, based on the name.\n */\nstruct CPTN : public CPLCY\n{\n    TN *ptn;\n    float radManual;\n    float xyManual;\n    float zManual;\n    int fHome;\n    float radHome;\n    FTND ftnd;\n    int fActivate;\n    int fPanOnEntryDone;\n    float swOrbit;\n    float tLastOrbit;\n    float radCur;\n    float radFwdPrev;\n    float radRevPrev;\n    float tMoveLast;\n    float uFollowCur;\n    float vxy;\n    float vz;\n    VECTOR posEyePrev;\n};\n\n/**\n * @brief Camera policy: (?).\n */\nstruct CPR\n{\n    CPP cpp;\n    CPLCY *pcplcy;\n    SO *psoFocus;\n    void *pv;\n};\n\n/**\n * @class _CAMERA\n * @brief Base class for cameras.\n */\nstruct CM : public LO\n{\n    /* 0x40 */ VECTOR pos;\n    VECTOR4 anormalFrustrumTranspose[3];\n    MATRIX3 mat;\n    float rMRDAdjust;\n    undefined4 field5_0x98;\n    undefined4 field6_0x9c;\n    undefined4 field7_0xa0;\n    MATRIX4 matProj;\n    MATRIX4 matWorldToClip;\n    MATRIX4 matClipToWorld;\n    VECTOR anormalFrustrum[4];\n    float rMRD;\n    float radFOV;\n    float rAspect;\n    float sRadiusNearClip;\n    float xScreenRange;\n    float yScreenRange;\n    float sNearFog;\n    float sFarFog;\n    float uFogMax;\n    RGBA rgbaFog;\n    FGFN fgfn;\n    float tJolt;\n    int grfzon;\n    int fCutNext;\n    int fCut;\n    int fRadCut;\n    float radCut;\n    float sNearClip;\n    float sFarClip;\n    int fDisplaced;\n    float uPanProgress;\n    float uTiltProgress;\n    float uSProgress;\n    float field35_0x1fc;\n    float field36_0x200;\n    VECTOR dposCenter;\n    VECTOR vCenter; //NOTE: this might not be a VECTOR... -Kestin\n    undefined4 field39_0x21c;\n    bool reset_flag;\n    int field41_0x224;\n    int field42_0x228;\n    float field43_0x22c;\n    undefined4 field44_0x230;\n    //VECTOR vAdjust;\n    VECTOR dposFocus;\n    VECTOR vFocus;\n    VECTOR posScreen;\n    VECTOR vScreen;\n    float swPanPos;\n    float swTiltPos;\n    float sv;\n    float swPanMat;\n    float swTiltMat;\n    undefined4 field52_0x278;\n    undefined4 field53_0x27c;\n    undefined4 field54_0x280;\n    VECTOR posCenterPrev;\n    VECTOR posClear;\n    MATRIX3 matClear;\n    SO *psoFocusPrev;\n    undefined4 field59_0x2c4;\n    undefined4 field60_0x2c8;\n    undefined4 field61_0x2cc;\n    CPDEFI cpdefiPrev;\n    int cpaloFade;\n    ALO *apaloFade[8];\n    float tActivateCplcy;\n    undefined4 field66_0x33c;\n    undefined4 field67_0x340;\n    MATRIX3 matRotateToCam;\n    MATRIX3 matRotateTiltToCam;\n    int ccpr;\n    CPR acpr[8];\n    CPMAN cpman;\n    undefined8 field73_0x428;\n    undefined8 field74_0x430;\n    undefined8 field75_0x438;\n    undefined8 field76_0x440;\n    undefined8 field77_0x448;\n    undefined8 field78_0x450;\n    undefined8 field79_0x458;\n    CPLOOK cplook;\n    CPALIGN cpalign;\n    CPASEG cpaseg;\n    CPTN cptn;\n};\n\n// extern CM g_cm; // Main game camera.\nextern CM *g_pcm; // Pointer to the main game camera.\n\n/**\n * @brief Starts up the camera system.\n */\nvoid StartupCm();\n\n/**\n * @brief Calls RecalcCmFrustrum on the given camera.\n */\nvoid RecalcCmFrustrum(CM *pcm);\n\n/**\n * @brief Sets far clip plane on the global camera.\n */\nvoid SetSwCameraFarClip(float sFarClip);\n\n/**\n * @brief Sets Fog on the global camera.\n */\nvoid SetSwCameraRgbaFog(SW *psw, RGBA *prgbaFog);\n\n/**\n * @brief Sets position on the given camera.\n */\nvoid SetCmPos(CM *pcm, VECTOR *ppos);\n\n/**\n * @brief Sets matrix on the given camera.\n */\nvoid SetCmMat(CM *pcm, MATRIX3 *pmat);\n\n/**\n * @brief Sets near clip plane on the given camera.\n */\nvoid SetCmNearClip(CM *pcm, float sNearClip);\n\n/**\n * @brief Sets far clip plane on the given camera.\n */\nvoid SetCmFarClip(CM *pcm, float sFarClip);\n\n/**\n * @brief Sets SProgress on the given camera.\n */\nvoid SetCmSProgress(CM *pcm, float uSProgress);\n\n/**\n * @brief Changes the FOV of the camera and then calls RecalcCmFrustrum.\n */\nvoid SetCmFov(CM *pcm, float fov);\n\n/**\n * @brief Sets field35_0x1fc on the given camera.\n */\nvoid FUN_001439c8(CM *pcm, float param_2); //TODO: Rename function\n\n/**\n * @brief Sets field36_0x200 on the given camera.\n */\nvoid FUN_001439e8(CM *pcm, float param_2); //TODO: Rename function\n\n/**\n * @brief Sets the RGBA fog color for the camera.\n */\nvoid SetCmRgbaFog(CM *pcm, RGBA *prgbaFog);\n\n/**\n * @brief Sets the minimum render distance ratio (?) on the given camera.\n */\nvoid SetCmMrdRatio(CM *pcm, float ratio);\n\n/**\n * @brief Clears fading objects from the given camera.\n */\nvoid ClearCmFadeObjects(CM *pcm);\n\n/**\n * @brief Sets up the given camera.\n */\nvoid SetupCm(CM *pcm);\n\n/**\n * @brief TODO.\n */\nvoid DrawCm(CM *pcm);\n\n/**\n * @brief Sets the position matrix on the given camera.\n */\nvoid SetCmPosMat(CM *pcm, VECTOR *ppos, MATRIX3 *pmat);\n\nvoid AdjustCmJoy(CM *pcm, JOY *pjoy, JOYID joyid, float *prad);\n\nvoid SetCmPolicy(CM *pcm, CPP cpp, CPLCY *pcplcy, SO *psoFocus, void *pv);\n\nvoid RevokeCmPolicy(CM *pcm, GRFRCP grfrcp, CPP cpp, CPLCY *pcplcy, SO *psoFocus, void *pv);\n\n/**\n * @brief Sets Cut on the given camera.\n */\nvoid SetCmCut(CM *pcm, float *pradCut);\n\n/**\n * @brief Sets the reset flag on the given camera.\n */\nvoid SetResetFlag(CM *pcm);\n\n/**\n * @brief Clears cut from the given camera.\n */\nvoid ClearCmCut(CM *pcm);\n\n/**\n * @brief Push lookk on the given camera.\n */\nvoid PushLookkCm(CM *pcm, LOOKK lookk);\n\n/**\n * @brief Calls LookkPopCm on the given camera.\n */\nLOOKK LookkPopCm(CM *pcm);\n\n/**\n * @brief Calls LookkCurCm on the given camera.\n */\nLOOKK LookkCurCm(CM *pcm);\n\n/**\n * @brief Sets sniper focus on the given camera.\n */\nvoid SetCmSniperFocus(CM *pcm, PNT *ppntAnchor, float sRadiusSniper, float rScreenSniper);\n\n/**\n * @brief Calls FUN_00146028 on the given camera.\n */\nvoid FUN_00146028(CM *pcm); //TODO: Rename function\n\n/**\n * @brief Initializes Camera.\n */\nvoid cm__static_initialization_and_destruction_0(int __initialize_p,int __priority);\n\n/**\n * @brief Startsup Camera.\n */\nvoid _GLOBAL_$I$StartupCm();\n\n// todo fix undefined reference errors\n// extern VECTOR4 g_posEyeDefault;\n// extern VECTOR4 g_posCenterDefault;\n// extern float g_sNearFog;\n// extern float g_sFarFog;\n// extern float g_uFogMax;\n// extern RGBA g_rgbaFog;\n// extern VECTOR4 D_2618b8;\n// extern float DT_CmJoltMax;\n// extern float SW_CmJolt;\n// extern CLQ s_clqUToUJolt;\n// extern VECTOR4 s_dposJolt;\n// extern VECTOR4 s_rotJolt;\n// extern VECTOR4 s_vecRange;\n// extern VECTOR4 s_vecOffset;\n// extern float R_SetCmSpring;\n// extern float R_SetCmDamping;\n// extern float D_00261928[9];\n// extern float D_0026194c;\n// extern float D_00261950;\n// extern SMP s_smpSquishEye;\n// extern float D_00261970;\n// extern float D_00261974;\n// extern float D_00261978;\n// extern float D_0026197c;\n// extern float D_00261980;\n// extern float D_00261984;\n// extern float D_00261988;\n// extern float D_0026198c;\n// extern CM* g_pcm;\n\n#endif // CM_H\n"
  },
  {
    "path": "include/cnvo.h",
    "content": "/**\n * @file cnvo.h\n */\n#ifndef CNVO_H\n#define CNVO_H\n\n#include \"common.h\"\n#include <so.h>\n\n// TODO: What is this? Where should this be defined?\nstruct XP;\n\n/**\n * @class CONVERYOR\n * @brief Conveyor belt (probably used in Fire Down Below).\n * @todo Implement the struct.\n */\nstruct CNVO : public SO\n{\n    // ...\n    /* 0x550 */ float svBelt;\n    /* 0x554 */ float svuAvg;\n    /* 0x558 */ float svvAvg;\n    // ...\n};\n\nvoid InitCnvo(CNVO *pcnvo);\n\nvoid LoadCnvoFromBrx(CNVO *pcnvo, CBinaryInputStream *pbis);\n\nvoid PostCnvoLoad(CNVO *pcnvo);\n\nvoid AdjustCnvoXpVelocity(CNVO *pcnvo, XP *pxp, int ixpd);\n\nvoid SetCnvoBeltSpeed(CNVO *pcnvo, float svBelt);\n\nvoid MatchCnvoScrollerToBeltSpeed(CNVO *pcnvo);\n\n#endif // CNVO_H\n"
  },
  {
    "path": "include/coin.h",
    "content": "/**\n * @file coin.h\n *\n * @brief Coins, keys, and other collectibles.\n */\n#ifndef COIN_H\n#define COIN_H\n\n#include \"common.h\"\n#include <alo.h>\n#include <oid.h>\n#include <sm.h>\n#include <sw.h>\n#include <xform.h>\n#include <sound.h>\n#include <target.h>\n\n// Forward declarations\nstruct DPRIZE;\nstruct COIN;\nstruct KEY;\nstruct CHARM;\n\n/**\n * @brief DPRIZE state.\n *\n * @note Values based on May 19 build.\n */\nenum DPRIZES\n{\n    DPRIZES_Nil = -1,\n    DPRIZES_Normal = 0,\n    DPRIZES_Collect = 1,\n    DPRIZES_Removed = 2,\n    DPRIZES_Fall = 3,\n    DPRIZES_Swirl = 4,\n    DPRIZES_Stick = 5,\n    DPRIZES_Lose = 6,\n    DPRIZES_Attract = 7,\n    DPRIZES_Max = 8\n};\n\n/**\n * @class _DPRIZE\n * @brief Base class for collectibles.\n */\nstruct DPRIZE : public ALO\n{\n    OID oidInitialState;\n    float tDprizes;\n    DPRIZES dprizesInit;\n    DPRIZES dprizes; // State\n    float dtInitialSkip;\n    SM *psm;   // State machine\n    SMA *psma; // State machine action\n    TARGET *ptarget;\n    VECTOR posCenter;\n    VECTOR vCenter;\n    VECTOR dvCenter;\n    PNT *ppntFrontGlint;\n    PNT *ppntBackGlint;\n    int fLeft;\n    float uGlintChance;\n    float tGlint;\n    undefined4 unk_0[4];\n    int fNeverReuse;\n    int fReuseCandidate;\n    int fLastBounce;\n    float svLastBounceMax;\n    float svLastBounce;\n    float sRadiusBounce;\n    float sRadiusCollect;\n    float rzBounce;\n    float rxyBounce;\n    float radSmooth;\n    VECTOR normalSmooth;\n    int fSwirlDone;\n    undefined4 unk_1;\n    DLE dle;\n    int ichkCollected;\n    EXPL *pexplCollect;\n    EXPL *pexplAttract;\n    float svcAttract;\n    float cAttract;\n};\n\n/**\n * @class COIN\n * @brief Treasure coin.\n */\nstruct COIN : public DPRIZE\n{\n    LM lmDtMaxLifetime;\n    float tLose;\n};\n\n/**\n * @class KEY\n * @brief Treasure key.\n */\nstruct KEY : public DPRIZE\n{\n    STRUCT_PADDING(5);  // 0x0 - 0x13 Padding?\n    SW* psw;            // 0x14\n    STRUCT_PADDING(19); // 0x18-0x2b Pading?\n    CFrame* pCFrame;    // 0x2c\n    STRUCT_PADDING(670); // 0x31 - 0x2cf Padding?\n    DPRIZES dprizes;    // 0x2d0\n};\n\n/**\n * @class CHARM\n * @brief Lucky charm worn by Sly and Murray.\n */\nstruct CHARM : public DPRIZE\n{\n    //...\n};\n\n/**\n * @brief Initializes a dprize.\n *\n * @param pdprize Dprize to initialize.\n */\nvoid InitDprize(DPRIZE *pdprize);\n\n/**\n * @brief Loads a dprize from an Input Stream.\n *\n * @param pdprize Dprize to load/initialize.\n * @param pbis Binary input Stream.\n */\nvoid LoadDprizeFromBrx(DPRIZE *pdprize, CBinaryInputStream *pbis);\n\n/**\n * @brief Clone a dprize.\n *\n * @param pdprize Dprize clone target.\n * @param pdprizeBase Original dprize to clone.\n *\n * @note ichkCollected and dle will not be overwritten.\n */\nvoid CloneDprize(DPRIZE *pdprize, DPRIZE *pdprizeBase);\n\n/**\n * @brief Sets the state of a given dprize.\n *\n * @param pdprize Dprize whose state to set.\n * @param dprizes New state value.\n *\n */\nvoid SetDprizeDprizes(DPRIZE *pdprize, DPRIZES dprizes);\n\n/**\n * @brief Initializes a coin.\n *\n * @param pcoin Coin to initialize.\n */\nvoid InitCoin(COIN *pcoin);\n\n/**\n * @brief Updates a coin.\n *\n * @param pcoin Coin to update.\n * @param dt Time elapsed since the last frame.\n *\n * @todo Implement this function.\n */\nvoid UpdateCoin(COIN *pcoin, float dt);\n\n// ...\n\nvoid CreateSwCharm(SW *psw);\n\n/**\n * @brief Adds a life.\n *\n */\nvoid AddLife(void *ptr);\n\n/**\n * @brief Handles when the player touches a coin.\n *\n * @param pcoin Pointer to the coin.\n */\nvoid OnCoinSmack(COIN *pcoin);\n\n/**\n * @brief Sets a coin's dprize state.\n *\n * @param pcoin Coin whose state to update.\n * @param dprizes New state value.\n *\n * @todo Implement this function.\n */\nvoid SetCoinDprizes(COIN *pcoin, DPRIZES dprizes);\n\n/**\n * @brief Initializes a lucky charm.\n *\n * @param pcharm Charm to initialize.\n */\nvoid InitCharm(CHARM *pcharm);\n\n/**\n * @brief Sets a lucky charm's dprize state.\n *\n * @param pcharm Charm whose state to update.\n * @param dprizes New state value.\n *\n * @todo Fill CHARM struct.\n */\nvoid SetCharmDprizes(CHARM *pcharm, DPRIZES dprizes);\n\n/**\n * @brief Initializes a treasure key.\n *\n * @param pcharm Key to initialize.\n */\nvoid InitKey(KEY *pkey);\n\n/**\n * @brief Sets a treasure key's dprize state.\n *\n * @param pkey Key whose state to set.\n * @param dprizes New state value.\n */\nvoid SetKeyDprizes(KEY *pkey, DPRIZES dprizes);\n\n/**\n * @brief Unknown.\n *\n * @todo Investigate this function.\n */\nint CpdprizeAttractSwDprizes(SW *psw, CID cid, VECTOR *pposCenter, int cpdprizeMax, DPRIZE **apdprize);\n\n/**\n * @brief Unknown.\n *\n * @todo Investigate this function.\n */\nvoid RemoveSwExtraneousCharms(SW *psw);\n\nextern SNIP s_asnipDprize[5];\n\n#endif // COIN_H\n"
  },
  {
    "path": "include/common.h",
    "content": "/**\n * @file common.h\n *\n * @brief Common header file.\n */\n#ifndef COMMON_H\n#define COMMON_H\n\n#include \"include_asm.h\"\n#include \"types.h\"\n#include \"vtables.h\"\n#include \"spaprops.h\"\n\n// Helper macros for decompilation\n\n/**\n * @brief Accesses a value on a struct by its offset and type. For use when the\n * struct is unimplemented, incomplete or inaccurate.\n *\n * @param pointer Pointer to the struct.\n * @param offset Offset of the field within the struct.\n * @param type Type of the field.\n */\n#define STRUCT_OFFSET(pointer, offset, type) (*(type *)((uint8_t *)(pointer) + (offset)))\n\n/**\n * @brief Access an array element at a struct offset with index.\n * Uses expression ordering that generates matching assembly.\n * @param pointer Pointer to the struct.\n * @param offset Offset of the array within the struct.\n * @param type Type of the array elements.\n * @param index Array index to access.\n */\n#define STRUCT_OFFSET_INDEX(pointer, offset, type, index) \\\n    (*(type *)((int)(pointer) + (((index) << 2) + (offset))))\n\n\n// Helper macros for struct padding (workaround for eegcc not supporting macro expansion in struct fields)\n#define STRUCT_PADDING_CAT(a, b) a##b\n#define STRUCT_PADDING_INTERNAL(a, b) STRUCT_PADDING_CAT(a, b)\n\n/**\n * @brief Inserts an array of padding words into a struct. It generates a unique\n * name for the padding field using the line number.\n *\n * @param name Name of the padding field.\n * @param size Number of 4-byte words in the padding field.\n */\n#define STRUCT_PADDING(size) uint32_t STRUCT_PADDING_INTERNAL(_pad_, __LINE__)[size]\n\n/**\n * @brief Inserts a four-byte word followed by four bytes of 0x00.\n */\n#define JUNK_WORD(val) asm(\".word \" #val \"\\n\\t\" \".word 0x00000000\\n\\t\")\n\n/**\n * @brief Shortcut macro for junk `addiu $29, $29, imm` instructions.\n * Takes the immediate value as a hex byte and emits the corresponding instruction word.\n */\n#define JUNK_ADDIU(imm) JUNK_WORD(0x27BD00##imm)\n\n/**\n * @brief Inserts a four-byte nop on it's own.\n */\n#define JUNK_NOP() asm(\".word 0x00000000\\n\\t\")\n\n// Global system values\nextern int _gpReg; // Global pointer register\n\n/**\n * @brief RGBA color value.\n */\nstruct RGBA\n{\n    uchar bRed;\n    uchar bGreen;\n    uchar bBlue;\n    uchar bAlpha;\n\n    inline void operator=(const int rgba)\n    {\n        bRed = (rgba >> 24) & 0xFF;\n        bGreen = (rgba >> 16) & 0xFF;\n        bBlue = (rgba >> 8) & 0xFF;\n        bAlpha = rgba & 0xFF;\n    }\n};\n\n#endif // COMMON_H\n"
  },
  {
    "path": "include/cplcy.h",
    "content": "/**\n * @file cplcy.h\n *\n * @brief Camera policy.\n *\n * @todo Either move the camera policy structs from cm.h here, or delete this header.\n */\n#ifndef CPLCY_H\n#define CPLCY_H\n\n#include \"common.h\"\n#include <cm.h>\n\nvoid PushCplookLookk(CPLOOK *pcplook, LOOKK lookk);\n\nLOOKK LookkPopCplook(CPLOOK *pcplook);\n\nLOOKK LookkCurCplook(CPLOOK *pcplook);\n\n#endif // CPLCY_H\n"
  },
  {
    "path": "include/credit.h",
    "content": "/**\n * @file credit.h\n *\n * @brief Credit UI blot.\n */\n#ifndef CREDIT_H\n#define CREDIT_H\n\n#include \"common.h\"\n\n// ...\n\n#endif // CREDIT_H\n"
  },
  {
    "path": "include/crout.h",
    "content": "/**\n * @file crout.h\n */\n#ifndef CROUT_H\n#define CROUT_H\n\n#include \"common.h\"\n\n// ...\n\n#endif // CROUT_H\n"
  },
  {
    "path": "include/crusher.h",
    "content": "/**\n * @file crusher.h\n */\n#ifndef CRUSHER_H\n#define CRUSHER_H\n\n#include \"common.h\"\n#include <stepguard.h>\n#include <vec.h>\n\n// Forward.\nstruct WKR;\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct CRFOD : public STEPGUARD\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct CRFODB : public STEPGUARD\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct CRFODK : public CRFOD\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct CRBRAIN : public ALO\n{\n    // ...\n};\n\nvoid OnCrfodAdd(CRFOD *pcrfod);\n\nvoid OnCrfodRemove(CRFOD *pcrfod);\n\nvoid CloneCrfod(CRFOD *pcrfod, CRFOD *pcrfodBase);\n\nvoid InitCrfodb(CRFODB *pcrfodb);\n\nvoid CalcHeadingVector(float rad, VECTOR *pvector);\n\nvoid UpdateCrfodbGoal(CRFODB *pcrfodb, int fEnter);\n\nint FDetectCrfodb(CRFODB *pcrfodb);\n\nint FAbsorbCrfodbWkr(CRFODB *pcrfodb, WKR *pwkr);\n\nSGS SgsNextCrfodkAI(CRFODK *pcrfodk);\n\nint FDetectCrfodk(CRFODK *pcrfodk);\n\nint FAbsorbCrfodkWkr(CRFODK *pcrfodk, WKR *pwkr);\n\nvoid InitCrbrain(CRBRAIN *pcrbrain);\n\n// TODO: Add unknown functions here.\n\n#endif // CRUSHER_H\n"
  },
  {
    "path": "include/crv.h",
    "content": "/**\n * @file crv.h\n */\n#ifndef CRV_H\n#define CRV_H\n\n#include \"common.h\"\n#include <vec.h>\n\n/**\n * @brief (?) kind.\n */\nenum CRVK\n{\n    CRVK_Nil = -1,\n    CRVK_Linear = 0,\n    CRVK_Cubic = 1,\n    CRVK_Max = 2\n};\n\n/**\n * @brief Unknown.\n */\nstruct CRV\n{\n    undefined4 unknown;\n    CRVK crvk;\n    int fClosed;\n    int ccv;\n    float *mpicvu;\n    float *mpicvs;\n    VECTOR *mpicvpos;\n};\n\n// ...\n\n#endif // CRV_H\n"
  },
  {
    "path": "include/dart.h",
    "content": "/**\n * @file dart.h\n *\n * @brief Dartgun projectiles.\n */\n#ifndef DART_H\n#define DART_H\n\n#include \"common.h\"\n#include <bis.h>\n#include <mq.h>\n#include <so.h>\n#include <po.h>\n\n// Forward.\nstruct EXPL;\nstruct DARTGUN;\n\n/**\n * @brief Dart State.\n */\nenum DARTS\n{\n    DARTS_Nil = -1,\n    DARTS_AvailToFire = 0,\n    DARTS_ReadyToFire = 1,\n    DARTS_Airborne = 2,\n    DARTS_Sticking = 3,\n    DARTS_Stuck = 4,\n    DARTS_Fading = 5,\n    DARTS_Max = 6\n};\n\n/**\n * @class DART\n * @brief Projectile for dartguns.\n */\nstruct DART : public SO\n{\n    /* 0x550 */ DARTS darts;\n    /* 0x554 */ float tDarts;\n    /* 0x558 */ float svDart;\n    /* 0x55c */ float sRadiusFireCloud;\n    /* 0x560 */ float sRadiusStrikeCloud;\n    /* 0x564 */ float dtFade;\n    /* 0x568 */ float dtMaxStuck;\n    /* 0x56c */ DLE dleDartFree;\n    /* 0x574 */ ASEG *pasegSticking;\n    /* 0x578 */ ASEGA *pasegaSticking;\n    /* 0x57c */ ALO *paloTarget;\n    /* 0x580 */ float dtLaunchToTarget;\n    /* 0x584 */ float dzTarget;\n    /* 0x588 */ DARTGUN *pdartgunFiredFrom;\n    /* 0x58c */ EXPL *pexpl;\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct. Move elsewhere?\n */\nstruct HBSK\n{\n    // ...\n};\n\nvoid InitDart(DART *pdart);\n\nvoid OnDartAdd(DART *pdart);\n\nvoid RemoveDart(DART *pdart);\n\nvoid CloneDart(DART *pdart, DART *pdartBase);\n\nvoid LoadDartFromBrx(DART *pdart, CBinaryInputStream *pbis);\n\nvoid HandleDartMessage(DART *pdart, MSGID msgid, void *pv);\n\nvoid PostDartLoad(DART *pdart);\n\nvoid UpdateDart(DART *pdart, float dt);\n\nvoid SetDartDarts(DART *pdart, DARTS darts);\n\nvoid ApplyDartThrow(DART *pdart, PO *ppo);\n\nvoid UpdateDartAirborne(DART *pdart, float dt);\n\n#endif // DART_H\n"
  },
  {
    "path": "include/dartgun.h",
    "content": "/**\n * @file dartgun.h\n */\n#ifndef DARTGUN_H\n#define DARTGUN_H\n\n#include \"common.h\"\n#include <break.h>\n#include <rat.h>\n#include <oid.h>\n#include <so.h>\n#include <mq.h>\n\n/**\n * @class DARTGUN\n * @brief Dart gun used in High Class Heist?\n */\nstruct DARTGUN : public BRK\n{\n    // ...\n    /* 0x744 */ int coidRatTarget;\n    /* 0x748 */ OID aoidRatTarget[8];\n    // ...\n    /* 0x78c */ int cpratInTargetArea;\n    /* 0x790 */ RAT *apratInTargetArea[8];\n    /* 0x7b0 */ int fJtInTargetArea;\n};\n\nvoid InitDartgun(DARTGUN *pdartgun);\n\nvoid HandleDartgunMessage(DARTGUN *pdartgun, MSGID msgid, void *pv);\n\nvoid BindDartgun(DARTGUN *pdartgun);\n\nvoid PostDartgunLoad(DARTGUN *pdartgun);\n\nvoid UpdateDartgun(DARTGUN *pdartgun, float dt);\n\nint FIgnoreDartgunIntersection(DARTGUN *pdartgun, SO *psoOther);\n\nvoid BreakDartgun(DARTGUN *pdartgun);\n\nvoid SetDartgunGoalState(DARTGUN *pdartgun, OID oidStateGoal);\n\nvoid TrackDartgun(DARTGUN *pdartgun, OID *poidStateGoal);\n\nint FPrepareDartgunToFire(DARTGUN *pdartgun);\n\nvoid FireDartgun(DARTGUN *pdartgun);\n\nvoid AgeDartgunStuckDart(DARTGUN *pdartgun);\n\nRAT *PratGetDartgunRatTarget(DARTGUN *pdartgun);\n\nvoid AddDartgunRatTarget(DARTGUN *pdartgun, OID oid);\n\nvoid StartDartgunTargetAreaChange(DARTGUN *pdartgun);\n\nvoid AddDartgunTargetAreaTarget(DARTGUN *pdartgun, ALO *paloTarget);\n\n#endif // DARTGUN_H\n"
  },
  {
    "path": "include/dialog.h",
    "content": "/**\n * @file dialog.h\n *\n * @brief Declarations for the dialog system.\n */\n#ifndef DIALOG_H\n#define DIALOG_H\n\n#include \"common.h\"\n#include <game.h>\n#include <util.h>\n#include <alo.h>\n\n// Forward.\nstruct SPEAKER;\n\ntypedef int GRFDP;\n\n/**\n * @brief Dialog Kind.\n */\nenum DIALOGK\n{\n    DIALOGK_Nil = -1,\n    DIALOGK_Binoc = 0,\n    DIALOGK_Instruct = 1,\n    DIALOGK_Confront = 2,\n    DIALOGK_Max = 3\n};\n\n/**\n * @brief Dialog State.\n */\nenum DIALOGS\n{\n    DIALOGS_Nil = -1,\n    DIALOGS_Enabled = 0,\n    DIALOGS_Triggered = 1,\n    DIALOGS_Disabled = 2,\n    DIALOGS_Playing = 3,\n    DIALOGS_Calling = 4,\n    DIALOGS_UnableToCall = 5,\n    DIALOGS_Max = 6\n};\n\n/**\n * @brief Unknown.\n * @todo Does this belong here?\n */\nenum DPK\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Does this belong here?\n */\nstruct DP\n{\n    /* 0x00 */ GRFDP grfdp;\n    /* 0x04 */ DPK dpk;\n    /* 0x08 */ SPEAKER *pspeakerLeft;\n    /* 0x0c */ SPEAKER *pspeakerRight;\n    /* 0x10 */ ASEGA *pasegaLipsync;\n    // ...\n};\n\n/**\n * @class DIALOG.\n * @brief Dialog line in a cutscene.\n */\nstruct DIALOG : public ALO\n{\n    STRUCT_PADDING(184);\n    /* 0x2d0 */ DIALOGK dialogk;\n    /* 0x2d4 */ DIALOGS dialogs;\n    float tDialogs;\n    /* 0x2dc */ int cde;\n    undefined4 field_0x2f0;\n    int ideCur;\n    /* 0x2e8 */ DP dp;\n    OID oidPntAnchor;\n    /* 0x304 */ int *pfPlayed;\n    int fPlayed;\n    int cpfEquivalence;\n    int *apfEquivalence[4];\n    int fDefault;\n    int fCrucial;\n};\n\n/**\n * @brief Dialog Event Kind.\n */\nenum DEK\n{\n    DEK_Nil = -1,\n    DEK_PreloadVag = 0,\n    DEK_SpeakerLeft = 1,\n    DEK_SpeakerRight = 2,\n    DEK_Talk = 3,\n    DEK_CallSplice = 4,\n    DEK_ShowLetterbox = 5,\n    DEK_HideLetterbox = 6,\n    DEK_ShowMovie = 7,\n    DEK_Max = 8\n};\n\n/**\n * @brief Dialog Event.\n */\nstruct DE\n{\n    DEK dek;\n};\n\n/**\n * @brief Unknown.\n * @todo Determine whether this should be defined elsewhere.\n */\nstruct DIAPI\n{\n    int fCallable;\n    int fPlayable;\n};\n\nvoid InitDialog(DIALOG *pdialog);\n\nvoid LoadDialogFromBrx(DIALOG *pdialog, CBinaryInputStream *pbis);\n\nvoid LoadDialogEventsFromBrx(DIALOG *pdialog, CBinaryInputStream *pbis, int *pcde, DE **pade);\n\nvoid SetDialogInstruct(DIALOG *pdialog);\n\nvoid SetDialogConfront(DIALOG *pdialog);\n\nvoid GetDialogPlayed(DIALOG *pdialog, int *pfPlayed);\n\nvoid SetDialogPlayed(DIALOG *pdialog, int fPlayed);\n\nvoid SetDialogDialogs(DIALOG *pdialog, DIALOGS dialogs);\n\nvoid UpdateDialog(DIALOG *pdialog, float dt);\n\nvoid HandleDialogEvent(DIALOG *pdialog, DE *pde);\n\nvoid HandleDialogMessage(DIALOG *pdialog, MSGID msgid, void *pv);\n\nint FPauseDialog(DIALOG *pdialog);\n\nvoid HandleDialogEvents(DIALOG *pdialog);\n\nvoid FUN_00151860(DIALOG *pdialog, BLOT *pblot);\n\nvoid TriggerDialog(DIALOG *pdialog);\n\nvoid UntriggerDialog(DIALOG *pdialog);\n\nextern DIALOG *g_pdialogCalling; // Dialog currently being called\n\nextern DIALOG *g_pdialogPlaying;\n\n#endif // DIALOG_H\n"
  },
  {
    "path": "include/difficulty.h",
    "content": "/**\n * @file difficulty.h\n *\n * @brief Dynamic difficulty system.\n */\n#ifndef DIFFICULTY_H\n#define DIFFICULTY_H\n\n#include \"common.h\"\n#include <util.h>\n#include <ensure.h>\n#include <chkpnt.h>\n#include <sw.h>\n\n/**\n * @brief Difficulty prize state.\n */\nenum DPS\n{\n    DPS_Normal = 0,\n    DPS_GivenCharms = 1,\n    DPS_Max = 2\n};\n\n/**\n * @brief Values for a particular difficulty level.\n */\nstruct DIFFICULTYLEVEL\n{\n    struct LM suck_lm; // Clamp the suck to this limit\n    LM unk_lm_0x8;\n    float field4_0xc;\n    float duSuckDeath;\n    float duSuckChkpntTrigger;   // Suck gain from triggering a checkpoint for the first time\n    float duSuckChkpntRetrigger; // Suck gain from retriggering a checkpoint subsequent times\n    float rand_low;\n    float field10_0x20;\n    float field11_0x24;\n    float field12_0x28;\n    float uSuckCharmLow;  // Suck threshold to get a low noob charm\n    int ccharmLow;        // Low noob charm count\n    float uSuckCharmHigh; // Suck threshold to get a high noob charm\n    int ccharmHigh;       // High noob charm count\n    float field17_0x3c;\n    float field18_0x40;\n    float field19_0x44;\n    float field20_0x48;\n    int field21_0x4c;\n    float field22_0x50;\n};\n\n/**\n * @brief Maintains the current difficulty level.\n */\nstruct DIFFICULTY\n{\n    LM *unk_lm;\n    int ccoinRichMin;\n    int ccoinRichMax;\n    int ccoinPoorMin;\n    int ccoinPoorMax;\n    int uRichLow;\n    int uRichHigh;\n    DIFFICULTYLEVEL *pDifficultyLevel;\n    enum DPS dps;\n};\n\n/**\n * @brief Unknown, more research needed.\n *\n * @param psw Pointer to the SW struct.\n * @param ensk Ensure kind?\n * @param param3 Unknown.\n */\nDIFFICULTY *PdifficultyEnsureSw(SW *psw, ENSK ensk, undefined4 param3);\n\n/**\n * @brief Clears the difficulty struct.\n *\n * @param pdifficulty Pointer to the difficulty.\n */\nvoid OnDifficultyGameLoad(DIFFICULTY *pdifficulty);\n\n/**\n * @brief Sets up the difficulty system before a level load.\n *\n * Sets the difficulty value based on the current level.\n *\n * @param pdifficulty Pointer to the difficulty.\n */\nvoid OnDifficultyWorldPreLoad(DIFFICULTY *pdifficulty);\n\n/**\n * @brief Sets up the difficulty system after a level load.\n *\n * Gives the player suck charms if they are below the threshold.\n *\n * @param pdifficulty Pointer to the difficulty.\n */\nvoid OnDifficultyWorldPostLoad(DIFFICULTY *pdifficulty);\n\n/**\n * @brief Stubbed, does nothing.\n *\n * @param pdifficulty Pointer to the difficulty.\n */\nvoid OnDifficultyInitialTeleport(DIFFICULTY *pdifficulty);\n\n/**\n * @brief Updates suck values for player death.\n *\n * Increases the player's suck value, accounting for a game over.\n *\n * @param scalar The amount to increase the suck value by.\n * @param pdifficulty Pointer to the difficulty.\n */\nvoid OnDifficultyPlayerDeath(float scalar, struct DIFFICULTY *pdifficulty);\n\n/**\n * @brief Updates suck values for a checkpoint.\n *\n * Decreases the suck value based on the difficulty level.\n *\n * @param pdifficulty Pointer to the difficulty.\n * @param pchkpnt Pointer to the checkpoint.\n */\nvoid OnDifficultyTriggerCheckpoint(DIFFICULTY *pdifficulty, struct CHKPNT *pchkpnt);\n\n/**\n * @brief Updates suck values for collecting a key.\n *\n * Resets the suck values.\n *\n * @param pdifficulty Pointer to the difficulty.\n */\nvoid OnDifficultyCollectKey(DIFFICULTY *pdifficulty);\n\n/**\n * @brief Updates suck values for breaking an object.\n *\n * @param pdifficulty Pointer to the difficulty.\n * @param ppos Pointer to the position of the breakable.\n * @param ccoin The number of coins. (?)\n */\nvoid OnDifficultyBreak(DIFFICULTY *pdifficulty, struct VECTOR *ppos, int ccoin);\n\n/**\n * @brief Changes the suck value by the given amount.\n *\n * Clamps the suck between the min and max values for the given difficulty.\n *\n * @param nParam The amount to change the suck value by.\n * @param pdifficulty Pointer to the difficulty.\n */\nvoid ChangeSuck(float nParam, struct DIFFICULTY *pdifficulty);\n\n// void ResetSuckChkpnts(int nParam);\n// void SetSuckChkpnts(int nParam);\n\n/**\n * @brief Stubbed function.\n */\nvoid OnDifficultyInitialTeleport();\n\n// Current difficulty struct\nextern struct DIFFICULTY g_difficulty;\n\n// Each of three difficulty levels\nextern struct DIFFICULTYLEVEL g_difficultyEasy;\nextern struct DIFFICULTYLEVEL g_difficultyMedium;\nextern struct DIFFICULTYLEVEL g_difficultyHard;\n\n#endif // DIFFICULTY_H\n"
  },
  {
    "path": "include/dl.h",
    "content": "/**\n * @file dl.h\n *\n * @brief Doubly-linked list.\n */\n#ifndef DL_H\n#define DL_H\n\n#include \"common.h\"\n#include <oid.h>\n\n/**\n * @brief Doubly Linked list\n */\nstruct DL\n{\n    void *head;\n    void *tail;\n    int ibDle;\n};\n\n/**\n * @brief Doubly Linked list Element\n *\n * @param next Points to the next element in the chain.\n * @param prev Points to the previous element in the chain.\n */\nstruct DLE\n{\n    void *next;\n    void *prev;\n};\n\n/**\n * @brief Doubly Linked-list Iterator. Used to iterate through DLs in the global list (Singly Linked-list).\n * \n * @param m_pdl The actual doubly linked list the iterator is navigating.\n * @param m_ppv A pointer to the current element/node inside that list.\n * @param m_ibDle Offset the the DLE structure.\n * @param m_pdliNext Next DLI in the chain.\n */\nstruct DLI\n{\n    DL *m_pdl;\n    void **m_ppv;\n    int m_ibDle;\n    DLI *m_pdliNext;\n};\n\n/**\n * @brief Unknown.\n */\nstruct DLIM\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct DLR\n{\n    OID oidChild;\n    DLR *pdlrNext;\n};\n\n/**\n * @brief Initialize a doubly linked list.\n *\n * @param pdl Pointer to the doubly linked list.\n * @param ibDle Offset to the DLE structure within the list element.\n */\nvoid InitDl(DL *pdl, int ibDle);\n\n/**\n * @brief Clear a doubly linked list.\n *\n * @param pdl Pointer to the doubly linked list.\n */\nvoid ClearDl(DL *pdl);\n\n/**\n * @brief Clear a doubly linked list element.\n *\n * @param pdle Pointer to the doubly linked list element.\n */\nvoid ClearDle(DLE *pdle);\n\n/**\n * @brief Get the DLE structure from a list element.\n *\n * @param pdl Pointer to the doubly linked list.\n * @param pv Pointer to the list element.\n * @return Pointer to the DLE structure.\n */\nDLE *PdleFromDlEntry(DL *pdl, void *pv);\n\n/**\n * @brief Append an element to the end of the doubly linked list.\n *\n * @param pdl Pointer to the doubly linked list.\n * @param pv Pointer to the list element.\n */\nvoid AppendDlEntry(DL *pdl, void *pv);\n\n/**\n * @brief Prepend an element to the beginning of the doubly linked list.\n *\n * @param pdl Pointer to the doubly linked list.\n * @param pv Pointer to the list element.\n */\nvoid PrependDlEntry(DL *pdl, void *pv);\n\n/**\n * @brief Insert an element before a specified element in the doubly linked list.\n *\n * @param pdl Pointer to the doubly linked list.\n * @param pvNext Pointer to the element before which the new element will be inserted.\n * @param pv Pointer to the new list element.\n */\nvoid InsertDlEntryBefore(DL *pdl, void *pvNext, void *pv);\n\n/**\n * @brief Remove an element from the doubly linked list and manage the doubly linked list iterator, incase the element being removed is a current iterator for an DLI instance.\n *\n * @param pdl Doubly linked list to remove the element from.\n * @param pv Element to remove.\n */\nvoid RemoveDlEntry(DL *pdl, void *pv);\n\n/**\n * @brief Determine if a list element is in the doubly linked list.\n *\n * @param pdl Doubly linked list to search.\n * @param pv List element to search for.\n * @return true if the element is in the list, false otherwise.\n */\nbool FFindDlEntry(DL *pdl, void *pv);\n\n/**\n * @brief Check if the doubly linked list is empty.\n *\n * @param pdl Pointer to the doubly linked list.\n * @return true if the list is empty, false otherwise.\n */\nbool FIsDlEmpty(DL *pdl);\n\n/**\n * @brief Merge two doubly linked lists.\n *\n * @param pdlDst Destination doubly linked list.\n * @param pdlSrc Source doubly linked list.\n */\nvoid MergeDl(DL *pdlDst, DL *pdlSrc);\n\n/**\n * @brief Traverse a doubly linked list starting from the head and count the number of elements.\n *\n * @param pdl Pointer to the doubly linked list.\n * @return The number of elements in the doubly linked list.\n */\nint CPvDl(DL *pdl);\n\n#endif // DL_H\n"
  },
  {
    "path": "include/dmas.h",
    "content": "/**\n * @file dmas.h\n *\n * @brief Direct memory access.\n */\n#ifndef DMAS_H\n#define DMAS_H\n\n#include \"common.h\"\n#include <sce/libdma.h>\n#include <sdk/ee/eekernel.h>\n#include <vec.h>\n\nextern sceDmaChan *g_pdcVif0;\nextern sceDmaChan *g_pdcVif1;\nextern sceDmaChan *g_pdcGif;\nextern sceDmaChan *g_pdcFromSpr;\nextern sceDmaChan *g_pdcToSpr;\n\n/**\n * @brief Union for 16-byte aligned data.\n */\nunion QW\n{\n    VECTOR vec;\n    VECTOR4 vec4;\n    ulong ull;\n    ulong aul[2];\n    uint aun[4];\n    ushort aus[8];\n    uchar ab[16];\n    long ll;\n    long al[2];\n    int an[4];\n    short as[8];\n    float ag[4];\n};\n\nclass DMAS\n{\npublic:\n    /* 0x00 */ uchar* m_pbMax;\n    /* 0x04 */ uchar* m_ab;\n    /* 0x08 */ QW* m_pqwCnt;\n    /* 0x0c */ uchar* m_pb;\n    /* 0x10 */ int m_fPad;\n    /* 0x14 */ int m_fEndPrim;\n\n    DMAS();\n\n    void Clear();\n    void Reset();\n    void AllocGlobal(int);\n    void AllocSw(int, int);\n    void AllocStack(int);\n    void AllocStatic(int, QW *);\n    void Detach(int *, QW **);\n    void DetachCopySw(int *, QW **, QW *, int);\n    void Send(sceDmaChan *chan);\n    void AddDmaCnt();\n    void AddDmaRefs(int cqw, QW *aqw);\n    void AddDmaCall(QW *);\n    void AddDmaRet();\n    void AddDmaBulk(int, QW *);\n    void AddDmaEnd();\n    void EndDmaCnt();\n\n    virtual void EndPrim();\n};\n\nvoid StartupDma();\n\ninline void AddDmaInt(DMAS *pdmas, int val)\n{\n    uchar *p = pdmas->m_pb;\n    pdmas->m_pb = p + 4;\n    *(int *)p = val;\n}\n\n#endif // DMAS_H\n"
  },
  {
    "path": "include/dysh.h",
    "content": "/**\n * @file dysh.h\n *\n * @brief Dynamic shadow(?)\n */\n#ifndef DYSH_H\n#define DYSH_H\n\n#include \"common.h\"\n#include <shadow.h>\n#include <flash.h>\n#include <mat.h>\n#include <cm.h>\n\n// Forward.\nstruct RPL;\n\n/**\n * @class DYNAMIC_SHADOW\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct DYSH\n{\n\t// ...\n};\n\nvoid InitDysh(DYSH *pdysh);\n\nvoid SetDyshShadow(DYSH *pdysh, SHADOW *pshadow);\n\nvoid RenderDyshSelf(DYSH *pdysh, CM *pcm, RO *pro);\n\nvoid DrawDysh(RPL *prpl);\n\nextern MATRIX4 s_matUvToClip;\n\n#endif // DYSH_H\n"
  },
  {
    "path": "include/dzg.h",
    "content": "/**\n * @file dzg.h\n */\n#ifndef DZG_H\n#define DZG_H\n\n#include \"common.h\"\n#include <so.h>\n#include <dl.h>\n\n// Forward.\nstruct XP;\n\ntypedef int GRFSG;\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct DZ\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct DZG\n{\n    int cdzMax;\n    int cdz;\n    DZ *adz;\n    DL dlPos;\n    DL dlZero;\n    DL dlMax;\n    DL dlUncat;\n    int cdzPos;\n    float *aagPos;\n    float *aagPosCrout;\n    float *asdv;\n    float *adsfPos;\n};\n\nvoid InitDzg(DZG *pdzg, int cpxp);\n\nvoid ClearDzgSolution(DZG *pdzg);\n\nvoid AppendDzgDz(DZG *pdzg, DZ *pdzOther);\n\nvoid FillDzgDz(DZG *pdzg, GRFSG grfsg, DZ *pdzForce, int cpxp, XP **apxp, int *acpso, SO ***aapso);\n\nvoid EnforceDzgDz(DZG *pdzg, DZ *pdzAdd);\n\nvoid SolveDzg(DZG *pdzg, GRFSG grfsg, int cpxp, XP **apxp, int *acpso, SO ***aapso);\n\nvoid SolveDzgFric(DZG *pdzg, GRFSG grfsg, int cpxp, XP **apxp, int *acpso, SO ***aapso, float dt);\n\nvoid ApplyDzg(DZG *pdzg, int cpsoRoot, int *acpso, SO ***aapso, float sdvMax, float sdwMax);\n\nvoid SolveInequalities(int c, float *aag, float *ag, float *agSoln);\n\n#endif // DZG_H\n"
  },
  {
    "path": "include/emitter.h",
    "content": "/**\n * @file emitter.h\n *\n * @brief Particle emitter.\n */\n#ifndef EMITTER_H\n#define EMITTER_H\n\n#include \"common.h\"\n#include <ensure.h>\n#include <xform.h>\n#include <rip.h>\n#include <alo.h>\n\n// Forward.\nstruct EXPL;\n\ntypedef int GRFEXPLSO;\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct EMITMESH\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct EMITBLIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct EMITGEN\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct EMITRIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct EMITDV\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct EMITV\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct EMITVX\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct EMITO\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct EMITB\n{\n    /* 0x00 */ int cref;\n    /* 0x04 */ STRUCT_PADDING(3);\n    /* 0x10 */ EMITO emito;\n    // ...\n};\n\n/**\n * @brief Emitter group?\n * @todo Implement the struct.\n */\nstruct EMITG\n{\n    // ...\n};\n\n/**\n * @brief Particle emitter.\n * @todo Implement the struct.\n */\nstruct EMITTER : public ALO\n{\n    // ...\n    /* 0x308 */ int fAutoPause;\n    /* 0x30c */ STRUCT_PADDING(13);\n    /* 0x340 */ float tUnpause;\n    /* 0x344 */ STRUCT_PADDING(2);\n    /* 0x34c */ int fValuesChanged;\n    // ...\n};\n\nvoid InitEmitb(EMITB *pemitb);\n\nvoid InitEmitter(EMITTER *pemitter);\n\nvoid LoadEmitmeshFromBrx(EMITMESH *pemitmesh, CBinaryInputStream *pbis);\n\nvoid LoadEmitblipColorsFromBrx(EMITBLIP *pemitblip, int crgba, LO *ploEmit, CBinaryInputStream *pbis);\n\nvoid LoadEmitterFromBrx(EMITTER *pemitter, CBinaryInputStream *pbis);\n\nvoid CloneEmitter(EMITTER *pemitter, EMITTER *pemitterBase);\n\nvoid BindEmitterCallback(EMITTER *pemitter, MSGID msgid, void *pvData);\n\nvoid BindEmitter(EMITTER *pemitter);\n\nvoid PostEmitterLoad(EMITTER *pemitter);\n\nvoid HandleEmitterMessage(EMITTER *pemitter, MSGID msgid, void *pv);\n\nvoid RenderEmitterSelf(EMITTER *pemitter, CM *pcm, RO *pro);\n\nEMITB *PemitbCopyOnWrite(EMITB *pemitb);\n\nEMITB *PemitbEnsureEmitter(EMITTER *pemitter, ENSK ensk);\n\nEMITTER *PemitterEnsureEmitter(EMITTER *pemitter, ENSK ensk);\n\nvoid AddEmitterSkeleton(EMITTER *pemitter, OID oid, OID oidOther, float sRadius, float gDensity, float sRadiusOther, float gDensityOther);\n\nvoid ModifyEmitterParticles(EMITTER *pemitter);\n\nvoid UpdateEmitter(EMITTER *pemitter, float dt);\n\nvoid PauseEmitter(EMITTER *pemitter, float dtPause);\n\nvoid PauseEmitterIndefinite(EMITTER *pemitter);\n\nvoid UnpauseEmitter(EMITTER *pemitter);\n\nint FPausedEmitter(EMITTER *pemitter);\n\nvoid SetEmitterEnabled(EMITTER *pemitter, int fEnabled);\n\nvoid GetEmitterEnabled(EMITTER *pemitter, int *pfEnabled);\n\nvoid GetEmitterPaused(EMITTER *pemitter, int *pfPaused);\n\nvoid OnEmitterValuesChanged(EMITTER *pemitter);\n\nvoid SetEmitterParticleCount(EMITTER *pemitter, int cParticle);\n\nvoid SetEmitterAutoPause(EMITTER *pemitter, int fAutoPause);\n\nvoid SetEmitbRipt(EMITB *pemitb, RIPT ript);\n\nvoid SetEmitterRipt(EMITTER *pemitter, RIPT ript);\n\nvoid SetExploRipt(EXPLO *pexplo, RIPT ript);\n\nvoid WakeSoWater(SO *pso, WATER *pwater, float dt, VECTOR *pvCurrent, VECTOR *pposSurface, float dtWakeMin, float gScale);\n\nvoid StandardSmokeCloud(VECTOR *ppos, float sRadius);\n\nvoid ChooseEmitoPos(EMITO *pemito, int iParticle, int cParticle, VECTOR *pposRet, VECTOR *pnormalRet);\n\nvoid ConvertEmitoPosVec(EMITO *pemito, VECTOR *ppos, VECTOR *pv);\n\nvoid CalculateEmitvx(int cParticlePerRing, LM *plmTilt, int cParticle, EMITVX *pemitvx);\n\nvoid ChooseEmitVelocity(EMITVX *pemitvx, float uRandom, float rSvz, LM *plmSv, VECTOR *pvecNormal, int iParticle, VECTOR *pv);\n\nvoid ChooseEmitvVelocityAge(EMITV *pemitv, EMITVX *pemitvx, EMITO *pemito, int iParticle, VECTOR *ppos, VECTOR *pnormal, VECTOR *pv, float *ptCreated, float *ptDestroy);\n\nvoid EmitRips(EMITB *pemitb, EMITG *pemitg, int crip, VECTOR *apos, VECTOR *av, float *atCreated, float *atDestroy);\n\nvoid EmitBlips(EMITB *pemitb, EMITG *pemitg, int cblipeRequested, VECTOR *apos, VECTOR *av, float *atCreated, float *atDestroy, VECTOR *aposFinal, VECTOR *avFinal);\n\nvoid OriginateParticles(int cParticle, EMITB *pemitb, EMITGEN *pemitgen);\n\nvoid OriginateSplineSinkParticles(int cParticle, EMITB *pemitb, EMITGEN *emitgen, EMITGEN *emitgenTarget);\n\nvoid EmitParticles(int cParticle, EMITB *pemitb, EMITG *pemitg);\n\nvoid EmitRipsSphere(VECTOR *ppos, VECTOR *pnormal, int crip, EMITRIP *pemitrip, EMITV *pemitv, RIPG **ppripg, LO *ploSubscribe);\n\nvoid StockSplashBig(VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid StockSplashSmall(VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid AddEmitoSkeleton(EMITO *pemito, OID oid, OID oidOther, float sRadius, float gDensity, float sRadiusOther, float gDensityOther, LO *ploContext);\n\nvoid BindEmitb(EMITB *pemitb, LO *ploContext);\n\nvoid SetEmitdvEmitb(EMITDV *pemitdv, EMITB *pemitb);\n\nvoid CalculateEmitdvMatrix(EMITDV *pemitdv, float dt, MATRIX4 *pmat4Dv);\n\nvoid PostExplLoad(EXPL *pexpl);\n\nvoid CalculateExplTransform(EXPL *pexpl, VECTOR *pposLocal, MATRIX3 *pmatLocal);\n\nvoid ExplodeExpl(EXPL *pexpl);\n\nvoid ExplodeExplParams(EXPL *pexpl, GRFEXPLSO grfexplso, ALO *paloReference, VECTOR *pvec, VECTOR *pposOrigin, float rScale, float sRadius);\n\nvoid ExplodeExplExplso(EXPL *pexpl, EXPLSO *pexplso);\n\nvoid LoadExplgFromBrx(EXPLG *pexplg, CBinaryInputStream *pbis);\n\nvoid CloneExplg(EXPLG *pexplg, EXPLG *pexplgBase);\n\nvoid BindExplg(EXPLG *pexplg);\n\nvoid ExplodeExplgExplso(EXPLG *pexplg, EXPLSO *pexplso);\n\nvoid InitExplo(EXPLO *pexplo);\n\nvoid LoadExploFromBrx(EXPLO *pexplo, CBinaryInputStream *pbis);\n\nvoid CloneExplo(EXPLO *pexplo, EXPLO *pexploBase);\n\nvoid BindExplo(EXPLO *pexplo);\n\nvoid ExplodeExploExplso(EXPLO *pexplo, EXPLSO *pexplso);\n\nvoid AddExploSkeleton(EXPLO *pexplo, OID oid, OID oidOther, float sRadius, float gDensity, float sRadiusOther, float gDensityOther);\n\nEMITB *PemitbEnsureExplo(EXPLO *pexplo, ENSK ensk);\n\nvoid InitExpls(EXPLS *pexpls);\n\nvoid BindExpls(EXPLS *pexpls);\n\nvoid HandleExplsMessage(EXPLS *pexpls, MSGID msgid, void *pv);\n\nvoid ExplodeExplsExplso(EXPLS *pexpls, EXPLSO *pexplso);\n\nSFX *PsfxEnsureExpls(EXPLS *pexpls, ENSK ensk);\n\nvoid FireExplsExplso(EXPLS *pexpls, EXPLSO *pexplso);\n\nvoid InferExpl(EXPL **ppexpl, ALO *palo);\n\nvoid FireSwTimedExplodeStyles(SW *psw);\n\n#endif // EMITTER_H\n"
  },
  {
    "path": "include/ensure.h",
    "content": "/**\n * @file ensure.h\n *\n * @brief Dynamic difficulty system.\n *\n * @todo Possibly merge this into another header, if appropriate.\n */\n#ifndef ENSURE_H\n#define ENSURE_H\n\n/**\n * @brief Ensure kind. Further research needed.\n */\nenum ENSK\n{\n    ENSK_Get,\n    ENSK_Set\n};\n\n#endif // ENSURE_H\n"
  },
  {
    "path": "include/eyes.h",
    "content": "/**\n * @file eyes.h\n */\n#ifndef EYES_H\n#define EYES_H\n\n#include \"common.h\"\n#include <shd.h>\n\n/**\n * @brief Eyes state.\n */\nenum EYESS\n{\n    EYESS_Nil = -1,\n    EYESS_Open = 0,\n    EYESS_Closing = 1,\n    EYESS_Closed = 2,\n    EYESS_Opening = 3,\n    EYESS_Max = 4\n};\n\n/**\n * @brief Eyes.\n */\nstruct EYES : public SAA\n{\n    // ...\n};\n\nvoid InitEyes(EYES *peyes, SAAF *psaaf);\n\nvoid PostEyesLoad(EYES *peyes);\n\nvoid SetEyesEyess(EYES *peyes, EYESS eyess);\n\nvoid UpdateEyes(EYES *peyes, float dt);\n\nvoid SetEyesClosed(EYES *peyes, float uClosed);\n\nSAI *PsaiFromEyesShd(EYES *peyes, SHD *pshd);\n\n#endif // EYES_H\n"
  },
  {
    "path": "include/fader.h",
    "content": "/**\n * @file fader.h\n */\n#ifndef FADER_H\n#define FADER_H\n\n#include \"common.h\"\n#include <alo.h>\n\n/**\n * @todo Implement the struct.\n */\nstruct FADER\n{\n    // ...\n};\n\n/**\n * @brief Update the fader.\n */\nvoid UpdateFader(FADER *pfader, float dt);\n\n/**\n * @brief Create a new fader.\n */\nFADER *PfaderNew(ALO *palo);\n\n/**\n * @brief Remove the fader.\n */\nvoid RemoveFader(FADER *pfader);\n\n#endif // FADER_H\n"
  },
  {
    "path": "include/find.h",
    "content": "/**\n * @file find.h\n *\n * @brief Find objects in the SW.\n */\n#ifndef FIND_H\n#define FIND_H\n\n#include \"common.h\"\n#include <alo.h>\n#include <sw.h>\n#include <cid.h>\n#include <so.h>\n\n/**\n * @brief Gets the DL for the SW object with the given OID.\n *\n * @param psw The SW object.\n * @param oid The OID of the object.\n *\n * @return The DL for the object, or NULL if the object was not found.\n */\nDL *PdlFromSwOid(SW *psw, OID oid);\n\nvoid MatchSwObject(LO *ploMatch, int grffsoMask, int fIncludeRemoved, int fProxyMatch, LO *ploContext, int cploMax, int *pcploMatch, LO **aplo, int *pcpaloBest);\n\nint CploFindSwObjects(SW *psw, GRFFSO grffso, OID oid, LO *ploContext, int cploMax, LO **aplo);\n\nLO *PloFindSwObject(SW *psw, GRFFSO grffso, OID oid, LO *ploContext);\n\n/**\n * @brief Finds the nearest SW object with the given OID from the context LO.\n *\n * @param psw The SW object.\n * @param oid The OID of the object to find.\n * @param ploContext The LO to search from.\n *\n * @return The nearest LO with the given OID, or NULL if no such object was found.\n */\nLO *PloFindSwNearest(SW *psw, OID oid, LO *ploContext);\n\n/**\n * @brief Finds a child SW object with the given OID under the specified ancestor ALO.\n *\n * @param psw The SW object.\n * @param oid The OID of the child object to find.\n * @param paloAncestor The ancestor ALO under which to search for the child.\n *\n * @return The found child LO, or NULL if no such child was found.\n */\nLO *PloFindSwChild(SW *psw, OID oid, ALO *paloAncestor);\n\n/**\n * @brief Checks if the given CID is derived from another.\n *\n * @param cid The CID to check.\n * @param cidAncestor The CID to check against.\n *\n * @retval 1 if the CID is derived from the ancestor.\n * @retval 0 if the CID is not derived from the ancestor.\n */\nint FIsCidDerivedFrom(int cid, int cidAncestor);\n\nint CploFindSwObjectsByClass(SW *psw, GRFFSO grffso, CID cid, LO *ploContext, int cploMax, LO **aplo);\n\nLO *PloFindSwObjectByClass(SW *psw, GRFFSO grffso, CID cid, LO *ploContext);\n\n/**\n * @brief Finds the common parent of two LOs.\n *\n * @param plo The first LO.\n * @param ploOther The second LO.\n *\n * @return The common parent of the two LOs.\n */\nALO *PaloFindLoCommonParent(LO *plo, LO *ploOther);\n\nextern void** g_mpcidpvt;\n\n#endif // FIND_H\n"
  },
  {
    "path": "include/flash.h",
    "content": "/**\n * @file flash.h\n *\n * @brief Flash (might be flash animation, or literal screen flashes).\n */\n#ifndef FLASH_H\n#define FLASH_H\n\n#include \"common.h\"\n#include <mat.h>\n#include <sm.h>\n#include <cm.h>\n\n/**\n * @brief Unknown (render options?).\n */\nstruct RO\n{\n    MATRIX4 mat;\n    float uAlpha;\n    float uAlphaCelBorder;\n    undefined4 unk0;\n    undefined4 unk1;\n};\n\n/**\n * @class FLASHLIGHT\n * @brief Flashlight guard's flashlight (maybe reused for spotlights?).\n */\nstruct FLASH : public ALO\n{\n    /* 0x2d0 */ int ctsurf;\n    /* 0x2d4 */ TSURF *atsurf;\n    /* 0x2d8 */ int ctbsp;\n    /* 0x2dc */ TBSP *atbsp;\n    /* 0x2e0 */ SMP smpScale;\n    /* 0x2ec */ float gScaleCur;\n    /* 0x2f0 */ float gScaleTarget;\n    undefined4 unk0;\n    undefined4 unk1;\n    undefined4 unk2;\n};\n\n/**\n * @brief Initializes the given flashlight.\n *\n * @param pflash Flash to initialize.\n */\nvoid InitFlash(FLASH *pflash);\n\n/**\n * @brief Loads a flashlight from the given binary input stream.\n *\n * @param pflash Where to load the flash.\n * @param pbis Binary input stream.\n */\nvoid LoadFlashFromBrx(FLASH *pflash, CBinaryInputStream *pbis);\n\n/**\n * @brief Updates the given flashlight.\n *\n * @param pflash Flash to update.\n * @param dt Delta time.\n */\nvoid UpdateFlash(FLASH *pflash, float dt);\n\n/**\n * @brief Renders the given flashlight.\n *\n * @param pflash Flash to render.\n * @param pcm Camera to render from.\n * @param pro Render options(?).\n */\nvoid RenderFlashSelf(FLASH *pflash, CM *pcm, RO *pro);\n\nint FPosFlashWithin(FLASH *pflash, VECTOR *ppos);\n\n#endif // FLASH_H\n"
  },
  {
    "path": "include/fly.h",
    "content": "/**\n * @file fly.h\n *\n * @brief Flying animals.\n */\n#ifndef FLY_H\n#define FLY_H\n\n#include \"common.h\"\n#include <target.h>\n#include <flash.h>\n#include <sound.h>\n#include <bis.h>\n#include <vec.h>\n#include <cm.h>\n#include <dl.h>\n#include <so.h>\n\n// Forward.\nstruct WKR;\nstruct SOP;\n\n/**\n * @brief Flying animal kind.\n */\nenum FLYK\n{\n    FLYK_Nil = -1,\n    FLYK_Insect = 0,\n    FLYK_Pigeon = 1,\n    FLYK_Max = 2\n};\n\n/**\n * @brief Flying animal state.\n */\nenum FLYS\n{\n    FLYS_Nil = -1,\n    FLYS_Wander = 0,\n    FLYS_Dying = 1,\n    FLYS_Dead = 2,\n    FLYS_Attract = 3,\n    FLYS_Stuck = 4,\n    FLYS_Land = 5,\n    FLYS_Ground = 6,\n    FLYS_Max = 7\n};\n\n/**\n * @class FLY\n * @brief Flying animal.\n */\nstruct FLY : public SO\n{\n    // ...\n    FLYK flyk;\n    FLYS flys;\n    float tFlys;\n    float tFlysnext;\n    FLYS flysInit;\n    int cpaloRender;\n    int ipaloRender;\n    ALO *apaloRender[16];\n    int cpaloRenderGround;\n    ALO *apaloRenderGround[8];\n    ALO *paloRenderDead;\n    EXPL *pexpl;\n    TARGET *ptarget;\n    DLE dleFly;\n    AMB *pambBuzz;\n    // ...\n};\n\nvoid InitFly(FLY *pfly);\n\nvoid LoadFlyFromBrx(FLY *pfly, CBinaryInputStream *pbis);\n\nvoid CloneFly(FLY *pfly, FLY *pflyBase);\n\nvoid FreezeFly(FLY *pfly, int fFreeze);\n\nvoid PostFlyLoad(FLY *pfly);\n\nvoid PresetFlyAccel(FLY *pfly, float dt);\n\nvoid UpdateFly(FLY *pfly, float dt);\n\nvoid RenderFlySelf(FLY *pfly, CM *pcm, RO *pro);\n\nint FAbsorbFlyWkr(FLY *pfly, WKR *pwkr);\n\nvoid GetFlyParams(FLY *pfly, SOP **ppsop);\n\nvoid SetFlyFlys(FLY *pfly, FLYS flys);\n\nvoid EmitFlyDroppings(FLY *pfly);\n\nint FFindFlyClosestLandingPos(FLY *pfly, VECTOR *ppos);\n\nFLYS FlysAttemptedFlyLanding(FLY *pfly);\n\nint FShouldFlyFlee(FLY *pfly);\n\nint FFilterFly(void *pv, SO *pso);\n\nint FCheckFlyOpenSpaceBelow(FLY *pfly);\n\n#endif // FLY_H\n"
  },
  {
    "path": "include/font.h",
    "content": "/**\n * @file font.h\n *\n * @brief Font system.\n */\n#ifndef FONT_H\n#define FONT_H\n\n#include \"common.h\"\n\n/**\n * @brief Scaled font ratio.\n */\nstruct SFR\n{\n    float rx, ry;\n};\n\nclass CFont\n{\n  public:\n    void CopyTo(CFont *pfontDest);\n\n  protected:\n    int m_dxCharUnscaled;\n    int m_dxSpaceUnscaled;\n    int m_dyUnscaled;\n    int m_csfr;\n    SFR m_asfr[4];\n    int m_fGstest;\n    undefined4 unk_1;\n    ulong m_gstest;\n    uint m_z;\n    float m_rxScale;\n    float m_ryScale;\n};\n\nclass CFontBrx : public CFont\n{\n  private:\n    undefined1 m_padding[0x33];\n};\n\nextern CFont *g_pfont;\n\nclass CRichText\n{\n  public:\n    CRichText(char *achz, CFont *pfont);\n    int Cch();\n    void Reset();\n    void SetBaseColor(RGBA *rgba);\n\n  private:\n    char *m_achz;\n    char *m_pchCur;\n    CFont *m_pfontCur;\n    CFont *m_pfontBase;\n    CFontBrx m_fontOther;\n    undefined4 m_unknown; // todo: figure out what this is\n    RGBA m_rgbaCur;\n    RGBA m_rgbaSet;\n    RGBA m_rgbaBase;\n    RGBA m_rgbaOther;\n};\n\nvoid StartupFont();\n\n#endif // FONT_H\n"
  },
  {
    "path": "include/freeze.h",
    "content": "/**\n * @file freeze.h\n */\n#ifndef FREEZE_H\n#define FREEZE_H\n\n#include \"common.h\"\n#include <alo.h>\n#include <so.h>\n#include <sw.h>\n#include <dl.h>\n\n/**\n * @brief Merge (?)\n * @todo Should this be defined elsewhere?\n */\nstruct MRG\n{\n    DLE dle;\n    int cpalo;\n    ALO **apalo;\n};\n\nvoid RemergeSwObject(SW *psw, ALO *palo);\n\nvoid MergeSwFreezeGroups(SW *psw, ALO *paloFreezeGroup1, ALO *paloFreezeGroup2);\n\nvoid SplinterSwFreezeGroup(SW *psw, ALO *paloFreezeRoot);\n\nvoid MergeSwGroup(SW *psw, MRG *pmrg);\n\nvoid AddSwMergeGroup(SW *psw, MRG *pmrg);\n\nvoid RemoveFromArray(int *pcpv, void **apv, void *pv);\n\nvoid RemoveSwMergeGroup(SW *psw, MRG *pmrg);\n\nvoid RemergeSwObjects(SW *psw);\n\nvoid FreezeAloHierarchy(ALO *palo, int fFreeze);\n\nvoid GetAloFrozen(ALO *palo, int *pfFrozen);\n\nvoid FreezeAlo(ALO *palo, int fFreeze);\n\nvoid FreezeSo(SO *pso, int fFreeze);\n\nvoid RefreezeSwObjects(SW *psw);\n\nvoid UpdateSwBusyList(SW *psw);\n\n#endif // FREEZE_H\n"
  },
  {
    "path": "include/frm.h",
    "content": "/**\n * @file frm.h\n *\n * @brief Frame manager.\n */\n#ifndef FRM_H\n#define FRM_H\n\n#include \"common.h\"\n#include <shd.h>\n\n// Forward.\nclass VIFS;\nstruct GIFS;\n\n/**\n * @brief Frame.\n * @todo Add the rest of the fields.\n */\nstruct FRM\n{\n    /* 0x00 */ int cqwGifs;\n    /* 0x04 */ QW *aqwGifs;\n    /* 0x08 */ int cqwVifs;\n    /* 0x0c */ QW *aqwVifs;\n    /* 0x10 */ SLI *asli;\n    /* 0x14 */ int cframe;\n    /* 0x18 */ int grffont;\n    /* 0x1c */ int fBackgroundUploadRequired;\n    STRUCT_PADDING(9);\n    /* 0x44 */ GRFZON grfzon;\n    // ...\n};\n\nvoid StartupFrame();\n\nvoid OpenFrame();\n\nvoid EnsureVu1Code(VIFS *pvifs, void *pvStart, void *pvEnd);\n\nvoid FinalizeFrameVifs(VIFS *pvifs, int *pcqwVifs, QW **ppqwVifs);\n\nvoid FinalizeFrameGifs(GIFS *pgifs, int *pcqwGifs, QW **ppqwGifs);\n\nvoid CloseFrame();\n\nvoid PrepareGsForFrameRender(FRM *pfrm);\n\nvoid FrameRenderLoop(void *);\n\nvoid RenderFrame(FRM *pfrm, int fRenderGifs);\n\nvoid ClearPendingFrame(FRM *pfrm);\n\nvoid FlushFrames(int fFreeze);\n\nvoid BlendPrevFrame();\n\nextern uchar g_abRenderLoopStack[0x20000];\nextern int g_cframe;\n\n#endif // FRM_H\n"
  },
  {
    "path": "include/frzg.h",
    "content": "/**\n * @file frzg.h\n */\n#ifndef FRZG_H\n#define FRZG_H\n\n#include \"common.h\"\n#include <freeze.h>\n#include <oid.h>\n#include <lo.h>\n\n/**\n * @class FREEZE_GROUP\n * @brief Group of freeze objects.\n */\nstruct FRZG : public LO\n{\n    int coid;\n    OID aoid[8];\n    MRG mrg;\n};\n\nvoid PostFrzgLoad(FRZG *pfrzg);\n\nvoid AddFrzgObject(FRZG *pfrzg, OID oid);\n\n#endif // FRZG_H\n"
  },
  {
    "path": "include/game.h",
    "content": "/**\n * @file game.h\n *\n * @brief Game state and level management.\n *\n * @todo Cleanup/update structs and function names/parameters.\n */\n#ifndef GAME_H\n#define GAME_H\n\n#include \"common.h\"\n#include <oid.h>\n#include <cid.h>\n\n/**\n * @brief World ID.\n */\nenum GAMEWORLD\n{\n    GAMEWORLD_Nil = -1,\n    GAMEWORLD_Intro = 0,\n    GAMEWORLD_Underwater = 1,\n    GAMEWORLD_Muggshot = 2,\n    GAMEWORLD_Voodoo = 3,\n    GAMEWORLD_Snow = 4,\n    GAMEWORLD_Clockwerk = 5,\n    GAMEWORLD_Max = 6\n};\n\n/**\n * @brief Level ID.\n */\nenum WORLDLEVEL\n{\n    WORLDLEVEL_Nil = -1,\n    WORLDLEVEL_Approach = 0,\n    WORLDLEVEL_Hub = 1,\n    WORLDLEVEL_Level1 = 2,\n    WORLDLEVEL_Level2 = 3,\n    WORLDLEVEL_Level3 = 4,\n    WORLDLEVEL_Level4 = 5,\n    WORLDLEVEL_Level5 = 6,\n    WORLDLEVEL_Level6 = 7,\n    WORLDLEVEL_Boss = 8,\n    WORLDLEVEL_Max = 9\n};\n\n/**\n * @brief Game state flags.\n */\nenum FGS\n{\n    FGS_FirstClue = 0x1,\n    FGS_HalfClues = 0x2,\n    FGS_AllClues = 0x4,\n    FGS_FirstVault = 0x8,\n    FGS_SecondVault = 0x10\n};\n\n/**\n * @brief World state flags.\n */\nenum FWS\n{\n    FWS_Visited = 0x1,\n    FWS_Lock_0 = 0x2,\n    FWS_Lock_1 = 0x4,\n    FWS_Lock_2 = 0x8,\n    FWS_Lock_3 = 0x10,\n    FWS_Lock_All = 0x1e\n};\n\n/**\n * @brief Level state flags.\n */\nenum FLS\n{\n    FLS_Visited = 0x1,\n    FLS_KeyCollected = 0x2,\n    FLS_Secondary = 0x4,\n    FLS_Tertiary = 0x8,\n    FLS_BossDefeated = 0x10\n};\n\n/**\n * @brief Game state flags integer type.\n */\ntypedef int GRFGS;\n\n/**\n * @brief World state flags integer type.\n */\ntypedef int GRFWS;\n\n/**\n * @brief Level state flags integer type.\n */\ntypedef int GRFLS;\n\n/**\n * @brief Vault powerup flags integer type.\n */\ntypedef int GRFVAULT;\n\n/**\n * @brief Level State.\n */\nstruct LS\n{\n    FLS fls;                // Level state flags\n    float dt;               // Time spent in level (secs)\n    float dtTimedBest;      // Best MTS time for level (secs)\n    float uSuck;            // Current player suck for this level\n    float unk_suck_0x10;    // unknown, seems suck related\n    int afDialogPlayed[12]; // Dialog played flags\n    int sceneVars[2][4];    // Scene variables\n    int cclue;              // Count of clues collected\n    uint fclue;             // Clue collected flags\n    int unk_field_0x6c;     // Unknown\n    int unk_field_0x70;     // Unknown\n    char *unk_field_0x74;   // Unknown\n};\n\n/**\n * @brief World State.\n */\nstruct WS\n{\n    LS als[9];  // Level states array\n    int ckey;   // Count of keys collected in world\n    int cvault; // Count of vaults opened on worls\n    int ctimed; // Count of MTSs completed in world\n    float dt;   // Time spent in world (secs)\n    FWS fws;    // World state flags\n};\n\n/**\n * @brief Game State.\n */\nstruct GS\n{\n    int gsv;                  // not sure why this isn't caled fgs\n    int cbThis;               // Struct size (bytes)\n    int nChecksum;            // Expected size (bytes)\n    float dt;                 // Time spent in game (secs)\n    WS aws[6];                // World states array\n    GAMEWORLD gameworldCur;   // Current world\n    WORLDLEVEL worldlevelCur; // Current level\n    int clife;                // Lives count\n    int ccharm;               // Charm count\n    int ccoin;                // Coin count\n    GRFGS grfgs;              // Game settings flags(?)\n    GRFVAULT grfvault;        // Unlocked powerup flags\n    unsigned int unlocked_cutscenes;\n    unsigned int fgs;\n    int fspLast; // Last selected powerup\n};\n\n/**\n * @brief World ID\n */\nenum WID\n{\n    // Intro\n    WID_stock_objects = 0x0,\n    WID_splash = 0x1,\n    WID_attract = 0x2,\n    WID_jb_intro = 0x3,\n\n    // Underwater\n    WID_uw_exterior_approach = 0x4,\n    WID_uw_exterior_boat = 0x5,\n    WID_uw_bonus_security = 0x6,\n    WID_uw_bonus_drivewheels_final = 0x7,\n    WID_uw_bonus_library = 0x8,\n    WID_uw_t3_final = 0x9,\n    WID_uw_rip_off = 0xa,\n    WID_uw_c2_final = 0xb,\n    WID_uw_boss_blimp = 0xc,\n\n    // Mesa\n    WID_ms_approach = 0xd,\n    WID_ms_casino = 0xe,\n    WID_ms_exterior = 0xf,\n    WID_ms_inspector = 0x10,\n    WID_ms_rooftop = 0x11,\n    WID_ms_vertigo = 0x12,\n    WID_ms_sniper = 0x13,\n    WID_ms_suv = 0x14,\n    WID_ms_boss_battle = 0x15,\n\n    // Voodoo\n    WID_v_approach = 0x16,\n    WID_v_gomerville = 0x17,\n    WID_v_swamp_monster = 0x18,\n    WID_v_hub = 0x19,\n    WID_v_skinterior = 0x1a,\n    WID_v_murray = 0x1b,\n    WID_v_chicken = 0x1c,\n    WID_v_puffer = 0x1d,\n    WID_v_boss = 0x1e,\n\n    // Snow\n    WID_s_approach = 0x1f,\n    WID_s_barrel = 0x20,\n    WID_s_hub = 0x21,\n    WID_s_inspector = 0x22,\n    WID_s_security = 0x23,\n    WID_s_sniper = 0x24,\n    WID_s_suv = 0x25,\n    WID_s_tank = 0x26,\n    WID_s_boss = 0x27,\n\n    // Clockwerk\n    WID_cw_suv = 0x28,\n    WID_cw_turret = 0x29,\n    WID_cw_security = 0x2a,\n    WID_cw_bentley = 0x2b,\n    WID_cw_reverse_sniper = 0x2c,\n    WID_cw_outclimb = 0x2d,\n    WID_cw_finish = 0x2e,\n\n    WID_Max = 0x2f\n};\n\nstruct GAME\n{\n    VTGAME *pvtgame;\n    int cAlarmsTriggered;\n    int fTimedChallenge;\n    float dtChallenge;\n    int cgoldLatest;\n};\n\n/**\n * @brief Used to locate level data by its location on the disc.\n *\n * @todo implement\n */\nstruct LevelLoadData\n{\n    // ...\n};\n\nextern const LevelLoadData *D_00247AB0[];\n\n/**\n * @brief Calls StartGame.\n */\nvoid StartupGame();\n\n// LevelLoadData * search_level_by_load_data(LevelLoadData *search_level);\n\n// LevelLoadData * search_level_by_id(int search_id);\n\n/**\n * @brief Gets the friendly name of a level from its world ID.\n *\n * @param wid World ID.\n */\nchar *PchzFriendlyFromWid(int wid);\n\n// LevelLoadData *call_search_level_by_id(int level_id);\n\n// WORLDLEVEL FFindLevel(LevelLoadData *level)\n\nuint get_level_completion_by_id(int level_id);\n\n/**\n * @brief Tally the completion of a world.\n *\n * @param wid World ID.\n * @param ckey Result of the tally of keys.\n * @param cvault Result of the tally of vaults.\n * @param cmts Result of the tally of Master Thief Sprints\n */\nvoid tally_world_completion(int wid, int *ckey, int *cvault, int *cmts);\n\n/**\n * @brief Get the game completion flags based on the current game state.\n */\nFGS get_game_completion();\n\n/**\n * @brief Unlocks the intro cutscene for a world.\n *\n * @param wid World ID.\n */\nvoid UnlockIntroCutsceneFromWid(int wid);\n\n/**\n * @brief Updates game state upon defeating the boss of a world.\n *\n * Unlocks specific reward cutscenes and powerups based on the world ID.\n *\n * @param wid World ID.\n */\nvoid DefeatBossFromWid(int wid);\n\n/**\n * @brief Unlocks the endgame cutscenes based on the completion flags.\n *\n * E.g. Ten Seconds, Thievius Raccoonus, etc.\n *\n * @param fgs Completion flags.\n */\nvoid UnlockEndgameCutscenesFromFgs(FGS fgs);\n\n/**\n * @brief Plays the ending cutscene based on the completion flags.\n *\n * @param grfgs Completion flags.\n */\nvoid PlayEndingFromCompletionFlags(GRFGS grfgs);\n\n/**\n * @brief Initializes the game state.\n *\n * @param pgs Game state.\n */\nvoid InitGameState(GS *pgs);\n\n/**\n * @brief Unknown function.\n *\n * @param param_1 Unknown parameter.\n */\nint FUN_00160650(int param_1);\n\n// void SetupGame(LevelLoadData *search_data,FTRANS transition_flags);\n\n/**\n * @brief Updates the timers on the game state.\n *\n * @param dt Delta time.\n */\nvoid UpdateGameState(float dt);\n\n/**\n * @brief Gets the level state object from a world ID.\n *\n * @param wid World ID.\n */\nint *LsFromWid(WID wid);\n\n/**\n * @brief Gets the level state flags from a world ID.\n *\n * @param wid World ID.\n */\nGRFLS GrflsFromWid(WID wid);\n\n/**\n * @brief Unloads the game.\n */\nvoid UnloadGame();\n\n/**\n * @brief TBD\n */\nvoid RetryGame();\n\n/**\n * Unloads the game and wipes to the default world warp.\n */\nvoid StartGame();\n\n/**\n * @brief Unknown function.\n */\nint FUN_00160948();\n\n/**\n * @brief Calculates the percentage completion of the game.\n *\n * Tallies up the completion of each world and returns the percentage\n * as an int out of 100.\n *\n * @param pgs Game state.\n */\nint CalculatePercentCompletion(GS *pgs);\n\n/**\n * @brief Sets the number of charms the player has.\n *\n * @param nParam Number of charms.\n */\nvoid SetCcharm(int nParam);\n\n/**\n * @brief Checks if the player has any charms available.\n *\n * Will return true if the ccharm on the g_gs is > 0, of if the\n * infinite charms cheat is enabled.\n */\nbool FCharmAvailable();\n\n/**\n * @brief Unknown function, TBD.\n *\n * @param pls Pointer to level state.\n * @param param_2 OID of the dialog.\n */\n//int PfLookupDialog(LS *pls, OID oidDialog);\n\n/**\n * @brief Clears 8 bytes of memory.\n *\n * Used in UnloadGame and FUN_00160948.\n * Probably used to clear a pointer or something.\n *\n * @param pv Pointer to the memory to clear.\n */\nextern \"C\" void *clr_8_bytes_1(void *pv);\n\n/**\n * @brief Unknown function.\n *\n * @param param_1 Unknown parameter.\n */\nvoid FUN_00160ce8(int param_1);\n\n/**\n * @brief Increases the count of alarms triggered in the given GAME.\n *\n * The count is used as a multiplier for the MTS countdown timer.\n */\nvoid OnGameAlarmTriggered(GAME *pgame);\n\n/**\n * @brief Decreases the count of alarms triggered in the given GAME.\n *\n * The count is used as a multiplier for the MTS countdown timer.\n */\nvoid OnGameAlarmDisabled(GAME *pgame);\n\n/**\n * @brief Unknown function.\n */\nGRFVAULT GetGrfvault_unknown();\n\n/**\n * @brief Gets the blueprint info for a vault.\n *\n * @param pgrfvault Pointer to the vault flags.\n * @param pipdialog Pointer to the dialog flags.\n *\n * @todo Fix parameter types.\n */\nvoid GetBlueprintInfo(int *pgrfvault, int *pipdialog);\n\n/**\n * @brief Returns the max number of charms the player can hold.\n *\n * @note Always returns 2. This is a holdover from earlier in development where\n * there was a powerup that allowed you to have more than 2 charms.\n */\nint CcharmMost();\n\n/**\n * @brief Reloads the game state after the player dies.\n */\nvoid reload_post_death();\n\n// todo these should be somewhere else?\nextern GS g_gsCur;\nextern WS g_wsCur;\nextern LS g_lsCur;\n\nextern GS *g_pgsCur;\nextern WS *g_pwsCur;\nextern LS *g_plsCur;\n\n#ifdef SKIP_ASM\n// For CalculatePercentCompletion\n\n/**\n * @brief Level Info\n *\n * Used by the game to load the level.\n*/\nstruct PchzLevel // maybe wrong name\n{\n    double lsn_and_unk_ciphers;\n    int search_Val;\n    unsigned int unk_0xc;\n    unsigned int unk_0x10;\n    unsigned int unk_0x14;\n    unsigned int unk_0x18;\n    unsigned int for_lsn;\n    int search_cipher;\n    unsigned int for_size;\n    unsigned int level_id;\n    char* level_name;\n    FLS tasks;\n};\n\nextern PchzLevel pchzLevelTable[]; // Level table\n#endif\n\n#endif // GAME_H\n"
  },
  {
    "path": "include/gcc/math.h",
    "content": "/**\n * @file math.h\n *\n * @brief Library math functions.\n */\n#ifndef MATH_H\n#define MATH_H\n\nextern \"C\"\n{\n    float tanf(float x);\n    float atan2f(float x, float y);\n    float fmodf(float x, float y);\n    float cosf(float x);\n}\n\n#endif // MATH_H\n"
  },
  {
    "path": "include/geom.h",
    "content": "/**\n * @file geom.h\n *\n * @brief Geometry.\n */\n#ifndef GEOM_H\n#define GEOM_H\n\n#include <vec.h>\n#include <mat.h>\n\n/**\n * @todo Define struct\n */\nstruct TBSP;\n\n/**\n * @brief Edge in a geometry.\n */\nstruct EDGE\n{\n    ushort aipos[2];\n    ushort aisurf[2];\n    EDGE *pedgeNext;\n    EDGE *pedgeOtherNext;\n};\n\n/**\n * @brief Unknown.\n */\nstruct SUR\n{\n    int cb;\n    void *pvSrc;\n    void *pvDst;\n    int cvtx;\n};\n\n/**\n * @brief Unknown.\n */\nstruct SURF\n{\n    VECTOR normal;\n    float gDot;\n    EDGE *pedge;\n    EDGE *pedgeOther;\n    short grfsurf;\n    short ipos;\n};\n\n/**\n * @brief Unknown.\n */\nstruct TSURF\n{\n    float gDot;\n    undefined4 unk1;\n    undefined4 unk2;\n    undefined4 unk3;\n    VECTOR normal;\n};\n\n/**\n * @brief Geometry.\n */\nstruct GEOM\n{\n    float sRadius;\n\n    int cpos;\n    VECTOR *apos;\n\n    int csurf;\n    SURF *asurf;\n\n    int cedge;\n    EDGE *aedge;\n\n    int *mpiposiiedgeMac;\n    int *aiedge;\n    VECTOR *mpisurfposCenter;\n    float *mpisurfsRadius;\n};\n\n/**\n * @brief Initializes the geometry struct.\n */\nvoid InitGeom(GEOM *pgeom);\n\n/**\n * @brief Clones the geometry struct.\n */\nvoid CloneGeom(GEOM *pgeomSrc, MATRIX4 *pdmat, GEOM *pgeomDst);\n\n#endif // GEOM_H\n"
  },
  {
    "path": "include/gifs.h",
    "content": "/**\n * @file gifs.h\n */\n#ifndef GIFS_H\n#define GIFS_H\n\n#include <dmas.h>\n\n/**\n * @brief Unknown. Constructs primitives for rendering? \n */\nstruct GIFS : public DMAS\n{\n    QW *m_pqwPrim;\n    uint m_creg;\n    uint m_cregAll;\n\n    GIFS();\n\n    void AddPrimEnd();\n    void EndPrim(int fEOP);\n    void CheckReg(int fExpectPack, int regExpect);\n    void AddPrimBulk(int prim, int c, int creg, ulong regs, QW **paqwBulk);\n    void AddPrimPack(int prim, int creg, unsigned long regs);\n    void PackRGBA(uint rgba);\n    void PackUV(int u, int v);\n    void PackSTQ(float s, float t, float q);\n    void PackXYZ(int x, int y, int z);\n    void PackXYZF(int x, int y, int z, int fog);\n    void PackXYZFNoKick(int x, int y, int z, int fog);\n    void PackAD(long int a, long int d);\n    void AddPrimList(int creg, ulong regs);\n    void ListRGBAQ(uint rgba, float q);\n    void ListUV(int u, int v);\n    void ListXYZF(int x, int y, int z, int fog);\n    void AddImage(int cqw);\n};\n\n#endif // GIFS_H\n"
  },
  {
    "path": "include/glbs.h",
    "content": "/**\n * @file glbs.h\n */\n#ifndef GLBS_H\n#define GLBS_H\n\n#include \"common.h\"\n#include <cm.h>\n#include <mat.h>\n#include <vec.h>\n#include <shd.h>\n#include <light.h>\n\n// Forward.\nstruct UV;\n\n/**\n * @brief (?) kind.\n */\nenum TRLK\n{\n    TRLK_Nil = -1,\n    TRLK_Download = 0,\n    TRLK_DownloadRelight = 1,\n    TRLK_Relight = 2,\n    TRLK_RelightCache = 3,\n    TRLK_Quick = 4,\n    TRLK_Max = 5\n};\n\n/**\n * @brief Unknown.\n */\ntypedef struct RGL\n{\n    /* 0x00 */ MATRIX4 matObjectToWorld;\n    /* 0x40 */ MATRIX4 matWorldToObject;\n    FGFN fgfn;\n    float uAlpha;\n    /* 0x94 */ TRLK trlk;\n    int fCull;\n    /* 0x9c */ TWPS twps;\n    QW qwPosCenter;\n} RGLD;\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct VTXG\n{\n    STRUCT_PADDING(10);\n};\n\n/**\n * @brief Unknown.\n */\nstruct GLBS\n{\n    /* 0x00  */ RGLD m_rgld;\n    /* 0xb0  */ int m_cplightStatic;\n    /* 0xb4  */ int m_cplightAll;\n    LIGHT *m_aplight[16];\n    /* 0xf8  */ SHD *m_pshd;\n    VTXG m_vtxg;\n    /* 0x124 */ int m_cvtxg;\n    /* 0x128 */ VTXG m_avtxg[148];\n\n    /**\n     * @brief Constructor.\n     */\n    GLBS();\n\n    /**\n     * @brief Destructor.\n     */\n    ~GLBS();\n\n    void SetTransform(VECTOR *ppos, MATRIX3 *pmat);\n\n    void FindLights(VECTOR *ppos, float sRadius);\n\n    void ResetStrip();\n\n    void BeginStrip(SHD *pshd);\n\n    void DrawPrelit();\n\n    void DrawThreeWay();\n\n    void EndStrip();\n\n    void SetNormal(VECTOR *ppos); // Might be SetPos?\n\n    void SetRgba(RGBA &rgba); // Might not be correct.\n\n    void SetUv(UV *puv);\n\n    void SetVtx(int fAdc);\n};\n\n#endif // GLBS_H\n"
  },
  {
    "path": "include/glob.h",
    "content": "/**\n * @file glob.h\n */\n#ifndef GLOB_H\n#define GLOB_H\n\n#include <bis.h>\n#include <alo.h>\n#include <vec.h>\n\ntypedef int GRFGLOB;\n\n/**\n * @todo Implement struct.\n */\nstruct GLOBSET\n{\n\t// ...\n};\n\n/**\n * @todo Implement struct.\n */\nstruct GLOB\n{\n    // ...\n};\n\n/**\n * @todo Implement struct.\n */\nstruct SUBGLOB\n{\n    // ...\n};\n\n/**\n * @todo Implement the struct and figure out does it belong here.\n */\nstruct SGVR\n{\n    // ...\n};\n\n/*\nvoid BuildGlobsetSaaArray(GLOBSET *pglobset);\n\nvoid LoadGlobsetFromBrx(GLOBSET *pglobset, CBinaryInputStream *pbis, ALO *palo);\n\nvoid EnsureBuffer(int iBuffer, VIFS *pvifs);\n\nvoid EnsureBufferCel(int iBuffer, VIFS *pvifs);\n\nvoid BuildSubcel(GLOBSET *pglobset, int iBuffer, SUBCEL *psubcel, int cposf, VECTORF *aposf, int ctwef, TWEF *atwef, SUBPOSEF *asubposef, VECTORF *aposfPoses, float *agWeights, VIFS *pvifs);\n\nvoid BuildSubglobSinglePass(GLOBSET *pglobset, GLOB *pglob, int iBuffer, SUBGLOB *psubglob, SHD *pshd, VECTORF *aposf, VECTORF *anormalf, RGBAF *argbaf, UVF *auvf, int cvtxf, VTXF *avtxf, SUBPOSEF *asubposef, VECTORF *aposfPoses, VECTORF *anormalfPoses, float *agWeights, VIFS *avifs, SGVR *psgvr);\n\nvoid BuildSubglobThreeWay(GLOBSET *pglobset, GLOB *pglob, int iBuffer, SUBGLOB *psubglob, SHD *pshd, VECTORF *aposf, VECTORF *anormalf, RGBAF *argbaf, UVF *auvf, int cvtxf, VTXF *avtxf, SUBPOSEF *asubposef, VECTORF *aposfPoses, VECTORF *anormalfPoses, float *agWeights, VIFS *avifs, SGVR *psgvr);\n\nvoid BuildSubglobLighting(GLOB *pglob, SUBGLOB *psubglob, SUBGLOBI *psubglobi);\n\nvoid PostGlobsetLoad(GLOBSET *pglobset, ALO *palo);\n\nvoid BindGlobset(GLOBSET *pglobset, ALO *palo);\n\nvoid CloneGlobset(GLOBSET *pglobset, ALO *palo, GLOBSET *pglobsetBase);\n\nvoid CloneGlob(GLOBSET *pglobset, GLOB *pglob, GLOBI *pglobi);\n\nvoid UpdateGlobset(GLOBSET * pglobset, ALO *palo, float dt);\n\nvoid UpdateAloConstraints(ALO *palo);\n\nvoid UpdateAloInfluences(ALO *palo, RO *pro);\n\nvoid PredrawGlob(GLOBSET *pglobset, GLOB *pglob, GLOBI *pglobi, ALO *palo);\n\nvoid RotateVu1Buffer();\n\nvoid DrawGlob(RPL *prpl);\n*/\n\n#endif // GLOB_H\n"
  },
  {
    "path": "include/gomer.h",
    "content": "/**\n * @file gomer.h\n */\n#ifndef GOMER_H\n#define GOMER_H\n\n#include \"common.h\"\n#include <stepguard.h>\n\n/**\n * @brief Gomer state.\n *\n * @todo Populate enum values.\n */\nenum GOMERS\n{\n    GOMERS_Nil = -1\n    // ...\n};\n\n/**\n * @class GOMER\n * @brief Unknown, related to bosses.\n * @todo Implement the struct.\n */\nstruct GOMER : public STEPGUARD\n{\n    // ...\n    /* 0xc40 */ int fAbandonExternal;\n};\n\n#endif // GOMER_H\n"
  },
  {
    "path": "include/gs.h",
    "content": "/**\n * @file gs.h\n *\n * @brief Graphics synthesizer.\n *\n * @note Note to be confused with GS (game state), declared in game.h.\n */\n#ifndef GS_H\n#define GS_H\n\n#include \"common.h\"\n#include <shd.h>\n#include <sce/libdma.h>\n\nstruct GSB\n{\n    int igsMin;\n    int igsMac;\n    int igsMax;\n};\n\n/**\n * @brief Initializes a GSB with the given values.\n *\n * @param pgsb The GSB to initialize.\n * @param igsMin The minimum index.\n * @param igsMax The maximum index.\n */\nvoid InitGsb(GSB *pgsb, int igsMin, int igsMax);\n\n/**\n * @brief Resets the igsMac to the minimum index.\n *\n * @param pGsb The GSB to reset.\n */\nvoid ResetGsb(GSB *pGsb);\n\n/**\n * @brief Allocates a range of indices in the GSB.\n *\n * @param pgsb The GSB to allocate from.\n * @param iCount The number of indices to allocate.\n *\n * @return The old value of igsMac.\n */\nint IgsAllocGsb(GSB *pgsb, int iCount);\n\nvoid BlastAqwGifsBothFrames(QW *);\n\nvoid SendDmaSyncGsFinish(sceDmaChan *pdc, QW *pqw);\n\nvoid StartupGs();\n\nvoid ClearFrameBuffers();\n\nvoid UploadBitmaps(GRFZON grfzon, GSB *pgsb);\n\n#endif // GS_H\n"
  },
  {
    "path": "include/hide.h",
    "content": "/**\n * @file hide.h\n */\n#ifndef HIDE_H\n#define HIDE_H\n\n#include \"common.h\"\n\n// ...\n\nvoid StartupHide();\n\n#endif // HIDE_H\n"
  },
  {
    "path": "include/hnd.h",
    "content": "/**\n * @file hnd.h\n */\n#ifndef HND_H\n#define HND_H\n\n#include \"common.h\"\n#include <target.h>\n#include <bis.h>\n\n/**\n * @class HANDLE\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct HND : public TARGET\n{\n    // ...\n};\n\nvoid InitHnd(HND *phnd);\n\nvoid LoadHndFromBrx(HND *phnd, CBinaryInputStream *pbis);\n\n#endif // HND_H\n"
  },
  {
    "path": "include/ik.h",
    "content": "/**\n * @file ik.h\n */\n#ifndef IK_H\n#define IK_H\n\n#include \"common.h\"\n#include <alo.h>\n#include <so.h>\n#include <cm.h>\n\n// Forward.\nstruct RO;\n\n/**\n * @class IK_HANDLE\n * @brief Inverse kinematics handle.\n * @todo Implement the struct.\n */\nstruct IKH : public SO\n{\n    // ...\n};\n\n/**\n * @class LIGHTWEIGHT_IK_HAN\n * @brief Lightweight(?) inverse kinematics handle.\n * @todo Implement the struct.\n */\nstruct LIKH : public ALO\n{\n    // ...\n};\n\nvoid RenderIkhSelf(IKH *pikh, CM pcm, RO *pro);\n\nvoid RenderLikhSelf(LIKH *plikh, CM *pcm, RO *pro);\n\nvoid SolveAloIK(ALO *palo);\n\n#endif // IK_H\n"
  },
  {
    "path": "include/include_asm.h",
    "content": "#ifndef INCLUDE_ASM_H\n#define INCLUDE_ASM_H\n\n#if !defined(M2CTX) && !defined(PERMUTER) && !defined(SKIP_ASM)\n\n#ifndef INCLUDE_ASM\n#define INCLUDE_ASM(FOLDER, NAME) \\\n    __asm__( \\\n        \".section .text\\n\" \\\n        \"    .set noat\\n\" \\\n        \"    .set noreorder\\n\" \\\n        \"    .include \\\"\" FOLDER \"/\" #NAME \".s\\\"\\n\" \\\n        \"    .set reorder\\n\" \\\n        \"    .set at\\n\" \\\n    )\n#endif\n#ifndef INCLUDE_RODATA\n#define INCLUDE_RODATA(FOLDER, NAME) \\\n    __asm__( \\\n        \".section .rodata\\n\" \\\n        \"    .include \\\"\" FOLDER \"/\" #NAME \".s\\\"\\n\" \\\n        \".section .text\" \\\n    )\n#endif\n__asm__(\".include \\\"include/labels.inc\\\"\\n\");\n\n#else\n\n#ifndef INCLUDE_ASM\n#define INCLUDE_ASM(FOLDER, NAME)\n#endif\n#ifndef INCLUDE_RODATA\n#define INCLUDE_RODATA(FOLDER, NAME)\n#endif\n\n#endif /* !defined(M2CTX) && !defined(PERMUTER) && !defined(SKIP_ASM) */\n\n#endif /* INCLUDE_ASM_H */\n"
  },
  {
    "path": "include/intrinsics.h",
    "content": "/**\n * @file intrinsics.h\n *\n * @brief Hardware intrinsics and inline assembly macros for MIPS/PS2 EE.\n */\n#ifndef INTRINSICS_H\n#define INTRINSICS_H\n\n/**\n * @brief Hardware square root using MIPS FPU sqrt.s instruction.\n *\n * @details Inline assembly to invoke the standard MIPS II FPU sqrt.s\n * instruction. Available on R5900 (PS2 EE) and most MIPS processors with an\n * FPU.\n *\n * @param value Expression to compute square root of\n * @return Square root result as a float\n */\n#define SQRTF(value)                                                           \\\n    ({                                                                         \\\n        float __result;                                                        \\\n        __asm__ volatile(\"sqrt.s %0, %1\"                                       \\\n                         : \"=&f\"(__result)                                     \\\n                         : \"f\"(value)                                          \\\n                         : \"memory\");                                          \\\n        __result;                                                              \\\n    })\n\n/**\n * @brief Read MIPS CP0 Count register (register $9).\n *\n * @details The Count register increments automatically every CPU cycle and is\n *          used for high-resolution timing. On PS2 EE, it runs at 294.912 MHz.\n *          https://psi-rockin.github.io/ps2tek/#eecop0timer\n *\n * @return 32-bit Count value as unsigned long\n */\n#define READ_CP0_COUNT()                                                       \\\n    ({                                                                         \\\n        unsigned long __result;                                                \\\n        __asm__ volatile(\"mfc0 %0, $9\" : \"=r\"(__result));                      \\\n        __result;                                                              \\\n    })\n\n#endif // INTRINSICS_H\n"
  },
  {
    "path": "include/jlo.h",
    "content": "/**\n * @file jlo.h\n */\n#ifndef JLO_H\n#define JLO_H\n\n#include \"common.h\"\n#include <button.h>\n#include <xform.h>\n#include <alo.h>\n#include <so.h>\n\n/**\n * @brief (?) state.\n */\nenum JLOS\n{\n    JLOS_Nil = -1,\n    JLOS_Jump = 0,\n    JLOS_Land = 1,\n    JLOS_Idle = 2,\n    JLOS_Fire = 3,\n    JLOS_Taunt = 4,\n    JLOS_Max = 5\n};\n\n/**\n * @class JLO\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct JLO : public SO\n{\n    // ...\n};\n\n/**\n * @class JLO_VOLUME\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct JLOVOL : public VOLBTN\n{\n    // ...\n};\n\n/**\n * @class JLO_CLUSTER\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct JLOC : public ALO\n{\n    // ...\n};\n\nvoid InitJlo(JLO *pjlo);\n\nvoid LoadJloFromBrx(JLO *pjlo, CBinaryInputStream *pbis);\n\nvoid PostJloLoad(JLO *pjlo);\n\nvoid PresetJloAccel(JLO *pjlo, float dt);\n\nvoid UpdateJlo(JLO *pjlo, float dt);\n\nJLOS JlosNextJlo(JLO *pjlo);\n\nvoid SetJloJlovol(JLO *pjlo, JLOVOL *pjlovol);\n\nvoid FireJlo(JLO *pjlo);\n\nvoid LandJlo(JLO *pjlo);\n\nvoid JumpJlo(JLO *pjlo);\n\nvoid HandleJloMessage(JLO *pjlo, MSGID msgid, void *pv);\n\nvoid SetJloJlos(JLO *pjlo, JLOS jlos);\n\nvoid ActivateJlo(JLO *pjlo);\n\nvoid DeactivateJlo(JLO *pjlo);\n\nvoid InitJloc(JLOC *pjloc);\n\nvoid LoadJlocFromBrx(JLOC *pjloc, CBinaryInputStream *pbis);\n\nvoid PostJlocLoad(JLOC *pjloc);\n\nXFM *PxfmChooseJloc(JLOC *pjloc);\n\nvoid InitJlovol(JLOVOL *pjlovol);\n\nvoid BindJlovol(JLOVOL *pjlovol);\n\nvoid HandleJlovolMessage(JLOVOL *pjlovol, MSGID msgid, void *pv);\n\n#endif // JLO_H\n"
  },
  {
    "path": "include/joy.h",
    "content": "/**\n * @file joy.h\n *\n * @brief Joypad manager.\n */\n#ifndef JOY_H\n#define JOY_H\n\n#include \"common.h\"\n#include <rumble.h>\n#include <util.h>\n\n#define JOY_BUTTON_PRESSED(pjoy, pad_button) (pjoy->grfbtnPressed & (pad_button) != _NOT_PRESSED)\n\n// MARK:Pad\n\nenum PAD\n{\n    _NOT_PRESSED = 0x0,\n    PAD_L2 = 0x1,\n    PAD_R2 = 0x2,\n    PAD_L1 = 0x4,\n    PAD_R1 = 0x8,\n    PAD_TRIANGLE = 0x10,\n    PAD_CIRCLE = 0x20,\n    PAD_CROSS = 0x40,\n    PAD_SQUARE = 0x80,\n    PAD_SELECT = 0x100,\n    PAD_L3 = 0x200,\n    PAD_R3 = 0x400,\n    PAD_START = 0x800,\n    PAD_UP_ARROW = 0x1000,\n    PAD_RIGHT_ARROW = 0x2000,\n    PAD_DOWN_ARROW = 0x4000,\n    PAD_LEFT_ARROW = 0x8000\n};\n\nenum BTNP\n{\n    BTNP_Nil = -1,\n    BTNP_PadRight = 0,\n    BTNP_PadLeft = 1,\n    BTNP_PadUp = 2,\n    BTNP_PadDown = 3,\n    BTNP_Triangle = 4,\n    BTNP_Circle = 5,\n    BTNP_X = 6,\n    BTNP_Square = 7,\n    BTNP_L1 = 8,\n    BTNP_R1 = 9,\n    BTNP_L2 = 10,\n    BTNP_R2 = 11,\n    BTNP_Max = 12\n};\n\n// MARK:Joy\n\n/**\n * @brief Joypad button integer type.\n */\ntypedef ushort GRFBTN;\n\n/**\n * @brief Joypad state.\n */\nenum JOYS\n{\n    JOYS_Initing = 0,\n    JOYS_Searching = 1,\n    JOYS_Waiting = 2,\n    JOYS_Ready = 3,\n    JOYS_Max = 4\n};\n\n/**\n * @brief Joypad kind.\n */\nenum JOYK\n{\n    JOYK_Unknown = 0,\n    JOYK_Digital = 1,\n    JOYK_Analog = 2,\n    JOYK_Shock = 3,\n    JOYK_Shock2 = 4,\n    JOYK_Max = 5\n};\n\n/**\n * @brief Joypad id.\n */\nenum JOYID\n{\n    JOYID_Nil = -1,\n    JOYID_Left = 0,\n    JOYID_Right = 1,\n    JOYID_Max = 2\n};\n\n/**\n * @brief Joypad.\n */\nstruct JOY\n{\n    undefined4 *pvtjoy;\n\n    // joypad info\n    int nPort;\n    int nSlot;\n    uint *aullDma; // todo: fix type\n    int term;\n    JOYS joys;\n    JOYK joyk;\n    float tJoys;\n    float tRead;\n    float tActive;\n    int dxLatch;\n    int dyLatch;\n    float tLatchX;\n    float dtLatchX;\n    float tLatchY;\n    float dtLatchY;\n\n    // left analog stick\n    float x, y;\n    /* 0x48 */ float uDeflect;\n    byte bX, bY;\n    ushort unk_short;\n    int fStickMoved;\n    LM almDeflect[4];\n\n    // right analog stick\n    float x2, y2;\n    /* 0x7c */ float uDeflect2;\n    byte bX2, bY2;\n    ushort unk_short2;\n    int fStickMoved2;\n    LM almDeflect2[4];\n\n    // face buttons\n    GRFBTN grfbtn;\n    GRFBTN grfbtnPressed;\n    GRFBTN grfbtnReleased;\n    byte mpbtnpb[12];\n\n    // rumble\n    short unk_short_3;\n    RUMBLE *prumble;\n    int fRumbleEnabled;\n};\n\nextern JOY g_joy;\n\n// MARK:User\n\n/**\n * @brief User flags integer type.\n */\ntypedef int GRFUSR;\n\nextern GRFUSR g_grfusr;\n\nextern int g_grfjoyt;\n\n/**\n * @brief User Flags.\n */\nenum FUSR\n{\n    FUSR_Menu = 0x1,\n    FUSR_HandsOff = 0x2,\n    FUSR_NoPause = 0x4\n};\n\n// MARK:Cheats\n\nstruct CODE\n{\n    ushort *ajbc;      // Pointer to code sequence\n    int cjbc;          // Code sequence length\n    void (*pfn)(int);  // Callback function pointer\n    int nParam;        // Param for callback function\n    int nInputCounter; // Counter for correct inputs\n    int index;         // Index of cheat code in linked list\n    CODE *pchtNext;    // Pointer to next cheat code\n};\n\nextern CODE *g_pcode;\nextern float g_tCodeCheck;\n\n/**\n * @brief Cheat flags.\n */\nenum FCHT\n{\n    FCHT_None = 0x0,\n    FCHT_Invulnerability = 0x1,\n    FCHT_InfiniteCharms = 0x2,\n    FCHT_LowGravity = 0x4,\n    FCHT_LowFriction = 0x8,\n    FCHT_ResetWorld = 0x4000\n};\n\n/**\n * @brief Cheat flags integer type.\n */\ntypedef int GRFCHT;\n\nextern GRFCHT g_grfcht;\n\n/**\n * @brief Cheat type.\n *\n * @note Usage unknown.\n */\nenum CHT\n{\n    CHT_Nil = 0x0,\n    CHT_Charms = 0x1,\n    CHT_Max = 0x2\n};\n\nvoid StartupJoy();\n\nvoid AddGrfusr(GRFUSR grfusr);\n\nvoid RemoveGrfusr(GRFUSR grfusr);\n\nvoid UpdateGrfjoytFromGrfusr();\n\nvoid InitJoy(JOY *pjoy, int nPort, int nSlot);\n\nvoid UpdateJoy(JOY *pjoy);\n\nvoid SetJoyJoys(JOY *pjoy, JOYS joys, JOYK joyk);\n\nvoid GetJoyXYDeflection(JOY *pjoy, uchar bX, uchar bY, float *px, float *py, float *puDeflect, uchar *pbX, uchar *pbY, int *pfStickMoved, LM *almDeflect);\n\nint FReadJoy(JOY *pjoy);\n\nvoid SetJoyBtnHandled(JOY *joy, ushort btn);\n\nvoid TriggerJoyRumbleRumk(RUMBLE *prumble, JOY *pjoy, float dt);\n\nvoid StartJoySelection(JOY *pjoy);\n\nint DxSelectionJoy(JOY *pjoy);\n\nint DySelectionJoy(JOY *pjoy);\n\nfloat UBtnpJoy(JOY *pjoy, BTNP btnp);\n\nvoid AddCode(CODE *pcode);\n\nvoid _ResetCodes();\n\nvoid _MatchCodes(JOY *pjoy, short grfbtnPrev);\n\nvoid UpdateCodes();\n\nvoid ClearFchts();\n\nvoid AddFcht(uint nParam);\n\nvoid Chetkido();\n\nvoid StartupCodes();\n\n#endif // JOY_H\n"
  },
  {
    "path": "include/jsg.h",
    "content": "/**\n * @brief jsg.h\n */\n#ifndef JSG_H\n#define JSG_H\n\n#include \"common.h\"\n#include <asega.h>\n#include <oid.h>\n#include <vec.h>\n#include <lo.h>\n#include <tn.h>\n#include <jt.h>\n\n/**\n * @brief (?) kind.\n */\nenum FTAK\n{\n    FTAK_Nil = -1,\n    FTAK_None = 0,\n    FTAK_Reach = 1,\n    FTAK_Sweep = 2,\n    FTAK_Whack = 2,\n    FTAK_Smash = 4,\n    FTAK_Rush = 8,\n    FTAK_Bomb = 16,\n    FTAK_Gun = 16,\n    FTAK_Max = 17,\n    FTAK_Shock = 32\n};\n\n/**\n * @brief Script element(?) kind.\n */\nenum JSGEK\n{\n    JSGEK_Nil = -1,\n    JSGEK_Context = 0,\n    JSGEK_Cut = 1,\n    JSGEK_Label = 2,\n    JSGEK_Tunnel = 3,\n    JSGEK_Pause = 4,\n    JSGEK_Jump = 5,\n    JSGEK_Run = 6,\n    JSGEK_Climb = 7,\n    JSGEK_Attack = 8,\n    JSGEK_Aseg = 9,\n    JSGEK_Focus = 10,\n    JSGEK_Clock = 11,\n    JSGEK_Unknown = 12,\n    JSGEK_Max = 13\n};\n\n/**\n * @brief Script jump(?) kind.\n */\nenum JSGJK\n{\n    JSGJK_Nil = -1,\n    JSGJK_Fall = 0,\n    JSGJK_Jump = 1,\n    JSGJK_DoubleJump = 2,\n    JSGJK_Max = 3\n};\n\n/**\n * @brief Script leap(?) kind.\n */\nenum JSGLK\n{\n    JSGLK_Nil = -1,\n    JSGLK_Normal = 0,\n    JSGLK_Big = 1,\n    JSGLK_Max = 2\n};\n\n/**\n * @brief Script element(?).\n */\nstruct JSGE\n{\n    JSGEK jsgek;\n    OID oid;\n    int fAsync;\n    union\n    {\n        struct\n        {\n            OID oid;\n        } label;\n        struct\n        {\n            float dtPause;\n        } pause;\n        struct\n        {\n            JSGJK jsgjk;\n            JSGLK jsglk;\n        } jump;\n        struct\n        {\n            float uRun;\n        } run;\n        struct\n        {\n            float uClimb;\n        } climb;\n        struct\n        {\n            FTAK ftak;\n        } attack;\n        struct\n        {\n            float rdt;\n        } clock;\n    };\n};\n\n/**\n * @class SCRIPT\n * @brief Object representing a script of some kind.\n */\nstruct JSG : public LO\n{\n    int cjsge;\n    JSGE *ajsge;\n    JT *pjt;\n    int ijsgeCur;\n    float tCur;\n    JSGE *pjsgeJoy;\n    LO *ploContext;\n    ASEGA *pasegaCur;\n    LO *ploFocus;\n    TN *ptnCur;\n    int fHideTn;\n    undefined4 unk1;\n    undefined4 unk2;\n    undefined4 unk3;\n};\n\n/**\n * @brief Initializes the given script.\n */\nvoid InitJsg(JSG *pjsg);\n\nvoid GetJsgLocation(JSG *pjsg, LO *plo, VECTOR *ppos, float *prad);\n\nvoid SetJsgFocus(JSG *pjsg, LO *plo);\n\nvoid SetJsgTn(JSG *pjsg, TN *ptn);\n\nvoid NextJsgJsge(JSG *pjsg);\n\nint FIsJsgJsgeComplete(JSG *pjsg, JSGE *pjsge);\n\nvoid UpdateJsgJsge(JSG *pjsg);\n\nvoid ReadJsgJoystick(JSG *pjsg, JOY *pjoy);\n\n/**\n * @brief Updates the script and returns true if there are still script elements to execute.\n *\n * @return 1 if count of script elements > 0, and current script element index < count of script elements.\n * @return 0 otherwise.\n */\nint FIsJsgActive(JSG *pjsg);\n\n/**\n * @brief Retracts the script and clears the count of script elements.\n */\nvoid ClearJsg(JSG *pjsg);\n\nvoid ApplyJsg(JSG *pjsg, JT *pjt);\n\nvoid RetractJsg(JSG *pjsg);\n\nJSGE *PjsgeAllocJsg(JSG *pjsg, JSGEK jsgek, OID oid, int fAsync);\n\n/**\n * @brief Apply the script to a JT context and mark it active.\n *\n * @param pjsg Script instance.\n * @param pjt JT context to attach the script to.\n */\nvoid ApplyJsg(JSG *pjsg, JT *pjt);\n\n/**\n * @brief Retract the script from its JT context and stop it.\n *\n * @param pjsg Script instance.\n */\nvoid RetractJsg(JSG *pjsg);\n\n/**\n * @brief Allocate and initialize a new script element (JSGE).\n *\n * @param pjsg Script instance.\n * @param jsgek Type of script element to allocate.\n * @param oid Object id associated with the element.\n * @param fAsync Whether the element is asynchronous.\n *\n * @returns Returns a pointer to an initialized JSGE within the script's array, or\n * a pointer to a static fallback if the script is full.\n */\nJSGE *PjsgeAllocJsg(JSG *pjsg, JSGEK jsgek, OID oid, int fAsync);\n\n/**\n * @brief Add a context element to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Object to use as context.\n */\nvoid AddJsgContext(JSG *pjsg, OID oid);\n\n/**\n * @brief Add a cut element to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Object marking the cut.\n */\nvoid AddJsgCut(JSG *pjsg, OID oid);\n\n/**\n * @brief Add a focus element to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Object to focus on.\n */\nvoid AddJsgFocus(JSG *pjsg, OID oid);\n\n/**\n * @brief Add a label element to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Label object ID.\n */\nvoid AddJsgLabel(JSG *pjsg, OID oid);\n\n/**\n * @brief Add a tunnel element to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Tunnel node to use.\n */\nvoid AddJsgTunnel(JSG *pjsg, OID oid);\n\n/**\n * @brief Add a pause element to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Object ID for pause context.\n * @param dtPause Duration to pause.\n */\nvoid AddJsgPause(JSG *pjsg, OID oid, float dtPause);\n\n/**\n * @brief Add an animation segment (ASEGA) element.\n *\n * @param pjsg Script instance.\n * @param oid Animation sequence ID.\n * @param fAsync Whether the segment runs asynchronously.\n */\nvoid AddJsgAseg(JSG *pjsg, OID oid, int fAsync);\n\n/**\n * @brief Add a jump action to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Object ID to perform jump.\n * @param jsgjk Jump kind.\n * @param jsglk Leap size kind.\n * @param fAsync Whether the action is asynchronous.\n */\nvoid AddJsgJump(JSG *pjsg, OID oid, JSGJK jsgjk, JSGLK jsglk, int fAsync);\n\n/**\n * @brief Add a run action to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Object ID to run.\n * @param uRun Speed of run.\n * @param fAsync Whether the action is asynchronous.\n */\nvoid AddJsgRun(JSG *pjsg, OID oid, float uRun, int fAsync);\n\n/**\n * @brief Add a climb action to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Object ID to climb.\n * @param uClimb Climb speed.\n * @param fAsync Whether the action is asynchronous.\n */\nvoid AddJsgClimb(JSG *pjsg, OID oid, float uClimb, int fAsync);\n\n/**\n * @brief Add an attack action to the script sequence.\n *\n * @param pjsg Script instance.\n * @param oid Object ID to attack with.\n * @param ftak Attack kind.\n * @param fAsync Whether the attack is asynchronous.\n */\nvoid AddJsgAttack(JSG *pjsg, OID oid, FTAK ftak, int fAsync);\n\n/**\n * @brief Add a clock rate change to the script sequence.\n *\n * @param pjsg Script instance.\n * @param rdt Rate delta time factor.\n */\nvoid AddJsgClock(JSG *pjsg, float rdt);\n\n#endif // JSG_H\n"
  },
  {
    "path": "include/jt.h",
    "content": "/**\n * @file jt.h\n *\n * @brief Sly entity.\n */\n#ifndef JT_H\n#define JT_H\n\n#include \"common.h\"\n#include <step.h>\n\n/**\n * JT state.\n *\n * @note Based on May proto, may be inaccurate.\n */\nenum JTS\n{\n    JTS_Nil = -1,\n    JTS_Stand = 0,\n    JTS_Run = 1,\n    JTS_Jump = 2,\n    JTS_Zap = 3,\n    JTS_Sidestep = 4,\n    JTS_Hide = 5,\n    JTS_Pipe = 6,\n    JTS_Edge = 7,\n    JTS_Celebrate = 8,\n    JTS_Rush = 9,\n    JTS_Puppet = 10,\n    JTS_Peek = 11,\n    JTS_Ball = 12,\n    JTS_Max = 13\n};\n\n/**\n * JT body state.\n *\n * @note Based on May proto, may be inaccurate.\n */\nenum JTBS\n{\n    JTBS_Nil = -1,\n    JTBS_Jump_Init = 0,\n    JTBS_Jump_Rise = 1,\n    JTBS_Jump_Fall = 2,\n    JTBS_Jump_Boost = 3,\n    JTBS_Jump_In = 4,\n    JTBS_Jump_Out = 5,\n    JTBS_Jump_Thrown = 6,\n    JTBS_Jump_Smash = 7,\n    JTBS_Jump_Dive = 8,\n    JTBS_Jump_Target = 9,\n    JTBS_Jump_Spire = 10,\n    JTBS_Jump_Rail = 11,\n    JTBS_Jump_Hshape = 12,\n    JTBS_Jump_Hpnt = 13,\n    JTBS_Hide_Stand = 14,\n    JTBS_Hide_Sidestep = 15,\n    JTBS_Hide_PeekLeft = 16,\n    JTBS_Hide_PeekRight = 17,\n    JTBS_Hide_Run = 18,\n    JTBS_Hide_Spin = 19,\n    JTBS_Pipe_Init = 20,\n    JTBS_Pipe_Stay = 21,\n    JTBS_Pipe_Up = 22,\n    JTBS_Pipe_Down = 23,\n    JTBS_Pipe_Spin = 24,\n    JTBS_Celebrate_Key = 25,\n    JTBS_Celebrate_Timed = 26,\n    JTBS_Celebrate_UseKey = 27,\n    JTBS_Rush_Attack = 28,\n    JTBS_Rush_Bounce = 29,\n    JTBS_Peek_Enter = 30,\n    JTBS_Peek_Peek = 31,\n    JTBS_Peek_Exit = 32,\n    JTBS_Zap_Blunt = 33,\n    JTBS_Zap_Electric = 34,\n    JTBS_Zap_Fire = 35,\n    JTBS_Zap_Water = 36,\n    // ...\n    JTBS_Unk_54 = 54,\n    JTBS_Unk_55 = 55\n\n};\n\n/**\n * @brief JT Health State.\n */\nenum JTHS\n{\n    JTHS_Nil = -1,\n    JTHS_Normal = 0,\n    JTHS_Damaged = 1,\n    JTHS_Dead = 2,\n    JTHS_Max = 3\n};\n\n/**\n * @brief JT cane state.\n *\n * @note Copied from May proto, may be outdated/out of order.\n */\nenum JTCS\n{\n    // ...\n};\n\n/**\n * @brief JT hide kind?\n */\nenum JTHK\n{\n    JTHK_Nil = -1,\n    JTHK_Flatten = 0,\n    JTHK_Duck = 1,\n    JTHK_Basket = 2,\n    JTHK_Nonchalant = 3,\n    JTHK_Rail = 4,\n    JTHK_Spire = 5,\n    JTHK_Reach = 6,\n    JTHK_Vault = 7,\n    JTHK_Max = 8\n};\n\n/**\n * @brief JT pipe direction kind.\n */\nenum JTPDK\n{\n    JTPDK_Nil = -1,\n    JTPDK_Up = 0,\n    JTPDK_Down = 1,\n    JTPDK_Max = 2\n};\n\n/**\n * @class JT\n * @brief Jewel thief (AKA Sly Cooper).\n *\n * JT = \"jewel thief\" = codename for Sly.\n */\nstruct JT : public STEP\n{\n    STRUCT_PADDING(1090);\n    undefined2 padding0_extra;\n\n    ALO *paloMine_0x1518;   // 0x1518\n\n    STRUCT_PADDING(832);\n    undefined2 padding1_extra;\n\n    JTS jts;                // 0x2220\n    int unk_0x2224;\n    JTBS jtbs;              // 0x2228\n\n    STRUCT_PADDING(328);\n    undefined1 padding2_extra;\n\n    int unk_0x2750;\n};\n\n/**\n * @brief Sets the JT state and JT body state on the given JT.\n *\n * @param pjt Pointer to the JT instance.\n * @param jts JT state value\n * @param JTBS JT body state value\n */\nvoid SetJtJts(JT *pjt, JTS jts, JTBS jtbs);\n\n/**\n * @brief Stubbed, does nothing.\n *\n * @param pjt Pointer to JT instance.\n * @param fProfile Profile flag.\n *\n * @deprecated\n */\nvoid ProfileJt(JT *pjt, int fProfile);\n\nextern JT *g_pjt;\n\n#endif // JT_H\n"
  },
  {
    "path": "include/jump.h",
    "content": "/**\n * @file jump.h\n */\n#ifndef JUMP_H\n#define JUMP_H\n\n#include \"common.h\"\n#include <mark.h>\n#include <vec.h>\n#include <joy.h>\n#include <pnt.h>\n#include <jt.h>\n#include <lo.h>\n#include <so.h>\n\n// Forward.\nstruct XP;\n\n/**\n * @class JUMP_TARGET\n * @brief Target point for a jump.\n * @todo Implement the struct.\n */\nstruct JMT : public PNT\n{\n    undefined4 unk1;\n    DLE dleJmt;\n    float sRadius;\n    /* 0x5c */ OID oidSetIgnoreJt;\n    /* 0x60 */ SO *psoSetIgnoreJt;\n    // ...\n};\n\nvoid PresetJtAccelJump(JT *pjt);\n\nvoid UpdateJtActiveJump(JT *pjt, JOY *pjoy);\n\nint FCheckJtSingleEdge(JT *pjt, SO *psoOther, EDGE *pedge, VECTOR *pnormal);\n\nint FCheckJtEdgeNormal(JT *pjt, VECTOR *pposEdge, VECTOR *pnormal);\n\nint FCheckJtEdgeGrab(JT *pjt, SO *psoOther, VECTOR *pposEdge, XPK xpk, void *pv, VECTOR *pnormal);\n\nXP *PxpFindJtBestEdge(JT *pjt, int *pixpdBest, VECTOR *pnormalBest);\n\nJTS JtsResetJt(JT *pjt);\n\nvoid HandleJtDiveEffect(JT *pjt);\n\nvoid UpdateJtJump(JT *pjt);\n\nint FTimeJtJumpToTarget(JT *pjt, VECTOR *pposJt, VECTOR *pvJt, VECTOR *pposTarget, VECTOR *pvTarget, float *pdtProject);\n\nvoid GetJtJumpVelocity(JT *pjt, VECTOR *pv);\n\nvoid GetJtJumpToTargetVelocity(JT *pjt, VECTOR *pv);\n\nvoid GetJtJumpBoostVelocity(JT *pjt, VECTOR *pv);\n\nvoid StartupJmt();\n\nvoid ResetJmtList();\n\nvoid OnJmtAdd(JMT *pjmt);\n\nvoid OnJmtRemove(JMT *pjmt);\n\nvoid CloneJmt(JMT *pjmt, JMT *pjmtBase);\n\nvoid PostJmtLoad(JMT *pjmt);\n\n#endif // JUMP_H\n"
  },
  {
    "path": "include/keyhole.h",
    "content": "/**\n * @file keyhole.h\n */\n#ifndef KEYHOLE_H\n#define KEYHOLE_H\n\n#include \"common.h\"\n#include <bis.h>\n#include <lo.h>\n\n/**\n * @class KEYHOLE\n * @brief Spot where keys are inserted into locks?\n * @todo Implement the struct.\n */\nstruct KEYHOLE : public LO\n{\n    // ...\n};\n\nvoid InitKeyhole(KEYHOLE *pkeyhole);\n\nvoid LoadKeyholeFromBrx(KEYHOLE *pkeyhole, CBinaryInputStream *pbis);\n\nvoid DrawKeyholeMask(KEYHOLE *pkeyhole, float x, float y, float rScale, float uAlpha);\n\nvoid DrawKeyhole(KEYHOLE *pkeyhole, float uClosed);\n\n#endif // KEYHOLE_H\n"
  },
  {
    "path": "include/labels.inc",
    "content": "# This file is used by the original compiler/assembler.\n# Defines the expected assembly macros.\n\n# A function symbol.\n.macro glabel label, visibility=global\n    .\\visibility \\label\n    .type \\label, @function\n    \\label:\n        .ent \\label\n.endm\n\n# The end of a function symbol.\n.macro endlabel label\n    .size \\label, . - \\label\n    .end \\label\n.endm\n\n# An alternative entry to a function.\n.macro alabel label, visibility=global\n    .\\visibility \\label\n    .type \\label, @function\n    \\label:\n.endm\n\n# A label referenced by an error handler table.\n.macro ehlabel label, visibility=global\n    .\\visibility \\label\n    \\label:\n.endm\n\n\n# A label referenced by a jumptable.\n.macro jlabel label, visibility=global\n    .\\visibility \\label\n    \\label:\n.endm\n\n\n# A data symbol.\n.macro dlabel label, visibility=global\n    .\\visibility \\label\n    .type \\label, @object\n    \\label:\n.endm\n\n# End of a data symbol.\n.macro enddlabel label\n    .size \\label, . - \\label\n.endm\n\n\n# Label to signal the symbol haven't been matched yet.\n.macro nonmatching label, size=1\n    .global \\label\\().NON_MATCHING\n    .type \\label\\().NON_MATCHING, @object\n    .size \\label\\().NON_MATCHING, \\size\n    \\label\\().NON_MATCHING:\n.endm\n"
  },
  {
    "path": "include/landing.h",
    "content": "/**\n * @file landing.h\n */\n#ifndef LANDING_H\n#define LANDING_H\n\n#include \"common.h\"\n#include <shape.h>\n#include <dl.h>\n\n/**\n * @class LANDING\n * @brief Unknown.\n */\nstruct LANDING : public SHAPE\n{\n    /* 0x38 */ DLE dleLanding;\n};\n\nvoid OnLandingAdd(LANDING *planding);\n\nvoid OnLandingRemove(LANDING *planding);\n\nvoid CloneLanding(LANDING *planding, LANDING *plandingBase);\n\n#endif // LANDING_H\n"
  },
  {
    "path": "include/lgn.h",
    "content": "/**\n * @file lgn.h\n */\n#ifndef LGN_H\n#define LGN_H\n\n#include \"common.h\"\n#include <screen.h>\n#include <shape.h>\n#include <break.h>\n#include <joy.h>\n#include <zap.h>\n#include <cm.h>\n#include <po.h>\n#include <jt.h>\n\n// Forward.\nstruct RO;\nstruct CPDEFI;\n\n/**\n * @class SWOOPER.\n * @brief Unknown.\n */\nstruct SWP : public BRK\n{\n    // ...\n};\n\n/**\n * @brief Light gun state.\n */\nenum LGNS\n{\n    LGNS_Nil = -1,\n    LGNS_Passive = 0,\n    LGNS_Active = 1,\n    LGNS_Zap = 2,\n    LGNS_Dead = 3,\n    LGNS_Max = 4\n};\n\n/**\n * @class LIGHT_GUN\n * @brief Light gun weapon (maybe the one used by Carmelita).\n *\n * @note Inherits from PO in the prototype but not in retail.\n * Judging on the function calls it might inherit from SUV?\n */\nstruct LGN\n{\n    // ...\n    /* 0xbf0 */ int fFlash;\n    /* 0xbf4 */ float tFlash;\n    // ...\n};\n\n/**\n * @brief Light gun something (?).\n */\nstruct LGNR : public BLOT\n{\n    // ...\n};\n\nvoid InitLgn(LGN *plgn);\n\nvoid PostLgnLoad(LGN *plgn);\n\nvoid UpdateLgnActive(LGN *plgn, JOY *pjoy, float dt);\n\nvoid UpdateLgn(LGN *plgn, float dt);\n\nvoid OnLgnActive(LGN *plgn, int fActive, PO *ppoOther);\n\nvoid RenderLgnAll(LGN *plgn, CM *pcm, RO *pro);\n\nvoid GetLgnCpdefi(LGN *plgn, float dt, CPDEFI *pcpdefi);\n\nint FInvulnerableLgn(LGN *plgn, ZPK zpk);\n\nJTHS JthsCurrentLgn(LGN *plgn);\n\nvoid UseLgnCharm(LGN *plgn);\n\nvoid ApplyLgnThrow(LGN *plgn, PO *ppo);\n\nint FTakeLgnDamage(LGN *plgn, ZPR *pzpr);\n\nvoid HandleLgnMessage(LGN *plgn, MSGID msgid, void *pv);\n\nvoid SetLgnLgns(LGN *plgn, LGNS lgns);\n\nvoid UpdateLgnrAim(LGNR *plgnr, JOY *pjoy);\n\nvoid DrawLgnr(LGNR *plgnr);\n\nvoid InitSwp(SWP *pswp);\n\nvoid PostSwpLoad(SWP *pswp);\n\nvoid UpdateSwp(SWP *pswp, float dt);\n\nvoid ProjectSwpTransform(SWP *pswp, float dt, int fParentDirty);\n\nvoid SetSwpShape(SWP *pswp, SHAPE *pshape, float tMax);\n\n#endif // LGN_H\n"
  },
  {
    "path": "include/lib/libkernl/filestub.h",
    "content": "/**\n * @file include/lib/libkernl/filestub.h\n * @note src/lib/libkernl/filestub.c\n */\n#ifndef FILESTUB_H\n#define FILESTUB_H\n\nextern \"C\"\n{\n    int sceFsReset();\n    int sceClose(int fd);\n    int sceRead(int fd, void *pv, int cb);\n    int sceIoctl(int, int, void *);\n};\n\n#endif // FILESTUB_H\n"
  },
  {
    "path": "include/light.h",
    "content": "/**\n * @file light.h\n *\n * @brief Light and shadow system.\n */\n#ifndef LIGHT_H\n#define LIGHT_H\n\n#include \"common.h\"\n#include <alo.h>\n#include <util.h>\n\n// Forward.\nstruct SW;\n\n/**\n * @brief Unknown.\n */\nenum TWPS\n{\n    TWPS_Shadow = 0,\n    TWPS_ShadowMidtone = 1,\n    TWPS_ShadowMidtoneSaturate = 2\n};\n\n/**\n * @brief Light kind.\n */\nenum LIGHTK\n{\n    LIGHTK_Nil = -1,\n    LIGHTK_Direction = 0,\n    LIGHTK_Position = 1,\n    LIGHTK_Frustrum = 2,\n    LIGHTK_Spot = 3,\n    LIGHTK_Max = 4\n};\n\n/**\n * @brief Light shadow & midtone.\n */\nstruct LSM\n{\n    float uShadow;\n    /* 0x04 */ float uMidtone;\n};\n\n/**\n * @brief Light.\n * @todo Implement the struct.\n */\nstruct LIGHT : public ALO\n{\n    // ...\n    /* 0x2e0 */ VECTOR vecHighlight;\n    /* 0x2f0 */ float gMidtone;\n    /* 0x2f4 */ float gShadow;\n    /* 0x2f8 */ float degHighlight;\n    /* 0x2fc */ float degMidtone;\n    /* 0x300 */ float degShadow;\n    /* 0x304 */ int fDynamic;\n    STRUCT_PADDING(13);\n    /* 0x338 */ float degCone;\n    /* 0x33c */ float degHotSpot;\n    // ...\n};\n\nextern int g_cframeStaticLightsInvalid;\n\n/**\n * @brief Initializes a light.\n *\n * @param plight Pointer to a light.\n */\nvoid InitLight(LIGHT *plight);\n\n/**\n * @brief TODO.\n */\nvoid UpdateLightXfWorldHierarchy(LIGHT *plight);\n\n/**\n * @brief Removes a light from the SW.\n *\n * @param plight Pointer to a light.\n */\nvoid RemoveLightFromSw(LIGHT *plight);\n\n/**\n * @brief Adds a light to the SW.\n *\n * @param plight Pointer to a light.\n */\nvoid AddLightToSw(LIGHT *plight);\n\n/**\n * @brief Adds a light.\n *\n * @param plight Pointer to a light.\n */\nvoid OnLightAdd(LIGHT *plight);\n\n/**\n * @brief Removes a light.\n *\n * @param plight Pointer to a light.\n */\nvoid OnLightRemove(LIGHT *plight);\n\n/**\n * @brief Clones a light.\n *\n * @param plight Pointer to a light.\n * @param plight Pointer to the light to clone.\n */\nvoid CloneLight(LIGHT *plight, LIGHT *plightBase);\n\nvoid FitLinearFunction(float x0, float y0, float x1, float y1, float *pdu, float *pru);\n\nvoid FitRecipFunction(float x0, float y0, float x1, float y1, float *pdu, float *pru);\n\nvoid ConvertFallOff(LM *plm, float *pdu, float *pru);\n\nvoid ConvertAngleStrength(float deg0, float g0, float deg1, float g1, float *pdu, float *pru);\n\nvoid InvalidateLight(LIGHT *plight);\n\nvoid RebuildLightVifs(LIGHT *plight);\n\nvoid SetLightKind(LIGHT *plight, LIGHTK lightk);\n\nvoid SetLightHighlightColor(LIGHT *plight, VECTOR *pvecHighlight);\n\nvoid SetLightMidtoneStrength(LIGHT *plight, float gMidtone);\n\nvoid SetLightShadowStrength(LIGHT *plight, float gShadow);\n\nvoid SetLightHighlightAngle(LIGHT *plight, float degHighlight);\n\nvoid SetLightMidtoneAngle(LIGHT *plight, float degMidtone);\n\nvoid SetLightShadowAngle(LIGHT *plight, float degShadow);\n\nvoid SetLightDirection(LIGHT *plight, VECTOR *pvecDirection);\n\nvoid SetLightDynamic(LIGHT *plight, int fDynamic);\n\nvoid SetLightFallOff(LIGHT *plight, LM *plm);\n\nvoid SetLightConeAngle(LIGHT *plight, float degCone);\n\nvoid SetLightHotSpotAngle(LIGHT *plight, float degHotSpot);\n\nvoid SetLightFrustrumUp(LIGHT *plight, VECTOR *pvecUpLocal);\n\nvoid RebuildLightFrustrum(LIGHT *plight);\n\nvoid UpdateLightBeamGrfzon(LIGHT *plight);\n\nvoid SetLightDiffuse_Old(LIGHT *plight, float gDiffuse);\n\nvoid GetLightDiffuse_Old(LIGHT *plight, float *pgDiffuse);\n\nvoid SetLightSaturate_Old(LIGHT *plight, VECTOR *pvecSaturate);\n\nvoid GetLightSaturate_Old(LIGHT *plight, VECTOR *pvecSaturate);\n\nint NCmpFindLight(LIGHT **pplight1, LIGHT **pplight2);\n\nvoid PrepareSwLightsForDraw(SW *psw);\n\nTWPS TwpsFindSwLights(SW *psw, VECTOR *ppos, float sRadius, int grffindlight, int cplightMax, int *pcplightStatic, int *pcplightAll, LIGHT **aplight);\n\n#endif // LIGHT_H\n"
  },
  {
    "path": "include/lo.h",
    "content": "/**\n * @file lo.h\n *\n * @brief Level objects.\n */\n#ifndef LO_H\n#define LO_H\n\n#include \"common.h\"\n#include <dl.h>\n#include <mq.h>\n#include <oid.h>\n#include <basic.h>\n#include <splice/frame.h>\n\nstruct ALO; // Forward declaration.\nstruct SW;\nstruct PXR;\nstruct LM;\nstruct CLQ;\nstruct VECTOR;\n\n/**\n * @brief Unknown.\n * @todo Does this belong here?\n */\nenum OPTID\n{\n    OPTID_Nil = -1\n};\n\n/**\n * @class LO\n * @brief Unknown, maybe \"level object\".\n *\n * @note The fields \"pchzName\" and \"dtickPerf\" present in the prototype are not in release.\n */\nstruct LO : public BASIC\n{\n    /* 0x08 */ OID oid;\n    /* 0x10 */ DLE dleOid;\n    /* 0x14 */ SW *psw;\n    /* 0x18 */ ALO *paloParent;\n    /* 0x1c */ DLE dleChild;\n    /* 0x24 */ LO *ploCidNext;\n    /* 0x28 */ MQ *pmqFirst;\n    /* 0x2c */ CFrame *pframe;\n    /* 0x30 */ PXR *ppxr;\n};\n\n/**\n * @brief \"Proxy Root\"?\n */\nstruct PXR\n{\n    LO *plo;\n    OID oidProxyRoot;\n    DLE dleProxyRoot;\n    char *pchzProxyRoot;\n};\n\n/**\n * @brief Initialize LO with defaults set\n */\nvoid InitLo(LO *plo);\n\n/**\n * @brief Calls HandleLoSpliceEvent with unknown event\n *        Called by LO subclasses?\n */\nvoid PostLoLoad(LO *plo);\n\n/**\n * @brief Adds LO to 'dlChild' of either parent ALO, if present, or SW\n *        If LO is in world, also calls AddLoHierarchy\n */\nvoid AddLo(LO *plo);\n\n/**\n * @brief Calls OnLoAdd, and SendLoMessage with MSGID_added\n */\nvoid AddLoHierarchy(LO *plo);\n\n/**\n * @brief Does nothing\n */\nvoid OnLoAdd(LO *plo);\n\n/**\n * @brief Removes LO from 'dlChild' of either parent ALO, if present, or SW\n *        If LO is in world, also calls RemoveLoHierarchy\n */\nvoid RemoveLo(LO *plo);\n\n/**\n * @todo\n */\nvoid DeferLoRemove(LO *plo);\n\n/**\n * @brief If global 'uSuck' is within given range, calls DeferLoRemove with this LO\n */\nvoid SetLoSuckHideLimits(LO *plo, LM *plmUSuck);\n\n/**\n * @brief Calls OnLoRemove, and SendLoMessage with MSGID_removed\n */\nvoid RemoveLoHierarchy(LO *plo);\n\n/**\n * @brief Does nothing\n */\nvoid OnLoRemove(LO *plo);\n\n/**\n * @brief If LO is in world, remove it\n */\nvoid SnipLo(LO *plo);\n\n/**\n * @brief Check ALO is parent/grandparent/etc of LO\n */\nint FFindLoParent(LO *plo, ALO *paloParent);\n\n/**\n * @brief Removes LO, sets ALO as parent, then re-adds LO\n */\nvoid SetLoParent(LO *plo, ALO *paloParent);\n\n/**\n * @brief Checks if the LO is currently in the world.\n */\nint FIsLoInWorld(LO *PLO);\n\n/**\n * @brief Check if LO is in world and updates provided flag with result\n */\nvoid GetLoInWorld(LO *plo, int *pfInWorld);\n\n/**\n * @brief Creates new LO, clones provided LO, returns new LO\n */\nLO* PloCloneLo(LO *plo, SW *psw, ALO *paloParent);\n\n/**\n * @brief Clones from 'base' LO into provided LO\n */\nvoid CloneLoHierarchy(LO *plo, LO *ploBase);\n\n/**\n * @brief Clones from 'base' LO into provided LO\n */\nvoid CloneLo(LO *plo, LO *ploBase);\n\n/**\n * @todo\n */\nvoid SubscribeSwPpmqStruct(SW *psw, MQ **ppmqFirst, PFNMQ pfnmq, void *pvContext);\n\nvoid UnsubscribeSwPpmqStruct(SW *psw, MQ **ppmqFirst, PFNMQ pfnmq, void *pvContext);\n\nvoid SubscribeLoStruct(LO *plo, PFNMQ pfnmq, void *pvContext);\n\nvoid UnsubscribeLoStruct(LO *plo, PFNMQ pfnmq, void *pvContext);\n\nvoid SubscribeLoObject(LO *plo, LO *ploTarget);\n\nvoid UnsubscribeLoObject(LO *plo, LO *ploTarget);\n\n/**\n * @brief Calls HandleLoMessage, then each MQ function with provided MSGID and data pointer\n */\nvoid SendLoMessage(LO *plo, MSGID msgid, void *pv);\n\n/**\n * @brief Loads options from Brx\n */\nvoid LoadLoFromBrx(LO *plo, CBinaryInputStream *pbis);\n\n/**\n * @brief Checks if LO OID, or LO's PXR OID, match provided OID\n */\nint FMatchesLoName(LO *plo, OID oid);\n\n/**\n * @brief Return OID of LO's PXR, or Nil\n */\nOID GetProxyLo(LO *plo);\n\n/**\n * @brief Return OID of LO's PXR, or LO's own OID\n */\nOID OidProxyLoPreferred(LO *plo);\n\n/**\n * @brief Updates provided OID pointer with LO's PXR OID\n */\nvoid GetLoOidProxy(LO *plo, OID *poid);\n\n/**\n * @todo Args for following functions based on proto\n */\nvoid PostSpliceEventCallback(LO *plo, uint symidEvent, void *pvarg);\n\nint FFilterSpliceEvent(LO *plo, /* SYMEVID */ int symevid, int cargs, void **ppvargs);\n\nvoid HandleLoSpliceEvent(LO *plo, uint symidEvent, int cargs, void **ppvargs);\n\nvoid EnsureLoSidebagBool(LO *plo, OPTID optid, int f);\n\nvoid EnsureLoSidebagInt(LO *plo, OPTID optid, int n);\n\nvoid EnsureLoSidebagFoat(LO *plo, OPTID optid, float g);\n\nvoid EnsureLoSidebagClq(LO *plo, OPTID optid, CLQ *pclq);\n\nvoid EnsureLoSidebagLm(LO *plo, OPTID optid, LM *plm);\n\nvoid EnsureLoSidebagOid(LO *plo, OPTID optid, OID oid);\n\nvoid EnsureLoSidebagVector(LO *plo, OPTID optid, VECTOR *pvec);\n\n#endif // LO_H\n"
  },
  {
    "path": "include/lookat.h",
    "content": "/**\n * @file lookat.h\n */\n#ifndef LOOKAT_H\n#define LOOKAT_H\n\n#include \"common.h\"\n#include <util.h>\n#include <vec.h>\n#include <mat.h>\n#include <alo.h>\n\n/**\n * @brief Actor Look At (?)\n */\nstruct ACTLA\n{\n    int fUseTarget;\n    ALO *paloTarget;\n    VECTOR posTargetLocal;\n    float sIgnore;\n    int nPriorityEnabled;\n    int nPriorityDisabled;\n    int fPaused;\n    CLQ clqPanToPan;\n    LM lmPan;\n    CLQ clqTiltToTilt;\n    LM lmTilt;\n};\n\nvoid InitActla(ACTLA *pactla, ALO *palo);\n\nvoid SetActlaTarget(ACTLA *pactla, ALO *paloTarget, VECTOR *pposLocal);\n\nALO *PaloGetActlaTarget(ACTLA *pactla);\n\nvoid UpdateActla(ACTLA *pactla, float dt);\n\nvoid GetActlaRotationGoal(ACTLA *pactla, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\n#endif // LOOKAT_H\n"
  },
  {
    "path": "include/macro.inc",
    "content": "# This file is used by modern gas.\n# Defines the expected assembly macros\n\n# Evaluate this file only once in case it's included more than once\n.ifndef _MACRO_INC_GUARD\n.internal _MACRO_INC_GUARD\n.set _MACRO_INC_GUARD, 1\n\n# A function symbol.\n.macro glabel label, visibility=global\n    .\\visibility \"\\label\"\n    .type \"\\label\", @function\n    \"\\label\":\n        .ent \"\\label\"\n.endm\n\n# The end of a function symbol.\n.macro endlabel label\n    .size \"\\label\", . - \"\\label\"\n    .end \"\\label\"\n.endm\n\n# An alternative entry to a function.\n.macro alabel label, visibility=global\n    .\\visibility \"\\label\"\n    .type \"\\label\", @function\n    \"\\label\":\n.endm\n\n# A label referenced by an error handler table.\n.macro ehlabel label, visibility=global\n    .\\visibility \"\\label\"\n    \"\\label\":\n.endm\n\n\n# A label referenced by a jumptable.\n.macro jlabel label, visibility=global\n    .\\visibility \"\\label\"\n    \"\\label\":\n.endm\n\n\n# A data symbol.\n.macro dlabel label, visibility=global\n    .\\visibility \"\\label\"\n    .type \"\\label\", @object\n    \"\\label\":\n.endm\n\n# End of a data symbol.\n.macro enddlabel label\n    .size \"\\label\", . - \"\\label\"\n.endm\n\n\n# Label to signal the symbol haven't been matched yet.\n.macro nonmatching label, size=1\n    .global \"\\label\\().NON_MATCHING\"\n    .type \"\\label\\().NON_MATCHING\", @object\n    .size \"\\label\\().NON_MATCHING\", \\size\n    \"\\label\\().NON_MATCHING\":\n.endm\n\n.endif\n"
  },
  {
    "path": "include/mark.h",
    "content": "/**\n * @file mark.h\n */\n#ifndef MARK_H\n#define MARK_H\n\n#include \"common.h\"\n#include <geom.h>\n#include <bsp.h>\n#include <vec.h>\n#include <sw.h>\n\n// Forward.\nstruct SO;\nstruct XP; // TODO: Figure out where this should be defined at.\n\n/**\n * @brief (?) kind.\n */\nenum XPK\n{\n    XPK_Nil = -1\n};\n\n/**\n * @brief Material kind?\n */\nenum MTLK\n{\n    MTLK_Nil = -1,\n    MTLK_Default = 0,\n    MTLK_Sand = 1,\n    MTLK_Metal = 2,\n    MTLK_Wood = 3,\n    MTLK_Rock = 4,\n    MTLK_Rubber = 5,\n    MTLK_Ice = 6,\n    MTLK_Tire = 7,\n    MTLK_Velcro = 8,\n    MTLK_NoBounce = 9,\n    MTLK_NoFriction = 10,\n    MTLK_NoFrictionElastic = 11,\n    MTLK_Max = 12\n};\n\n/**\n * @brief Unknown.\n */\nstruct SBI\n{\n    VECTOR pos;\n    VECTOR normal;\n    float gDist;\n    XPK xpk;\n    // ...\n};\n\nfloat MuFromAmtlk(MTLK *amtlk);\n\nfloat ElasFromAmtlk(MTLK *amtlk);\n\nXP *PxpAdd(SO *pso0, SO *pso1, VECTOR *ppos, VECTOR *pnormal, float gDist, XPK xpk, void *pv0, void *pv1, XP **ppxpFirst);\n\nvoid RecalcSwXpPos(SW *psw, int cpxp, XP **apxp);\n\nvoid RecalcSwXpMovement(SW *psw, int cpxp, XP **apxp);\n\nvoid FreeSwXpList(SW *psw, XP *pxpFirst);\n\nvoid FindClosestPointOnLine(VECTOR *ppos, VECTOR *pposSeg0, VECTOR *pposSeg1, float *pu, float *ps);\n\nvoid FindClosestPointOnLineSegment(VECTOR *ppos, VECTOR *pposSeg0, VECTOR *pposSeg1, float *pu, float *ps);\n\nint ClsgClipSoAllEdges(SO *pso0, SO *pso1, BSP *pbsp, int clsgMax, LSG *alsg);\n\nint ClsgClipSoBspEdges(SO *pso0, SO *pso1, int cbspPruned, BSP *abspPruned, int clsgMax, LSG *alsg);\n\nvoid CategorizeAlsg(int clsg, LSG *alsg, int *pciposEmbed, int *aiposEmbed, LSG **aplsgEmbed, LSG **pplsgEdge);\n\nint CplsgFindEdgePath(SURF *asurf, int isurf, int isurfTarget, LSG *plsgEdge, LSG **aplsg);\n\nvoid MarkSoContactsBspBsp(SO *pso0, SO *pso1, int cbspPruned, BSP *abspPruned, BSP *pbspPruned, XP **ppxpFirst);\n\nint CsbiIntersectSphereBsp(VECTOR *pposCenter, float sRadius, int cbsp, BSP *absp, BSP *pbspPrune, GEOM *pgeom, int csbiMax, SBI *asbi);\n\nvoid MarkSoContactsSphereBsp(SO *pso0, VECTOR *pposCenter, float sRadius, SO *pso1, int cbsp, BSP *absp, BSP *pbspPrune, XP **ppxpFirst);\n\nvoid MarkSoContactsSphereSphere(SO *pso0, SO *pso1, XP **ppxpFirst);\n\nvoid CalculateCenterContact(SO *pso, VECTOR *pnormal, float gDot, VECTOR *ppos, float *ps);\n\nint FMarkSoContactsCenterBsp(SO *pso0, SO *pso1, int cbspPruned, BSP *abspPruned, BSP *pbspPruned, XP **ppxpFirst);\n\nint FClipEdgeToSphere(VECTOR *pposSphere, float sRadius, VECTOR *ppos0, VECTOR *ppos1, float *pu, VECTOR *ppos, VECTOR *pnormal, float *pgDot);\n\nint FMarkSoContactsCenterSphere(SO *pso0, SO *pso1, XP **ppxpFirst);\n\nvoid AddSoXps(SO *psoRoot, SO *psoOther, int fCenterXp, int cbspPruned, BSP *abspPruned, BSP *pbspPruned, XP **ppxpFirst);\n\nXP *PxpMarkSwContactsRoot(SW *psw, SO **apso, int fCenterXp);\n\n#endif // MARK_H\n"
  },
  {
    "path": "include/mat.h",
    "content": "/**\n * @file mat.h\n *\n * @brief 3x3 and 4x4 matrix types.\n*/\n#ifndef MAT_H\n#define MAT_H\n\n#include <vec.h>\n\n/**\n * @brief 4x4 Matrix\n*/\nstruct MATRIX4\n{\n\tfloat mat[4][4];\n};\n\n/**\n * @brief 3x3 Matrix\n*/\nstruct MATRIX3\n{\n\tfloat mat[3][3];\n};\n\nvoid PostCopyMatrix3(MATRIX4 *pmat);\n\nMATRIX3 *MatMulMatTransMat(MATRIX3 *matLeft, MATRIX3 *matRight);\n\nvoid LoadIdentityMatrix4(MATRIX4 *pmat);\n\nvoid MultiplyMatrix4Vector(MATRIX4 *pmat4, VECTOR *pvecIn, float gImplied, VECTOR *pvecOut);\n\nvoid TransposeMatrix4(MATRIX4 *pmatSrc, MATRIX4 *pmatDst);\n\nvoid AddMatrix4Matrix4(MATRIX4 *pmatLeft, MATRIX4 *pmatRight, MATRIX4 *pmatDst);\n\nvoid LoadRotateMatrixRad(float rad, VECTOR *pnormal, MATRIX3 *pmat);\n\nvoid LoadRotateMatrix(VECTOR *pvec, MATRIX3 *pmat);\n\nvoid LoadRotateMatrixEuler(VECTOR *peul, MATRIX3 *pmatRot);\n\nvoid LoadMatrixFromPosRot(VECTOR *ppos, MATRIX3 *pmat, MATRIX4 *pmatDst);\n\nvoid LoadMatrixFromPosRotInverse(VECTOR *pposSrc, MATRIX3 *pmatSrc, MATRIX4 *pmatDst);\n\nvoid LoadMatrixFromPosRotScale(VECTOR *pvecPos, MATRIX3 *pmatRot, VECTOR *pvecScale, MATRIX4 *pmat);\n\nfloat CosRotateMatrixMagnitude(MATRIX3 *pmat);\n\nvoid DecomposeRotateMatrixRad(MATRIX3 *pmat, float *prad, VECTOR *pnormal);\n\nvoid DecomposeRotateMatrixEuler(MATRIX3 *pmat, VECTOR *peul);\n\nvoid NormalizeRotateMatrix3(MATRIX3 *pmat);\n\nvoid CalculateDmat(MATRIX3 *pmat0, MATRIX3 *pmat1, MATRIX3 *pdmat);\n\nvoid CalculateDmat4(MATRIX4 *pmat0, MATRIX4 *pmat1, MATRIX4 *pdmat);\n\nvoid DecomposeRotateMatrixPanTilt(MATRIX3 *pmat, float *pradPan, float *pradTilt);\n\nvoid LoadRotateMatrixPanTilt(float radPan, float radTilt, MATRIX3 *pmat);\n\nvoid LoadLookAtMatrix(VECTOR *pdpos, MATRIX3 *pmat);\n\nvoid TiltMatUpright(MATRIX3 *pmat, MATRIX3 *pdmat, MATRIX3 *pmatUpright);\n\nbool FInvertMatrix(int c, float *aagSrc, float *aagDst);\n\nbool FInvertMatrix3(MATRIX3 *pmatSrc, MATRIX3 *pmatDst);\n\nbool FInvertMatrix4(MATRIX4 *pmatSrc, MATRIX4 *pmatDst);\n\nvoid BuildOrthonormalMatrixY(VECTOR *pvecX, VECTOR *pvecY, MATRIX3 *pmat);\n\nvoid BuildOrthonormalMatrixZ(VECTOR *pvecX, VECTOR *pvecZ, MATRIX3 *pmat);\n\nvoid BuildRotateVectorsMatrix(VECTOR *pvec1, VECTOR *pvec2, MATRIX3 *pmat);\n\n/**\n * @brief Creates a perspective projection matrix with optional center offsets.\n *\n * @param rx Horizontal field-of-view scale.\n * @param ry Vertical field-of-view scale.\n * @param dxOffset Horizontal offset of the projection center.\n * @param dyOffset Vertical offset of the projection center.\n * @param sFar Far plane distance.\n * @param sNear Near plane distance.\n * @param pmat Pointer to the output.\n */\nvoid BuildSimpleProjectionMatrix(float rx, float ry, float dxOffset, float dyOffset, float sFar, float sNear, MATRIX4 *pmat);\n\nvoid LoadScaleMatrixScalar(VECTOR *ppos, float rScale, MATRIX4 *pmatScale);\n\nvoid LoadScaleMatrixVector(VECTOR *ppos, MATRIX3 *pmat, VECTOR *pvecScale, MATRIX4 *pmatScale);\n\nvoid LoadRotateVectorMatrix(VECTOR *pvecFrom, VECTOR *pvecTo, MATRIX3 *pmat);\n\n#endif // MAT_H\n"
  },
  {
    "path": "include/mb.h",
    "content": "/**\n * @file mb.h\n *\n * @brief Mesa boss.\n */\n#ifndef MB_H\n#define MB_H\n\n#include <stepguard.h>\n\n/**\n * @class MS_BOSS_GUARD\n * @brief Mesa boss guard (Muggshot).\n */\nstruct MBG : public STEPGUARD\n{\n    // ...\n};\n\n#endif // MB_H\n"
  },
  {
    "path": "include/memcard.h",
    "content": "/**\n * @file memcard.h\n */\n#ifndef MEMCARD_H\n#define MEMCARD_H\n\n#include \"common.h\"\n\n/**\n * @todo Incomplete.\n */\nstruct MEMCARD\n{\n    /* 0x00 */ int semaphoreId;\n    /* 0x04 */ int threadId;\n    /* 0x08 */ int field_0x08;\n    /* 0x0c */ int field_0x0c;\n    /* 0x10 */ int field_0x10;\n};\n\n/**\n * @note Judging from the memset in InitSave,\n * this struct could be over 20k bytes long.\n */\nstruct SAVE\n{\n    int field_0x00;\n    // ...\n};\n\n/**\n * @brief Startup the memory card system.\n */\nvoid StartupMemcard();\n\nvoid UpdateSave(SAVE *psave);\n\nextern SAVE g_save;\n\n#endif // MEMCARD_H\n"
  },
  {
    "path": "include/memory.h",
    "content": "/**\n * @file memory.h\n */\n#ifndef MEMORY_H\n#define MEMORY_H\n\n#include \"common.h\"\n\ntypedef struct _reent;\n\n/**\n * @brief Starts up the memory manager system.\n */\nvoid StartupMemMgr();\n\n/**\n * @brief Allocates memory from the global heap.\n *\n * @param cb Size in bytes.\n *\n * @return Pointer to the allocated memory.\n */\nvoid *PvAllocGlobalImpl(int cb);\n\n#ifdef PROTO\n/**\n * @brief Shows an error message on the screen.\n * @note Called if we have run out of memory on the stack.\n *\n * @param rgba Background color for the text box.\n */\nvoid HardLockError(RGBA *rgba);\n#endif\n\n/**\n * @brief Stubbed, does nothing.\n *\n * @note Would have checked to see if we are out of stack memory.\n *\n * @deprecated\n */\nvoid CheckForOutOfMemory();\n\n/**\n * @brief Allocates memory for an SW.\n *\n * @param cb Size in bytes.\n *\n * @return Pointer to the allocated memory.\n */\nvoid *PvAllocSwImpl(int cb);\n\n/**\n * @brief Clears the SW stack.\n */\nvoid FreeSw();\n\n/**\n * @brief Allocates memory for an SW and copies data to it.\n *\n * @param cb Size of the block in bytes.\n * @param pvBase Data to copy.\n *\n * @return Pointer to the allocated memory.\n */\nvoid *PvAllocSwCopyImpl(int cb, void *pvBase);\n\n/**\n * @brief Allocates memory for an SW and clears it.\n *\n * @param cb Size in bytes.\n *\n * @return Pointer to the allocated memory.\n */\nvoid *PvAllocSwClearImpl(int cb);\n\n/**\n * @brief Initializes a new allocation frame on the stack.\n */\nvoid InitStackImpl();\n\n/**\n * @brief Allocates memory on the stack.\n *\n * @param cb Size in bytes.\n *\n * @note Rounds up `cb` to next multiple of 16.\n */\nvoid *PvAllocStackImpl(int cb);\n\n/**\n * @brief Allocates memory on the stack and clears it.\n *\n * @param cb Size in bytes.\n *\n * @note Rounds up `cb` to next multiple of 16.\n */\nvoid *PvAllocStackClearImpl(int cb);\n\n/**\n * @brief Unravels the current stack allocation frame.\n */\nvoid FreeStackImpl();\n\nextern \"C\"\n{\n    void *malloc(uint __size);\n    void *_malloc_r(_reent *pre, uint __size);\n    void free(void *pv);\n}\n\n/**\n * @brief Copies an array of quadwords (16-byte blocks).\n *\n * @param pvDst Destination pointer.\n * @param pvSrc Source pointer.\n * @param cqw Number of quadwords to copy (16 bytes each).\n *\n * @note Total bytes copied will be `cqw * 16`.\n */\nvoid CopyAqw(void *pvDst, void *pvSrc, int cqw);\n\n/**\n * @brief Copies an array of bytes.\n *\n * @param pvDst Destination pointer.\n * @param pvSrc Source pointer.\n * @param cb Number of bytes to copy.\n */\nvoid CopyAb(void *pvDst, void *pvSrc, uint cb);\n\n#endif // MEMORY_H\n"
  },
  {
    "path": "include/missile.h",
    "content": "/**\n * @file missile.h\n */\n#ifndef MISSILE_H\n#define MISSILE_H\n\n#include \"common.h\"\n#include <bomb.h>\n#include <bis.h>\n#include <vec.h>\n#include <alo.h>\n#include <cm.h>\n\n// Forward.\nstruct RO;\n\n/**\n * @class MISSILE\n * @brief Missile (maybe the ones fired by smartguards?).\n * @todo Implement the struct.\n */\nstruct MISSILE : public BOMB\n{\n    // ...\n    /* 0x6b4 */ ASEGA *pasegaCur;\n    /* 0x6b8 */ int fFollowTrajectory;\n    // ...\n};\n\n/**\n * @class ACCEL_MISSILE\n * @brief Accelerating missile.\n * @todo Implement the struct.\n */\nstruct ACCMISS : public MISSILE\n{\n    // ...\n};\n\n/**\n * @class TARGET_MISSILE\n * @brief Target missile.\n * @todo Implement the struct.\n */\nstruct TARMISS : public MISSILE\n{\n    // ...\n};\n\n/**\n * @class SPLINE_MISSILE\n * @brief Spline missile.\n * @todo Implement the struct.\n */\nstruct SPLMISS : public MISSILE\n{\n    // ...\n};\n\n/**\n * @class GROUND_MISSILE\n * @brief Ground missile.\n * @todo Implement the struct.\n */\nstruct GROUNDMISS : public MISSILE\n{\n    // ...\n};\n\nvoid InitMissile(MISSILE *pmissile);\n\nvoid LoadMissileFromBrx(MISSILE *pmissile, CBinaryInputStream *pbis);\n\nvoid OnMissileRemove(MISSILE *pmissile);\n\nvoid ProjectMissileTransform(MISSILE *pmissile, float dt, int fParentDirty);\n\nvoid FireMissile(MISSILE *pmissile, ALO *paloTarget, VECTOR *pposTargetLocal);\n\nvoid RenderMissileAll(MISSILE *pmissile, CM *pcm, RO *pro);\n\n\nvoid InitAccmiss(ACCMISS *paccmiss);\n\nvoid FireAccmiss(ACCMISS *paccmiss, ALO *paloTarget, VECTOR *pposTarget);\n\nvoid PresetAccmissAccel(ACCMISS *paccmiss, float dt);\n\n\nvoid FireSplmiss(SPLMISS *psplmiss, ALO *paloTarget, VECTOR *pposTargetLocal);\n\nvoid ProjectSplmissTransform(SPLMISS *psplmiss, float dt, int fParentDirty);\n\n#endif // MISSILE_H\n"
  },
  {
    "path": "include/mpeg.h",
    "content": "/**\n * @file mpeg.h\n *\n * @brief Mpeg video.\n */\n#ifndef MPEG_H\n#define MPEG_H\n\n#include \"common.h\"\n#include <oid.h>\n#include <bas.h>\n\nclass CMpeg\n{\npublic:\n    OID oid_1;\n    OID oid_2;\n    // todo\n\n    void ExecuteOids();\n    void Execute(OID *poid);\n    void Start(CBinaryAsyncStream *pbas);\n    void Update();\n    void Finish();\n};\n\nvoid StartupMpeg();\n\nextern CMpeg g_mpeg;\n\n#endif // MPEG_H\n"
  },
  {
    "path": "include/mq.h",
    "content": "/**\n * @file mq.h\n *\n * @brief Message queue.\n */\n#ifndef MQ_H\n#define MQ_H\n\n#include \"common.h\"\n\ntypedef int GRFCMQ; // TODO: Does this belong to mq.h?\n\n/**\n * @brief Message ID\n *\n * @note Based on values from May 19, may not be accurate to release.\n */\nenum MSGID\n{\n    MSGID_Nil = -1,\n    MSGID_callback = 0,\n    MSGID_added = 1,\n    MSGID_removed = 2,\n    MSGID_translated = 3,\n    MSGID_rotated = 4,\n    MSGID_asega_limit = 5,\n    MSGID_asega_retracted = 6,\n    MSGID_asega_wrapped = 7,\n    MSGID_sfx_start = 8,\n    MSGID_sfx_end = 9,\n    MSGID_water_entered = 10,\n    MSGID_water_left = 11,\n    MSGID_button_trigger = 12,\n    MSGID_button_untrigger = 13,\n    MSGID_break_break = 14,\n    MSGID_break_piece = 15,\n    MSGID_rip_removed = 16,\n    MSGID_color_change = 17,\n    MSGID_user_message = 18,\n    MSGID_label = 19,\n    MSGID_sma_transition = 20,\n    MSGID_waypoint = 21,\n    MSGID_waypoint_transition = 22,\n    MSGID_damaged = 23,\n    MSGID_param_read = 24,\n    MSGID_param_write = 25,\n    MSGID_Max = 26\n};\n\ntypedef void (*PFNMQ)(void *, MSGID, void *);\n\n/**\n * @brief Message queue(?)\n */\nstruct MQ\n{\n    /* 0x00 */ PFNMQ pfnmq;\n    /* 0x04 */ void *pvContext;\n    /* 0x08 */ MSGID msgid;\n    /* 0x0c */ void *pvCallbackData;\n    /* 0x10 */ MQ *pmqNext;\n};\n\n#endif // MQ_H\n"
  },
  {
    "path": "include/mrkv.h",
    "content": "/**\n * @file mrkv.h\n */\n#ifndef MRKV_H\n#define MRKV_H\n\n#include \"common.h\"\n#include <so.h>\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct MRKV : public SO\n{\n    // ...\n};\n\nvoid InitMrkv(MRKV *pmrkv);\n\n#endif // MRKV_H\n"
  },
  {
    "path": "include/ms.h",
    "content": "/**\n * @file Unknown.\n */\n\n#include \"common.h\"\n#include <cm.h>\n\nstruct RO; // todo define this struct somewhere\n\n/**\n * @class MERGED_STATICS\n * @brief Unknown.\n */\nstruct MS\n{\n    // ...\n};\n\nvoid RenderMsGlobset(MS *pms, CM *pcm, RO *pro);\n"
  },
  {
    "path": "include/murray.h",
    "content": "/**\n * @file murray.h\n *\n * @brief \"The Murray\".\n */\n#ifndef MURRAY_H\n#define MURRAY_H\n\n#include \"common.h\"\n#include <stepguard.h>\n#include <turret.h>\n#include <xform.h>\n\n// Forward.\nstruct WKR;\n\n/**\n * @class MURRAY\n * @brief Used for Murray in Murray's Big Gamble and King of the Hill.\n * @todo Implement the struct.\n */\nstruct MURRAY : public STEPGUARD\n{\n    // ...\n};\n\nvoid InitMurray(MURRAY *pmurray);\n\nvoid PostMurrayLoad(MURRAY *pmurray);\n\nvoid OnMurrayEnteringSgs(MURRAY *pmurray, SGS sgsPrev, ASEG *pasegOverride);\n\nvoid OnMurrayExitingSgs(MURRAY *pmurray, SGS sgs);\n\nvoid UpdateMurrayGoal(MURRAY *pmurray, int fEnter);\n\nvoid UpdateMurraySgs(MURRAY *pmurray);\n\nint FAbsorbMurrayWkr(MURRAY *pmurray, WKR *pwkr);\n\nint FDetectMurray(MURRAY *pmurray);\n\n/**\n * @brief Always returns false and never gets called anywhere.\n */\nint FCanMurrayAttack(MURRAY *pmurray);\n\nvoid AddMurrayEnemy(MURRAY *pmurray, ALO *paloEnemy);\n\nvoid SetMurrayPursueXfm(MURRAY *pmurray, XFM *pxfm);\n\nvoid SetMurrayPatrolXfm(MURRAY *pmurray, XFM *pxfm);\n\nvoid CollectMurrayPrize(MURRAY *pmurray, PCK pck, ALO *paloOther);\n\n#endif // MURRAY_H\n"
  },
  {
    "path": "include/oid.h",
    "content": "/**\n * @file oid.h\n *\n * @brief Object IDs.\n */\n#ifndef OID_H\n#define OID_H\n\n#include \"common.h\"\n\n/**\n * @brief Object ID.\n */\nenum OID\n{\n    OID_Nil = -1,\n    OID_Unknown = 0x0,\n    OID__MERGED_STATICS = 0x1,\n    OID__VISIBILITY_MAP = 0x2,\n    OID__WORLD = 0x3,\n    OID__CAMERA = 0x4,\n    OID_jt = 0x5,\n    OID_bentley = 0x6,\n    OID_murray = 0x7,\n\n    // ...\n\n    OID_shd_stock_shadow = 0x2c,\n\n    // ...\n\n    OID_rat = 0x269,\n\n    // ...\n\n    OID_state_ubb_round_2 = 0x2da,\n    OID_state_ubb_round_3 = 0x2db,\n\n    // ...\n\n    OID_state_ubb_dunk = 0x2e0,\n\n    // ...\n};\n\n#endif // OID_H\n"
  },
  {
    "path": "include/path.h",
    "content": "/**\n * @file path.h\n */\n#ifndef PATH_H\n#define PATH_H\n\n#include \"common.h\"\n\n// ...\n\n#endif // PATH_H\n"
  },
  {
    "path": "include/phasemem.h",
    "content": "/**\n * @file phasemem.h\n */\n#ifndef PHASEMEM_H\n#define PHASEMEM_H\n\n#include \"common.h\"\n\n/**\n * @brief Engine phase.\n */\nenum PHASE\n{\n    PHASE_Nil = -1,\n    PHASE_None = 0,\n    PHASE_Startup = 1,\n    PHASE_Load = 2,\n    PHASE_Main = 3,\n    PHASE_Mpeg = 4,\n    PHASE_Max = 5\n};\n\n/**\n * @brief Current engine phase.\n */\nextern PHASE g_phase;\n\n/**\n * @brief Set the current engine phase.\n */\nvoid SetPhase(PHASE phase);\n\n/**\n * @brief Clear the current engine phase.\n */\nvoid ClearPhase(PHASE phase);\n\n#endif // PHASEMEM_H\n"
  },
  {
    "path": "include/pipe.h",
    "content": "/**\n * @file pipe.h\n */\n#ifndef PIPE_H\n#define PIPE_H\n\n#include \"common.h\"\n#include <lo.h>\n\n/**\n * @class PIPE\n * @brief Pipe that JT can climb on.\n * @todo Implement the struct.\n */\nstruct PIPE : public LO\n{\n    /* 0x34 */ undefined4 unk;\n    /* 0x38 */ DLE dlePipe;\n    /* 0x40 */ STRUCT_PADDING(9);\n    /* 0x64 */ OID oid; // TODO: Verify name.\n    /* 0x68 */ LO *plo; // TODO: Verify type and name.\n};\n\nvoid StartupPipe();\n\nvoid ResetPipeList();\n\nvoid InitPipe(PIPE *ppipe);\n\nvoid OnPipeAdd(PIPE *ppipe);\n\nvoid OnPipeRemove(PIPE *ppipe);\n\nvoid PostPipeLoad(PIPE *ppipe);\n\nvoid ClonePipe(PIPE *ppipe, PIPE *ppipeBase);\n\n#endif // PIPE_H\n"
  },
  {
    "path": "include/pnt.h",
    "content": "/**\n * @file pnt.h\n *\n * @brief Points.\n */\n#ifndef PNT_H\n#define PNT_H\n\n#include \"common.h\"\n#include <proxy.h>\n#include <vec.h>\n#include <bis.h>\n#include <alo.h>\n#include <lo.h>\n\n/**\n * @class POINT\n * @brief Object defined only by a point in space.\n */\nstruct PNT : public LO\n{\n    /* 0x34 */ STRUCT_PADDING(3); // This could be a vector, something like posGlobal?\n    /* 0x40 */ VECTOR posLocal;\n};\n\n/**\n * @class POINT_WITH_SPEED\n * @brief Object defined by a point in space with a velocity.\n */\nstruct PNTSV : PNT\n{\n    // ...\n};\n\n/**\n * @class POINT_WITH_DISTANCE\n * @brief Object defined by a point in space with a distance.\n */\nstruct PNTS : PNT\n{\n    // ...\n};\n\n/**\n * @class POINT_WITH_VECTOR\n * @brief Object defined by a point in space with a vector.\n */\nstruct PNTVEC : PNT\n{\n    // ...\n};\n\nvoid LoadPntFromBrx(PNT *ppnt, CBinaryInputStream *pbis);\n\nvoid GetPntPos(PNT *ppnt, VECTOR *ppos);\n\nvoid SetPntParent(PNT *ppnt, ALO *paloParent);\n\nvoid ApplyPntProxy(PNT *ppnt, PROXY *pproxyApply);\n\n#endif // PNT_H\n"
  },
  {
    "path": "include/po.h",
    "content": "/**\n * @file po.h\n *\n * @brief Player object.\n */\n#ifndef PO_H\n#define PO_H\n\n#include \"common.h\"\n#include <dialog.h>\n#include <zap.h>\n#include <so.h>\n\n// Forward.\nstruct ALO;\nstruct AMB;\nstruct CPDEFI;\n\n/**\n * @brief (?) kind.\n * @todo This should maybe be moved to pzo.h?\n */\nenum PCK\n{\n    PCK_Nil = -1,\n    PCK_Key = 0,\n    PCK_Gold = 1,\n    PCK_Max = 2\n};\n\n/**\n * @todo Unknown.\n * @note Based on proto, may be inaccurate.\n */\nstruct PZI\n{\n    int fCollectEnabled;\n    ALO *paloBag;\n    ALO *mpccharmpaloCharm[5];\n    float sAutoCollect;\n    ALO *paloCollect;\n};\n\n/**\n * @class PO\n * @brief Used for playable objects (e.g. JT).\n *\n * @note Based on proto, may be inaccurate.\n */\nstruct PO : public SO\n{\n    /* 0x550 */ int fPlayable;\n    int fLockBase;\n    VECTOR posBasePrev;\n    float tWakeRipple;\n    AMB *pambWake;\n    PZI pzi;\n    ALO *paloUseCharm;\n};\n\nvoid InitPo(PO *ppo);\n\nvoid ClonePo(PO *ppo, PO *ppoBase);\n\nvoid HandlePoMessage(PO *ppo, MSGID msgid, void *pv);\n\nvoid OnPoActive(PO *ppo, int fActive, PO *ppoOther);\n\nvoid GetPoCpdefi(PO *ppo, float dt, CPDEFI *pcpdefi);\n\nint FIsPoSoundBase(PO * ppo);\n\n/**\n * @brief Switch to the given PO, if it isn't the currently active one.\n */\nvoid MakePoActive(PO *ppo);\n\nint FInvulnerablePo(PO *ppo, ZPK zpk);\n\nint FTakePoDamage(PO *ppo, ZPR *pzpr);\n\n// JTHS JthsCurrentPo(PO *ppo); // TODO: Fix includes.\n\n/**\n * @brief Collect a prize.\n */\nvoid CollectPoPrize(PO *ppo, PCK pck, ALO *paloOther);\n\n/**\n * @brief Gets a pointer to the current PO.\n */\nPO *PpoCur();\n\nPO *PpoStart(void);\n\n/**\n * @brief Finds the index of the given PO (?)\n */\nint _IppoFindPo(PO *ppo);\n\n/**\n * @brief Add the given PO to the list.\n */\nvoid AddPoToList(PO *ppo);\n\n/**\n * @brief Remove the given PO from the list.\n */\nvoid RemovePoFromList(PO *ppo);\n\n/**\n * @brief Adds the given PO to the list and then calls an unknown function.\n */\nvoid OnPoAdd(PO *ppo);\n\n/**\n * @brief Removes the given PO from the list and then calls an unknown function.\n */\nvoid OnPoRemove(PO *ppo);\n\n/**\n * @brief Unknown.\n */\nvoid SwitchToIppo(int index);\n\n/**\n * @brief Unknown.\n */\nvoid SetPoPlayable(PO *ppo, int playable);\n\n/**\n * @brief Switch to the given PO.\n */\nvoid SwitchToPo(PO *ppo);\n\nPZI *PpziCur();\n\nvoid GetPoDiapi(PO *ppo, DIALOG *pdialog, DIAPI *pdiapi);\n\nvoid PlayPoDialog(PO *ppo, DIALOG *pdialog);\n\n/**\n * @brief Update the PO.\n */\nvoid UpdatePo(PO *ppo, float dt);\n\n/**\n * @brief Use a charm.\n */\nvoid UsePoCharm(PO *ppo);\n\n#endif // PO_H\n"
  },
  {
    "path": "include/prog.h",
    "content": "/**\n * @file prog.h\n *\n * @brief Progress bar.\n */\n#ifndef PROG_H\n#define PROG_H\n\n#include \"common.h\"\n#include <binoc.h>\n\nclass CProg\n{\n    int m_fActive;\n    int m_nMax;\n    int m_nTarget;\n    int m_nRemain;\n    int m_cRetry;\n\n    RGBA m_rgbaComplete;\n    RGBA m_rgbaRemain;\n    RGBA m_rgbaWarning;\n    RGBA m_rgbaTrouble;\n\npublic:\n    /**\n     * @brief Initializes CProg with RGBA values.\n     *\n     * @param rgbaComplete Color of the filled portion of the bar (e.g. blue or green).\n     * @param rgbaRemain Color of the unfilled portion of the bar (e.g. gray).\n     * @param rgbaWarning Color of the bar if there's a warning (e.g. yellow).\n     * @param rgbaTrouble Color of the bar if there's trouble (e.g. red)\n     */\n    CProg(RGBA *rgbaComplete, RGBA *rgbaRemain, RGBA *rgbaWarning, RGBA *rgbaTrouble);\n\n    /**\n     * @brief Zeroes out the variables.\n     *\n     */\n    void Begin();\n\n    /**\n     * @brief Clear's Frame Buffers, updates remain and calls draw.\n     *\n     * @param nRemain new Remain value.\n     */\n    void SetRemain(int nRemain);\n\n    /**\n     * @brief Zeroes out the variables.\n     *\n     */\n    void End();\n\n    /**\n     * @brief Draws the progress bar on the screen with the current colors.\n     */\n    void Draw();\n};\n\n#endif // PROG_H\n"
  },
  {
    "path": "include/proxy.h",
    "content": "/**\n * @file proxy.h\n */\n#ifndef PROXY_H\n#define PROXY_H\n\n#include \"common.h\"\n#include <alo.h>\n#include <bis.h>\n#include <dl.h>\n\n/**\n * @brief Unknown.\n */\nstruct PROXY : public ALO\n{\n    DL dlProxyRoot;\n    DLE dleProxy;\n    undefined4 unk_0x8;\n    undefined4 unk_0xC;\n    undefined4 unk_0x10;\n};\n\nvoid InitProxy(PROXY *pproxy);\n\nvoid LoadProxyFromBrx(PROXY *pproxy, CBinaryInputStream *pbis);\n\nvoid CloneProxy(PROXY *pproxy, PROXY *pproxyBase);\n\nvoid PostProxyLoad(PROXY *pproxy);\n\n#endif // PROXY_H\n"
  },
  {
    "path": "include/puffer.h",
    "content": "/**\n * @file puffer.h\n *\n * @brief Piranha Lake in Vicious Voodoo (believed to be formerly called \"Pufferfish Pond\").\n */\n#ifndef PUFFER_H\n#define PUFFER_H\n\n#include \"common.h\"\n#include <stepguard.h>\n#include <water.h>\n#include <bis.h>\n#include <joy.h>\n#include <so.h>\n#include <mq.h>\n\n/**\n * @class PUFFER\n * @brief Piranha fish used in Piranha Lake.\n * @todo Implement the struct.\n */\nstruct PUFFER : public PO\n{\n    // ...\n};\n\n/**\n * @class PUFFER_COLLECTION\n * @brief Collection of piranha fish.\n * @todo Implement the struct.\n */\nstruct PUFFC : public ALO\n{\n    // ...\n};\n\n/**\n * @class PUFFER_BRAIN\n * @brief AI controller for piranha fish.\n * @todo Implement the struct.\n */\nstruct PUFFB : public ALO\n{\n    // ...\n};\n\n/**\n * @class PUFFER_TORCH\n * @brief Tiki torch object in Piranha Lake.\n * @todo Implement the struct.\n */\nstruct PUFFT : public SO\n{\n    // ...\n};\n\nvoid InitPuffer(PUFFER *ppuffer);\n\nvoid LoadPufferFromBrx(PUFFER *ppuffer, CBinaryInputStream *pbis);\n\nvoid PostPufferLoad(PUFFER *ppuffer);\n\nvoid PresetPufferAccel(PUFFER *ppuffer, float dt);\n\nint FFilterPuffer(PUFFER *ppuffer, SO *psoOther);\n\nvoid UpdatePuffer(PUFFER *ppuffer, float dt);\n\nPUFFT *PpufftChoosePuffer(PUFFER *ppuffer);\n\nvoid OnPufferActive(PUFFER *ppuffer, int fActive, PO *ppoOther);\n\nvoid UpdatePufferActive(PUFFER *ppuffer, JOY *pjoy, float dt);\n\nvoid AddPufferWaterAcceleration(PUFFER *ppuffer, WATER *pwater, float dt);\n\nvoid HandlePufferMessage(PUFFER *ppuffer, MSGID msgid, void *pv);\n\nvoid PostPuffcLoad(PUFFC *ppuffc);\n\nvoid PresetPuffcAccel(PUFFC *ppuffc, float dt);\n\nvoid UpdatePuffcGoal(PUFFC *ppuffc, int fEnter);\n\nvoid OnPuffcExitingSgs(PUFFC *ppuffc, SGS sgsNext);\n\nvoid OnPuffcEnteringSgs(PUFFC *ppuffc, SGS sgsPrev, ASEG *pasegOverride);\n\nvoid UpdatePuffcSgs(PUFFC *ppuffc);\n\nvoid HandlePuffcMessage(PUFFC *ppuffc, MSGID msgid, void *pv);\n\nvoid UpdatePuffc(PUFFC *ppuffc, float dt);\n\nint FCanPuffcAttack(PUFFC *ppuffc);\n\nvoid PostPuffbLoad(PUFFB *ppuffb);\n\n#endif // PUFFER_H\n"
  },
  {
    "path": "include/pzo.h",
    "content": "/**\n * @file pzo.h\n *\n * @brief Vaults, clue bottles, keys and locks.\n */\n#ifndef PZO_H\n#define PZO_H\n\n#include \"common.h\"\n#include <joy.h>\n#include <alo.h>\n#include <so.h>\n#include <po.h>\n#include <sm.h>\n#include <cm.h>\n\n// Forward.\nstruct RO;\nstruct WKR;\n\n/**\n * @brief Something (?) clue state?\n */\nenum PCS\n{\n    PCS_Nil = -1,\n    PCS_Collected = 0,\n    PCS_Collectible = 1,\n    PCS_NotCollectible = 2,\n    PCS_Max = 3\n};\n\n/**\n * @brief Goal advice dialog kind (?)\n */\nenum GOADK\n{\n    GOADK_Nil = -1,\n    GOADK_LessThanHalf = 0,\n    GOADK_MoreThanHalf = 1,\n    GOADK_Most = 2,\n    GOADK_AllButOne = 3,\n    GOADK_All = 4,\n    GOADK_Max = 5\n};\n\n/**\n * @class _SPRIZE\n * @brief Base class for SPRIZEs.\n */\nstruct SPRIZE : public SO\n{\n    // ...\n};\n\n/**\n * @class _SCPRIZE\n * @brief Base class for SCPRIZEs.\n */\nstruct SCPRIZE : public SPRIZE\n{\n    // ...\n};\n\n/**\n * @class CLUE\n * @brief Clue bottle.\n */\nstruct CLUE : public SPRIZE\n{\n    // ...\n};\n\n/**\n * @class LOCK\n * @brief Treasure key lock.\n */\nstruct LOCK : public ALO\n{\n    // ...\n};\n\n/**\n * @class LOCK_GROUP\n * @brief Group of treasure key lock objects.\n */\nstruct LOCKG : public ALO\n{\n    STRUCT_PADDING(3);\n    /* 0x2DC */ uint coidLock;\n    /* 0x2E0 */ OID aoidLock[8];\n};\n\n/**\n * @class VAULT\n * @brief Vault used for unlocking thief moves in levels.\n */\nstruct VAULT : public PO\n{\n    // ...\n};\n\n/**\n * @brief Vault tumbler.\n */\nstruct TMBL\n{\n    ALO *palo;\n    SM *psmDial;\n    SMA *psmaDial;\n};\n\nvoid InitSprize(SPRIZE *psprize);\n\nvoid LoadSprizeFromBrx(SPRIZE *psprize, CBinaryInputStream *pbis);\n\nvoid BindSprize(SPRIZE *psprize);\n\nvoid PostSprizeLoad(SPRIZE *psprize);\n\nvoid UpdateSprize(SPRIZE *psprize, float dt);\n\nvoid CollectSprize(SPRIZE *psprize);\n\nvoid EmitSprizeExplosion(SPRIZE *psprize);\n\nPCS PcsFromSprize(SPRIZE *psprize);\n\nvoid AddSprizeAseg(SPRIZE *psprize, OID oidAseg);\n\nvoid HandleSprizeMessage(SPRIZE *psprize, MSGID msgid, void *pv);\n\nint FIgnoreSprizeIntersection(SPRIZE *psprize, SO *psoOther);\n\nvoid InitScprize(SCPRIZE *pscprize);\n\nvoid CloneScprize(SCPRIZE *pscprize, SCPRIZE *pscprizeBase);\n\nPCS PcsFromScprize(SCPRIZE *pscprize);\n\nvoid CollectScprize(SCPRIZE *pscprize);\n\n/**\n * @brief Loads a LOCK object from a binary input stream.\n *\n * @param plock Pointer to the LOCK to initialize.\n * @param pbis Pointer to the binary input stream to read from.\n */\nvoid LoadLockFromBrx(LOCK *plock, CBinaryInputStream *pbis);\n\n/**\n * @brief Sets up a LOCK object after loading.\n *\n * @param plock Pointer to the LOCK object.\n */\nvoid PostLockLoad(LOCK *plock);\n\n/**\n * @brief Loads a LOCKG object from a binary input stream.\n *\n * @param plockg Pointer to the LOCKG to initialize.\n * @param pbis Pointer to the binary input stream to read from.\n */\nvoid LoadLockgFromBrx(LOCKG *plockg, CBinaryInputStream *pbis);\n\n/**\n * @brief Sets up a LOCKG object after loading.\n *\n * @param plockg Pointer to the LOCKG object.\n */\nvoid PostLockgLoad(LOCKG *plockg);\n\n/**\n * @brief Sets the index of the LOCKG object(?)\n *\n * @param plockg Pointer to the LOCKG object.\n * @param ifws Index to set.\n */\nvoid SetLockgIndex(LOCKG *plockg, int ifws);\n\n/**\n * @brief Adds a lock to the given lock group.\n *\n * @param plockg Pointer to the LOCKG object.\n * @param oidLock OID of the LOCK to add.\n */\nvoid AddLockgLock(LOCKG *plockg, OID oidLock);\n\nvoid TriggerLockg(LOCKG *plockg);\n\nvoid InitClue(CLUE *pclue);\n\nvoid LoadClueFromBrx(CLUE *pclue, CBinaryInputStream *pbis);\n\nvoid CloneClue(CLUE *pclue, CLUE *pclueBase);\n\nvoid PostClueLoad(CLUE *pclue);\n\nvoid OnClueSmack(CLUE *pclue);\n\nvoid CollectClue(CLUE *pclue);\n\nvoid BreakClue(CLUE *pclue);\n\nvoid CollectClueSilent(CLUE *pclue);\n\nvoid ImpactClue(CLUE *pclue, int fParentDirty);\n\nint FAbsorbClueWkr(CLUE *pclue, WKR *pwkr);\n\nvoid RenderClueAll(CLUE *pclue, CM *pcm, RO *pro);\n\nvoid CollectAllClues(int nParam);\n\nvoid SetGrfvault(int grfvault);\n\nvoid InitVault(VAULT *pvault);\n\nvoid PostTmblLoad(TMBL *ptmbl, OID oidInitialState);\n\nvoid PostVaultLoad(VAULT *pvault);\n\nvoid OnVaultActive(VAULT *pvault, int fActive, PO *ppoOther);\n\nvoid UpdateVaultActive(VAULT *pvault, JOY *pjoy, float dt);\n\nvoid HandleVaultMessage(VAULT *pvault, MSGID msgid, void *pv);\n\nvoid AddVaultGoadDialog(VAULT *pvault, GOADK goadk, OID oidDialog);\n\n#endif // PZO_H\n"
  },
  {
    "path": "include/rail.h",
    "content": "/**\n * @file rail.h\n */\n#ifndef RAIL_H\n#define RAIL_H\n\n#include \"common.h\"\n#include <shape.h>\n#include <dl.h>\n\n/**\n * @class RAIL\n * @brief Rail that JT can walk/slide on.\n * @todo Check if the field names are correct.\n */\nstruct RAIL : public SHAPE\n{\n    /* 0x38 */ DLE dleRail;\n    /* 0x40 */ int fSlippery;\n    /* 0x44 */ float svMax;\n    /* 0x48 */ float rdvGravity;\n    /* 0x4c */ float unk1;\n    /* 0x50 */ undefined4 unk2;\n    /* 0x54 */ OID oid;\n    /* 0x58 */ LO *plo;\n};\n\nvoid InitRail(RAIL *prail);\n\nvoid OnRailAdd(RAIL *prail);\n\nvoid OnRailRemove(RAIL *prail);\n\nvoid PostLoadRail(RAIL *prail);\n\nvoid CloneRail(RAIL *prail, RAIL *prailBase);\n\n#endif // RAIL_H\n"
  },
  {
    "path": "include/rat.h",
    "content": "/**\n * @file rat.h\n *\n * @brief Rats.\n */\n#ifndef RAT_H\n#define RAT_H\n\n#include \"common.h\"\n#include <flash.h>\n#include <bis.h>\n#include <so.h>\n#include <lo.h>\n#include <cm.h>\n\n// Forward.\nstruct XP;\nstruct WKR;\n\n/**\n * @brief Rat state.\n */\nenum RATS\n{\n    RATS_Nil = -1,\n    RATS_Stopped = 0,\n    RATS_Scurry = 1,\n    RATS_Flee = 2,\n    RATS_Dead = 3,\n    RATS_Hidden = 4,\n    RATS_Max = 5\n};\n\n/**\n * @class RAT\n * @brief Rat animal.\n * @todo Implement the struct.\n */\nstruct RAT : public SO\n{\n    // ...\n    /* 0x55c */ float tRatSqueak;\n    /* 0x560 */ STRUCT_PADDING(40);\n    /* 0x600 */ DLE dleRat;\n    /* 0x608 */ LM lmDtStop;\n    /* 0x610 */ STRUCT_PADDING(21);\n    /* 0x664 */ int ccoin;\n    // ...\n};\n\n/**\n * @class RATHOLE\n * @brief Hole where rats come from/go to.\n * @todo Implement the struct.\n */\nstruct RATHOLE : public LO\n{\n    // ...\n};\n\nvoid InitRat(RAT *prat);\n\nvoid LoadRatFromBrx(RAT *prat, CBinaryInputStream *pbis);\n\nvoid PostRatLoad(RAT *prat);\n\nvoid OnRatAdd(RAT *prat);\n\nvoid OnRatRemove(RAT *prat);\n\nvoid CloneRat(RAT *prat, RAT *pratBase);\n\nvoid PresetRatAccel(RAT *prat, float dt);\n\nvoid UpdateRat(RAT *prat, float dt);\n\nvoid AdjustRatNewXp(RAT *prat, XP *pxp, int ixpd);\n\nvoid AdjustRatXpVelocity(RAT *prat, XP *pxp, int ixpd);\n\nvoid RenderRatAll(RAT *prat, CM *pcm, RO *pro);\n\nint FAbsorbRatWkr(RAT *prat, WKR *pwkr);\n\nvoid ChooseRatFleeTarget(RAT *prat);\n\nvoid HideRat(RAT *prat, int fHide);\n\nvoid SetRatRats(RAT *prat, RATS rats);\n\nvoid OnRatholeAdd(RATHOLE *prathole);\n\nvoid OnRatholeRemove(RATHOLE *prathole);\n\n#endif // RAT_H\n"
  },
  {
    "path": "include/rchm.h",
    "content": "/**\n * @file rchm.h\n */\n#ifndef RCHM_H\n#define RCHM_H\n\n#include \"common.h\"\n#include <target.h>\n#include <pipe.h>\n#include <vec.h>\n#include <bsp.h>\n#include <lo.h>\n#include <jt.h>\n\n/**\n * @brief Unknown.\n */\nstruct TWR\n{\n    int aipos[4];\n};\n\n/**\n * @class REACH_MAP\n * @brief Spatial map determining where JT can reach with his cane.\n * @todo Implement the struct.\n */\nstruct RCHM : public LO\n{\n    /* 0x34 */ OID oidHost;\n    /* 0x38 */ OID oidTouch;\n    /* 0x3c */ STRUCT_PADDING(6);\n    /* 0x54 */ float rclNatural;\n    /* 0x58 */ float ioNatural;\n    /* 0x5c */ float lhubNatural;\n    /* 0x60 */ STRUCT_PADDING(8);\n    /* 0x80 */ int fCenterSet;\n    // ...\n};\n\nvoid InitRchm(RCHM *prchm);\n\nvoid LoadRchmFromBrx(RCHM *prchm, CBinaryInputStream *pbis);\n\nvoid PostRchmLoad(RCHM *prchm);\n\nvoid ReblendRchm(RCHM *prchm, TWR *ptwr, VECTOR *ppos);\n\nvoid BuildRchmCoefficients(RCHM *prch, float rcl, float io, float lhub, float *mpiblu);\n\nvoid ConvertRchmIposToRclIoLhub(RCHM *prchm, int ipos, float *prcl, float *pio, float *plhub);\n\nvoid SetRchmNaturalCoefficients(RCHM *prchm, float rcl, float io, float lhub);\n\nvoid SetRchmCenterCoefficients(RCHM *prchm, float rcl, float io, float lhub);\n\nvoid PredictRchmTargetPos(RCHM *prchm, TARGET *ptarget, float dt, VECTOR *ppos);\n\nvoid PredictRchmTargetLocalPos(RCHM *prchm, TARGET *ptarget, float dt, VECTOR *pposLocal);\n\nTWR *PtwrMapRchmSafe(RCHM *prchm, BSP *pbsp, VECTOR *ppos);\n\nvoid FindRchmClosestPoint(RCHM *prchm, VECTOR *ppos, VECTOR *pposClosest, TWR **pptwr, float *ps);\n\nvoid TrackJtTarget(JT *pjt, RCHM *prchm, TARGET *ptarget);\n\nvoid TrackJtPipe(JT *pjt, RCHM *prchm, PIPE *ppipe, float *psPipe);\n\n#endif // RCHM_H\n"
  },
  {
    "path": "include/render.h",
    "content": "/**\n * @file render.h\n *\n * @brief Rendering system.\n */\n#ifndef RENDER_H\n#define RENDER_H\n\n#include \"common.h\"\n#include <sw.h>\n#include <cm.h>\n#include <dmas.h>\n#include <gifs.h>\n\n/**\n * @brief Unknown.\n */\nenum RP\n{\n    RP_Nil = -1,\n    RP_DynamicTexture = 0,\n    RP_Background = 1,\n    RP_BlotContext = 2,\n    RP_Opaque = 3,\n    RP_Cutout = 4,\n    RP_CelBorder = 5,\n    RP_ProjVolume = 6,\n    RP_OpaqueAfterProjVolume = 7,\n    RP_CutoutAfterProjVolume = 8,\n    RP_CelBorderAfterProjVolume = 9,\n    RP_MurkClear = 10,\n    RP_MurkOpaque = 11,\n    RP_MurkFill = 12,\n    RP_Translucent = 13,\n    RP_TranslucentCelBorder = 14,\n    RP_Blip = 15,\n    RP_Foreground = 16,\n    RP_WorldMap = 17,\n    RP_Max = 18\n};\n\n/**\n * @brief Render Primitive List (?)\n * @todo Implement the struct.\n */\nstruct RPL\n{\n    undefined4 *pfndraw; // NOTE: This is a function pointer.\n    float z;\n    RP rp;\n    // ...\n};\n\nvoid SubmitRpl(RPL *prpl);\n\nint NCmpPrplReverseZ(RPL **pprpl1, RPL **pprpl2);\n\nint CprplPartitionArpl(int cprpl, RPL *arpl, RPL **aprpl);\n\n/**\n * @brief Renders the given SW with the given camera.\n *\n * @param psw Pointer to the SW object.\n * @param pcm Pointer to the camera.\n */\nvoid RenderSw(SW *psw, CM *pcm);\n\nvoid EnsureRenderGlobals();\n\nvoid EnsureCameraGlobals();\n\nvoid EnsureScreenCleared();\n\nvoid SetupRpDynamicTexture(RPL *prpl);\n\nvoid SetupRpBackground(RPL *prpl);\n\nvoid SetupRpBlotContext(RPL *prpl);\n\nvoid SetupRpGlob(RPL *prpl);\n\nvoid SetupRpBlip(RPL *prpl);\n\nvoid SetupRpWorldMap(RPL *prpl);\n\n/**\n * @brief Draws the given SW with the given camera.\n *\n * @param psw Pointer to the SW object.\n * @param pcm Pointer to the camera.\n */\nvoid DrawSw(SW *psw, CM *pcm);\n\n/**\n * @brief Fills a rectangular area of the screen with a specified color and alpha value.\n *\n * @param r The red component of the fill color (0-255).\n * @param g The green component of the fill color (0-255).\n * @param b The blue component of the fill color (0-255).\n * @param alpha The alpha (transparency) value of the fill (0-255).\n * @param xLeft The left x-coordinate of the rectangle.\n * @param yTop The top y-coordinate of the rectangle.\n * @param xRight The right x-coordinate of the rectangle.\n * @param yBottom The bottom y-coordinate of the rectangle.\n * @param pgifs Pointer to a GIFS structure used for rendering.\n */\nvoid FillScreenRect(int r, int g, int b, int alpha, float xLeft, float yTop, float xRight, float yBottom, GIFS *pgifs);\n\n/**\n * @briefs Starts up the rendering system.\n */\nvoid StartupRender();\n\n#endif // RENDER_H\n"
  },
  {
    "path": "include/rip.h",
    "content": "/**\n * @file rip.h\n *\n * @brief Particle system (?)\n */\n#ifndef RIP_H\n#define RIP_H\n\n#include \"common.h\"\n#include <blip.h>\n#include <vec.h>\n#include <so.h>\n#include <lo.h>\n#include <cm.h>\n\n// Forward.\nstruct RO;\nstruct RIPG;\n\n// TODO: Does this belong here or puffer.h?\nstruct PUFF;\n\n// TODO: Add to vtables.\nstruct VTRIP;\n\n/**\n * @brief (?) particle type?\n * @note All of these values are taken straight\n * from the prototype so they may be incorrect.\n */\nenum RIPT\n{\n    RIPT_Nil = -1,\n    RIPT_Rip = 0,\n    RIPT_Shadow = 1,\n    RIPT_Droplet = 2,\n    RIPT_Bublet = 3,\n    RIPT_Ripple = 4,\n    RIPT_Puff = 5,\n    RIPT_Dablet = 6,\n    RIPT_Flake = 7,\n    RIPT_Spark = 8,\n    RIPT_Burst = 9,\n    RIPT_Trail = 10,\n    RIPT_Fireball = 11,\n    RIPT_SmokeCloud = 12,\n    RIPT_SmokeTrail = 13,\n    RIPT_Debris = 14,\n    RIPT_Orbit = 15,\n    RIPT_Smack = 16,\n    RIPT_Ray = 17,\n    RIPT_Rose = 18,\n    RIPT_Flying = 19,\n    RIPT_Stuck = 20,\n    RIPT_Leaf = 21,\n    RIPT_Flame = 22,\n    RIPT_Bullet = 23,\n    RIPT_Shrapnel = 24,\n    RIPT_Glint = 25,\n    RIPT_Match = 26,\n    RIPT_Emitter = 27,\n    RIPT_Max = 28\n};\n\n/**\n * @brief (?) type?\n */\nenum RIPGT\n{\n    RIPGT_Nil = -1,\n    RIPGT_Default = 0,\n    RIPGT_Bounce = 1,\n    RIPGT_Loot = 2,\n    RIPGT_Max = 3\n};\n\n/**\n * @brief Rose state.\n */\nenum ROSES\n{\n    ROSES_Nil = -1,\n    ROSES_Closing = 0,\n    ROSES_Spinning = 1,\n    ROSES_Opening = 2,\n    ROSES_Max = 3\n};\n\n/**\n * @brief Unknown.\n */\nenum TRLS\n{\n    TRLS_Nil = -1,\n    TRLS_None = 0,\n    TRLS_TrackingRip = 1,\n    TRLS_TrackingAlo = 2,\n    TRLS_ChainingRip = 3,\n    TRLS_Max = 4\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct RIP\n{\n    STRUCT_PADDING(2);\n    int cref;\n    RIPG *pripg;\n    // ...\n};\n\n/**\n * @brief (?) group?\n * @todo Implement the struct.\n */\nstruct RIPG : public SO\n{\n    // ...\n};\n\n/**\n * @brief Rose.\n * @todo Implement the struct.\n */\nstruct ROSE : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct DROPLET : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct BUBLET : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct RIPPLE : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct DABLET : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct FLAKE : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct SPARK : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct BURST : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct TRAIL : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct FIREBALL : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct SMOKETRAIL : public TRAIL\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct DEBRIS : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct SMOKECLOUD : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct SMACK : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ORBIT : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct RAY : public SPARK\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct FLYING : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct STUCK : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct LEAF : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct FLAME : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct BULLET : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct SHRAPNEL : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct GLINT : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct MATCH : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct REMIT : public RIP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct HP\n{\n    VECTOR pos;\n    VECTOR posHull;\n    float radHull;\n    float sEdge;\n    float sCorner;\n    int xhpKey;\n};\n\nRIPG *PripgNew(SW *psw, RIPGT ripgt);\n\nvoid InitRipg(RIPG *pripg);\n\nvoid SetRipgEmitb(RIPG *pripg, EMITB *pemitb);\n\nvoid OnRipgRemove(RIPG *pripg);\n\nvoid ProjectRipgTransform(RIPG *pripg, float dt, int fForce);\n\nvoid UpdateRipgBounds(RIPG *pripg);\n\nvoid UpdateRipg(RIPG *pripg, float dt);\n\nvoid BounceRipgRips(RIPG *pripg);\n\nvoid RenderRipgSelf(RIPG *pripg, CM *pcm, RO *pro);\n\nVTRIP *PvtripFromRipt(RIPT ript);\n\nRIP *PripNewRipg(RIPT ript, RIPG *pripg);\n\nvoid InitRip(RIP *prip, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid RemoveRip(RIP *prip);\n\nvoid AddRipRef(RIP *prip);\n\nvoid ReleaseRip(RIP *prip);\n\nvoid TouchRip(RIP *prip, int fTouching);\n\nvoid ForceRipFade(RIP *prip, float dtFade);\n\nint FBounceRip(RIP *prip, SO *psoOther, VECTOR *ppos, VECTOR *pnormal);\n\nvoid ProjectRipTransform(RIP *prip, float dt);\n\nvoid UpdateRip(RIP *prip, float dt);\n\nint FRenderRipPosMat(RIP *prip, CM *pcm, VECTOR *ppos, MATRIX3 *pmat);\n\nvoid RenderRip(RIP *prip, CM *pcm);\n\nvoid SubscribeRipObject(RIP *prip, LO *ploTarget);\n\nvoid SubscribeRipStruct(RIP *prip, PFNMQ pfnmq, void *pvContext);\n\nvoid UnsubscribeRipStruct(RIP *prip, PFNMQ pfnmq, void *pvContext);\n\nvoid InitDroplet(DROPLET *pdroplet, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid TouchDroplet(DROPLET *pdroplet, int fTouching);\n\nvoid InitBublet(BUBLET *pbublet, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid ProjectBubletTransform(BUBLET *pbublet, float dt);\n\nvoid TouchBublet(BUBLET *pbublet, int fTouching);\n\nvoid InitRipple(RIPPLE *pripple, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid InitPuff(PUFF *ppuff, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid InitDablet(DABLET *pdablet, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid InitFlake(FLAKE *pflake, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid UpdateFlake(FLAKE *pflake, float dt);\n\nvoid RenderFlake(FLAKE *pflake, CM *pcm);\n\nvoid TouchFlake(FLAKE *pflake, int fTouching);\n\nvoid InitSpark(SPARK *pspark, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid RenderSpark(SPARK *pspark, CM *pcm);\n\nvoid InitBurst(BURST *pburst, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid InitTrail(TRAIL *ptrail, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid OnTrailRemove(TRAIL *ptrail);\n\nvoid SetTrailTrls(TRAIL *ptrail, TRLS trls, void *pv);\n\nvoid DetachTrail(TRAIL *ptrail);\n\nvoid ProjectTrailTransform(TRAIL *ptrail, float dt);\n\nvoid RenderTrail(TRAIL *ptrail, CM *pcm);\n\nvoid HandleTrailMessage(TRAIL *ptrail, MSGID msgid, void *pv);\n\nvoid InitFireball(FIREBALL *pfireball, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid UpdateFireball(FIREBALL *pfireball, float dt);\n\nvoid InitSmokecloud(SMOKECLOUD *psmokecloud, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid InitSmoketrail(SMOKETRAIL *psmoketrail, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid InitDebris(DEBRIS *pdebris, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid InitSmack(SMACK *psmack, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid ProjectSmackTransform(SMACK *psmack, float dt);\n\nvoid RenderSmack(SMACK *psmack, CM *pcm);\n\nvoid UpdateSmack(SMACK *psmack, float dt);\n\nvoid InitOrbit(ORBIT *porbit, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid ProjectOrbitTransform(ORBIT *porbit, float dt);\n\nvoid UpdateOrbit(ORBIT *porbit, float dt);\n\nvoid RenderOrbit(ORBIT *porbit, CM *pcm);\n\nvoid InitRay(RAY *pray, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid InitRose(ROSE *prose, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid ProjectRoseTransform(ROSE *prose, float dt);\n\nvoid UpdateRose(ROSE *prose, float dt);\n\nvoid RenderRose(ROSE *prose, CM *pcm);\n\nvoid SetRoseRoses(ROSE *prose, ROSES roses);\n\nint SgnCmpHp(void *pv0, void *pv1);\n\nint ChpBuildConvexHullScreen(VECTOR *pposCenter, int chp, HP *ahp);\n\nint ChpBuildConvexHullXY(MATRIX4 *pdmat, int chp, HP *ahp);\n\nvoid PostFlyingEmit(FLYING *pflying, EMITB *pemitb);\n\nvoid RenderFlying(FLYING *pflying, CM *pcm);\n\nvoid CreateStuck(RIP *pripSrc, ALO *paloRender, SO *psoOther, VECTOR *ppos, VECTOR *pnormal, STUCK **ppstuck);\n\nint FBounceFlying(FLYING *pflying, SO *psoOther, VECTOR *ppos, VECTOR *pnormal);\n\nvoid UpdateStuck(STUCK *pstuck, float dt);\n\nvoid RenderStuck(STUCK *pstuck, CM *pcm);\n\nvoid PostLeafEmit(LEAF *pleaf, EMITB *pemitb);\n\nvoid ProjectLeafTransform(LEAF *pleaf, float dt);\n\nint FBounceLeaf(LEAF *pleaf, SO *psoOther, VECTOR *ppos, VECTOR *pnormal);\n\nint FFilterFlameObjects(void *pv, SO *pso);\n\nvoid PostFlameEmit(FLAME *pflame, EMITB *pemitb);\n\nvoid PostBulletEmit(BULLET *pbullet, EMITB *pemitb);\n\nvoid RenderBullet(BULLET *pbullet, CM *pcm);\n\nint FBounceBullet(BULLET *pbullet, SO *psoOther, VECTOR *ppos, VECTOR *pnormal);\n\nvoid PostShrapnelEmit(SHRAPNEL *pshrapnel, EMITB *pemitb);\n\nint FBounceShrapnel(SHRAPNEL *pshrapnel, SO *psoOther, VECTOR *ppos, VECTOR *pnormal);\n\nvoid RenderShrapnel(SHRAPNEL *pshrapnel, CM *pcm);\n\nvoid InitGlint(GLINT *pglint, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid RenderGlint(GLINT *pglint, CM *pcm);\n\nvoid InitMatch(MATCH *pmatch, VECTOR *ppos, float gScale, SO *psoTouch);\n\nvoid LaunchMatch(MATCH *pmatch);\n\nvoid ProjectMatchTransform(MATCH *pmatch, float dt);\n\nvoid UpdateMatch(MATCH *pmatch, float dt);\n\nvoid RenderMatch(MATCH *pmatch, CM *pcm);\n\nvoid PostRemitEmit(REMIT *premit, EMITB *pemitb);\n\nvoid UpdateRemit(REMIT *premit, float dt);\n\n#endif // RIP_H\n"
  },
  {
    "path": "include/rog.h",
    "content": "/**\n * @file rog.h\n *\n * @note At the time of writing, all the enum values were taken\n * straight from the prototype, so they may be incorrect/incomplete.\n */\n#ifndef ROG_H\n#define ROG_H\n\n#include \"common.h\"\n#include <ensure.h>\n#include <oid.h>\n#include <joy.h>\n#include <po.h>\n#include <mq.h>\n\n// Forward.\nstruct XP;\nstruct DZ;\nstruct FX;\nstruct WKR;\n\ntypedef int GRFSG;\n\n/**\n * @brief (?) state.\n */\nenum ROVS\n{\n    ROVS_Nil = -1,\n    ROVS_Brake = 0,\n    ROVS_Drive = 1,\n    ROVS_Descend = 2,\n    ROVS_Ascend = 3,\n    ROVS_Max = 4\n};\n\n/**\n * @brief (?) state.\n */\nenum ROBS\n{\n    ROBS_Nil = -1,\n    ROBS_Descend = 0,\n    ROBS_Instruct = 1,\n    ROBS_Normal = 2,\n    ROBS_Lose = 3,\n    ROBS_Win = 4,\n    ROBS_Ascend = 5,\n    ROBS_Max = 6\n};\n\n/**\n * @brief (?) state.\n */\nenum ROVTS\n{\n    ROVTS_Nil = -1,\n    ROVTS_Calm = 0,\n    ROVTS_Firing = 1,\n    ROVTS_Max = 2\n};\n\n/**\n * @brief (?) state.\n */\nenum ROHS\n{\n    ROHS_Nil = -1,\n    ROHS_Inactive = 0,\n    ROHS_Spawn = 1,\n    ROHS_Wander = 2,\n    ROHS_Collect = 3,\n    ROHS_Grab = 4,\n    ROHS_Return = 5,\n    ROHS_Exit = 6,\n    ROHS_Happy = 7,\n    ROHS_Sad = 8,\n    ROHS_Die = 9,\n    ROHS_Dead = 10,\n    ROHS_Max = 11\n};\n\n/**\n * @brief (?) state.\n */\nenum ROCS\n{\n    ROCS_Nil = -1,\n    ROCS_Rest = 0,\n    ROCS_Hit1 = 1,\n    ROCS_Hit2 = 2,\n    ROCS_Hit3 = 3,\n    ROCS_Hit4 = 4,\n    ROCS_Hit5 = 5,\n    ROCS_Hit6 = 6,\n    ROCS_Hit7 = 7,\n    ROCS_Hit8 = 8,\n    ROCS_Destroyed = 9,\n    ROCS_Max = 10\n};\n\n/**\n * @brief (?) state.\n */\nenum ROPS\n{\n    ROPS_Nil = -1,\n    ROPS_StayPut = 0,\n    ROPS_Reveal = 1,\n    ROPS_Collect = 2,\n    ROPS_Collected = 3,\n    ROPS_Max = 4\n};\n\n/**\n * @brief (?) state.\n */\nenum ROSTS\n{\n    ROSTS_Nil = -1,\n    ROSTS_Close = 0,\n    ROSTS_Open = 1,\n    ROSTS_Max = 2\n};\n\n/**\n * @brief (?) kind.\n */\nenum ROBK\n{\n    ROBK_Nil = -1,\n    ROBK_Primary = 0,\n    ROBK_Secondary = 1,\n    ROBK_Tertiary = 2,\n    ROBK_Max = 3\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ROV : public PO\n{\n    /* 0x610 */ ROVS rovs;\n    /* 0x614 */ ROVTS rovts;\n    /* 0x618 */ float radJoyLeft;\n    /* 0x61c */ float uJoyDeflectLeft;\n    /* 0x620 */ float radJoyRight;\n    /* 0x624 */ float uJoyDeflectRight;\n    /* 0x628 */ float svMax;\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ROB : public ALO\n{\n    // ...\n    /* 0x2e0 */ int coidRost;\n    /* 0x2e4 */ OID aoidRost[16]; // TODO: Verify size.\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ROH : public SO\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ROC : public SO\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ROST : public SO\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ROP : public SO\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct RODD\n{\n    // ...\n};\n\nvoid InitRov(ROV *prov);\n\nvoid LoadRovFromBrx(ROV *prov, CBinaryInputStream *pbis);\n\nvoid PostRovLoad(ROV *prov);\n\nvoid UpdateRovActive(ROV *prov, JOY *pjoy, float dt);\n\nvoid UpdateRov(ROV *prov, float dt);\n\nvoid ReadRovJoystick(ROV *prov, JOY *pjoy);\n\nROVS RovsNextRov(ROV *prov);\n\nvoid SetRovRovs(ROV *prov, ROVS rovs);\n\nROVTS RovtsNextRov(ROV *prov);\n\nvoid SetRovRovts(ROV *prov, ROVTS rovts);\n\nvoid HandleRovMessage(ROV *prov, MSGID msgid, void *pv);\n\nvoid PresetRovAccel(ROV *prov, float dt);\n\nvoid AdjustRovXpVelocity(ROV *prov, XP *pxp, int ixpd);\n\nvoid AdjustRovNewXp(ROV *prov, XP *pxp, int ixpd);\n\nvoid PropagateRovForce(ROV *prov, GRFSG grfsg, XP *pxp, int ixpd, DZ *pdz, FX *afx);\n\nint FIsRovSoundBase(ROV *prov);\n\nvoid InitRob(ROB *prob);\n\nvoid SetRobCollectible(ROB *prob, OID oidCollectible);\n\nvoid SetRobHarvester(ROB *prob, OID oidHarvester);\n\nvoid SetRobVehicle(ROB *prob, OID oidVehicle);\n\nvoid SetRobPrize(ROB *prob, OID oidPrize);\n\nvoid AddRobSpawnTunnel(ROB *prob, OID oidSpawnTunnel);\n\nROBK RobkCur();\n\nvoid BindRob(ROB *prob);\n\nvoid PostRobLoad(ROB *prob);\n\nvoid UpdateRob(ROB *prob, float dt);\n\nROBS RobsNextRob(ROB *prob);\n\nvoid SetRobRobs(ROB *prob, ROBS robs);\n\nvoid AddRobRoc(ROB *prob);\n\nvoid AddRobRoh(ROB *prob);\n\nvoid AdjustRobDifficulty(ROB *prob, float rRoc);\n\nvoid DestroyedRobRoc(ROB *prob, ROC *proc);\n\nvoid SpawnedRobRoh(ROB *prob, ROH *proh);\n\nvoid GrabbedRobRoh(ROB *prob, ROH *proh);\n\nvoid DroppedRobRoh(ROB *prob, ROH *proh);\n\nvoid ReturnedRobRoh(ROB *prob, ROH *proh);\n\nvoid ExitedRobRoh(ROB *prob, ROH *proh);\n\nvoid KilledRobRoh(ROB *prob, ROH *proh);\n\nint FChooseRobRoc(ROB *prob, ROH *proh);\n\nvoid TakeRobRoc(ROB *prob, ROH *proh, ROC *proc);\n\nint FChooseRobRoh(ROB *prob, ROC *proc);\n\nint FChooseRobReturnPoint(ROB *prob, ROH *proh);\n\nvoid ChooseRobWanderLocation(ROB *prob, ROH *proh);\n\nRODD *ProddCurRob(ROB *prob, ENSK ensk);\n\nvoid InitRoh(ROH *proh);\n\nvoid LoadRohFromBrx(ROH *proh, CBinaryInputStream *pbis);\n\nvoid CloneRoh(ROH *proh, ROH *prohBase);\n\nvoid PostRohLoad(ROH *proh);\n\nvoid UpdateRoh(ROH *proh, float dt);\n\nvoid MoveRohToTarget(ROH *proh, VECTOR *ppos, int fBackwards);\n\nROHS RohsNextRoh(ROH *proh);\n\nvoid SetRohRohs(ROH *proh, ROHS rohs);\n\nint FAbsorbRohWkr(ROH *proh, WKR *pwkr);\n\nROC *ProcContactRoh(ROH *proh);\n\nvoid InitRoc(ROC *proc);\n\nvoid LoadRocFromBrx(ROC *proc, CBinaryInputStream *pbis);\n\nvoid CloneRoc(ROC *proc, ROC *procBase);\n\nvoid PostRocLoad(ROC *proc);\n\nvoid UpdateRoc(ROC *proc, float dt);\n\nvoid PresetRocAccel(ROC *proc, float dt);\n\nvoid AdjustRocNewXp(ROC *proc, XP *pxp, int ixpd);\n\nint FAbsorbRocWkr(ROC *proc, WKR *pwkr);\n\nROCS RocsNextRoc(ROC *proc);\n\nvoid SetRocRocs(ROC *proc, ROCS rocs);\n\nvoid InitRost(ROST *prost);\n\nvoid LoadRostFromBrx(ROST *prost, CBinaryInputStream *pbis);\n\nvoid CloneRost(ROST *prost, ROST *prostBase);\n\nvoid PostRostLoad(ROST *prost);\n\nvoid UpdateRost(ROST *prost, float dt);\n\nROSTS RostsNextRost(ROST *prost);\n\nvoid SetRostRosts(ROST *prost, ROSTS rosts);\n\nvoid InitRop(ROP *prop);\n\nvoid LoadRopFromBrx(ROP *prop, CBinaryInputStream *pbis);\n\nvoid PostRopLoad(ROP *prop);\n\nvoid UpdateRop(ROP *prop, float dt);\n\nvoid SetRopRops(ROP *prop, ROPS rops);\n\nROPS RopsNextRop(ROP *prop);\n\n#endif // ROG_H\n"
  },
  {
    "path": "include/rs.h",
    "content": "/**\n * @file rs.h\n *\n * @note No functions are declared here.\n */\n#ifndef RS_H\n#define RS_H\n\n#include \"common.h\"\n#include <oid.h>\n\n/**\n * @brief Unknown.\n *\n * @todo Figure out what this struct represents.\n */\nstruct RSMG\n{\n    OID oidRoot;\n    OID oidSM;\n    OID oidTriggerGoal;\n    OID oidUntriggerGoal;\n};\n\n#endif // RS_H\n"
  },
  {
    "path": "include/rumble.h",
    "content": "/**\n * @file rumble.h\n *\n * @brief Joypad rumble.\n */\n#ifndef RUMBLE_H\n#define RUMBLE_H\n\n#include \"common.h\"\n\nstruct JOY; // Forward declaration\n\n/**\n * @brief Rumble state\n */\nenum RUMS\n{\n    RUMS_Dead = 0,\n    RUMS_Idle = 1,\n    RUMS_Rumble = 2,\n    RUMS_Stop = 3,\n    RUMS_Kill = 4,\n    RUMS_Max = 5\n};\n\n/**\n * @brief Rumble kind\n */\nenum RUMK\n{\n    RUMK_Nil = -1,\n    RUMK_SteadyBuzz = 0,\n    RUMK_LowThrob = 1,\n    RUMK_MediumThrob = 2,\n    RUMK_HardThrob = 3,\n    RUMK_Blunt = 4,\n    RUMK_Electric = 5,\n    RUMK_Fire = 6,\n    RUMK_Water = 7,\n    RUMK_Crush = 8,\n    RUMK_Break = 9,\n    RUMK_Bomb = 10,\n    RUMK_Max = 11\n};\n\n/**\n * @brief Rumble intensity\n */\nstruct RUMINS\n{\n    byte fHighSpeedMotor;\n    byte bLowSpeedMotor;\n    byte unk1;\n    byte unk2;\n    float dt;\n};\n\n/**\n * @brief Rumble pattern\n */\nstruct RUMPAT\n{\n    int crumins;\n    RUMINS arumins[32];\n};\n\n/**\n * @brief Rumble\n *\n * Combines the rumble state, rumble pattern, and rumble intensity along with the\n * port and slot of the controller.\n */\nstruct RUMBLE\n{\n    /* 0x00 */ STRUCT_PADDING(1); // TODO: Add vtable.\n    /* 0x04 */ int nPort;\n    /* 0x08 */ int nSlot;\n    /* 0x0c */ RUMS rums;\n    RUMPAT *prumpat;\n    int irumins;\n    float dtRumble;\n    float dtRumins;\n};\n\nvoid InitRumble(RUMBLE *prumble, int nPort, int nSlot);\n\nvoid TriggerRumbleRumk(RUMBLE *prumble, RUMK rumk, float dt);\n\nvoid SetRumbleRums(RUMBLE *prumble, RUMS rums);\n\nvoid StopRumbleActuators(RUMBLE *prumble);\n\n#endif // RUMBLE_H\n"
  },
  {
    "path": "include/rwm.h",
    "content": "/**\n * @file rwm.h\n */\n#ifndef RWM_H\n#define RWM_H\n\n#include \"common.h\"\n#include <vec.h>\n#include <oid.h>\n#include <so.h>\n#include <lo.h>\n\n/**\n * @class AMMO_MANAGER\n * @brief Object representing a manager for projectile ammo.\n * @todo Implement the struct.\n */\nstruct RWM : public LO\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct RWTI\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct RWAC\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct RWFI\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct RWC\n{\n    // ...\n};\n\nvoid InitRwm(RWM *prwm);\n\nvoid PostRwmLoad(RWM *prwm);\n\nRWC *PrwcFindRwm(RWM *prwm, OID oidCache);\n\nvoid EnableRwmRwc(RWM *prwm, OID oidCache);\n\nvoid DisableRwmRwc(RWM *prwm, OID oidCache);\n\nvoid ResizeRwmRwc(RWM *prwm, OID oidCache, int cpso);\n\nint FIsRwmAmmo(RWM *prwm, SO *psoAmmo);\n\nint FAvailableRwmAmmo(RWM *prwm, SO *psoAmmo);\n\nvoid CycleRwmCache(RWM *prwm);\n\nvoid ReloadRwm(RWM *prwm);\n\nint FEnsureRwmLoaded(RWM *prwm);\n\nint FFireRwm(RWM *prwm, int fAim);\n\nvoid ClearRwmFireInfo(RWM *prwm);\n\nvoid ClearRwmTargetInfo(RWM *prwm);\n\nvoid ClearRwmAimConstraints(RWM *prwm);\n\nvoid GetRwfiPosMat(RWFI *prwfi, VECTOR *ppos, MATRIX3 *pmat);\n\nvoid GetRwtiPos(RWTI *prwti, VECTOR *pposSource, VECTOR *ppos);\n\nvoid GetRwacPan(RWAC *prwac, float *pradPan);\n\nvoid GetRwacTilt(RWAC *prwac, float *pradTilt);\n\n#endif // RWM_H\n"
  },
  {
    "path": "include/sb.h",
    "content": "/**\n * @file sb.h\n *\n * @brief Snow boss.\n */\n#ifndef SB_H\n#define SB_H\n\n#include <stepguard.h>\n\n/**\n * @class S_BOSS_GUARD\n * @brief Snow boss guard (Panda King).\n */\nstruct SBG : public STEPGUARD\n{\n    // ...\n};\n\nvoid PostSbgLoad(SBG *psbg);\n\nundefined4 FUN_001a9928(SBG *psbg);\n\nvoid UpdateSbgGoal(SBG *psbg, int fEnter);\n\nvoid UpdateSbgSgs(SBG *psbg, SGS sgsPrev, ASEG *pasegTargetOverride);\n\nvoid UpdateSbg(SBG *psbg, float dt);\n\n// ...\n\nint FAbsorbSbgWkr(SBG *psbg, WKR *pwkr);\n\n// ...\n\n#endif // SB_H\n"
  },
  {
    "path": "include/sce/libdma.h",
    "content": "/**\n * @file libdma.h\n *\n * @brief Direct memory access library.\n */\n#ifndef LIBDMA_H\n#define LIBDMA_H\n\ntypedef unsigned char u_char;\ntypedef unsigned short u_short;\ntypedef unsigned int u_int;\n\nextern \"C\"\n{\n    struct tD_CHCR\n    {\n        unsigned DIR : 1;   /* Direction */\n        unsigned pad0: 1;\n        unsigned MOD : 2;   /* Mode */\n        unsigned ASP : 2;   /* Address stack pointer */\n        unsigned TTE : 1;   /* Tag trasfer enable */\n        unsigned TIE : 1;   /* Tag interrupt enable */\n        unsigned STR : 1;   /* start */\n        unsigned pad1: 7;\n        unsigned TAG :16;   /* DMAtag */\n    };\n\n    struct _sceDmaTag\n    {\n        u_short qwc;       /* transfer count */\n        u_char mark;       /* mark */\n        u_char id;         /* tag */\n        _sceDmaTag *next;  /* next tag */\n        u_int p[2];        /* padding */\n    } __attribute__ ((aligned(16)));\n\n    struct sceDmaChan\n    {\n        tD_CHCR chcr; // Channel control\n        u_int p0[3];\n\n        volatile void *madr; // Transfer memory address\n        u_int p1[3];\n\n        volatile u_int qwc;  // Transfer count\n        u_int p2[3];\n\n        volatile _sceDmaTag *tadr; // Transfer tag address\n        u_int p3[3];\n\n        volatile void *as0; // Address stack 0\n        u_int p4[3];\n\n        volatile void *as1; // Address stack Dn_ASR1\n        u_int p5[3];\n\n        u_int p6[4]; // pad\n        u_int p7[4]; // pad\n\n        void* sadr; // SPR address\n        u_int p8[3];\n    };\n\n    /**\n     * @brief Get a DMA channel structure by ID\n     *\n     * @param id Channel number\n     * @return sceDmaChan*\n     */\n    sceDmaChan *sceDmaGetChan(int id);\n\n    /**\n     * @brief Reset the DMA controller\n     *\n     * @param mode 0 = disable, 1 = enable\n     * @return Previous mode before reset\n     */\n    int sceDmaReset(int mode);\n\n    // ...\n\n    /**\n     * @brief Start DMA transfer from memory to a device using Source Chain Mode.\n     *\n     * @param chan DMA channel for performing the transfer\n     * @param tag Starting address of the transfer list\n     */\n    void sceDmaSend(sceDmaChan *chan, void *tag);\n\n    /**\n     * @todo Document this function.\n     */\n    u_int sceDmaSync(sceDmaChan *pdmaChan, int mode, int timeout);\n}\n\n#endif // LIBDMA_H\n"
  },
  {
    "path": "include/sce/memset.h",
    "content": "/**\n * @file memset.h\n *\n * @brief Memset.\n */\n#ifndef MEMSET_H\n#define MEMSET_H\n#include <stddef.h>\n\nextern \"C\"\n{\n    void* memset(void* ptr, int value, size_t num);\n}\n\n#endif // MEMSET_H\n"
  },
  {
    "path": "include/sce/rand.h",
    "content": "/**\n * @file rand.h\n * @note /sce/ee/gcc/src/newlib/libc/stdlib/rand.c\n *\n * @brief Random number generation.\n */\n#ifndef RAND_H\n#define RAND_H\n\ntypedef unsigned int undefined4;\ntypedef unsigned int u_int;\n\nextern \"C\"\n{\n    struct RNG {\n        undefined4 field0_0x0;\n        undefined4 field1_0x4;\n        undefined4 field2_0x8;\n        undefined4 field3_0xc;\n        undefined4 field4_0x10;\n        undefined4 field5_0x14;\n        undefined4 field6_0x18;\n        undefined4 field7_0x1c;\n        undefined4 field8_0x20;\n        undefined4 field9_0x24;\n        undefined4 field10_0x28;\n        undefined4 field11_0x2c;\n        undefined4 field12_0x30;\n        undefined4 field13_0x34;\n        undefined4 field14_0x38;\n        undefined4 field15_0x3c;\n        undefined4 field16_0x40;\n        undefined4 field17_0x44;\n        undefined4 field18_0x48;\n        undefined4 field19_0x4c;\n        undefined4 field20_0x50;\n        undefined4 field21_0x54;\n        u_int next;\n    };\n\n    /**\n     * @brief Seed the random number generator.\n     */\n    void srand(u_int seed);\n\n    /**\n     * @brief Generate a random number.\n     */\n    u_int rand();\n};\n\n#endif // RAND_H\n"
  },
  {
    "path": "include/screen.h",
    "content": "/**\n * @file screen.h\n *\n * @brief GUI elements.\n */\n#ifndef SCREEN_H\n#define SCREEN_H\n\n#include \"common.h\"\n#include <font.h>\n#include <game.h>\n\nstruct SHD; // Forward declaration.\nclass CTextEdge; // Forward declaration\n\n// MARK: Blot\n\nenum BLOTE\n{\n    BLOTE_Nil = -1,\n    BLOTE_Left = 0,\n    BLOTE_Right = 1,\n    BLOTE_Top = 2,\n    BLOTE_Bottom = 3,\n    BLOTE_Max = 4\n};\n\nenum BLOTK\n{\n    BLOTK_Nil = -1,\n    // ...\n    BLOTK_Max = 0x1d\n};\n\nenum BLOTS\n{\n    BLOTS_Nil = -1,\n    BLOTS_Hidden = 0,\n    BLOTS_Appearing = 1,\n    BLOTS_Visible = 2,\n    BLOTS_Disappearing = 3,\n    BLOTS_Max = 4\n};\n\nstruct BLOTI\n{\n    float x, y;\n    BLOTE blote;\n    BLOTK blotkPeg;\n    BLOTE blotePeg;\n};\n\nstruct BLOT\n{\n    union\n    {\n        VTBLOT *pvtblot;\n        VTNOTE *pvtnote;\n        VTBINOC *pvtbinoc;\n        VTTIMER *pvttimer;\n        VTTOTALS *pvttotals;\n    };\n    CFont *pfont;\n    char achzDraw[512];\n    RGBA rgba;\n    float rFontScale;\n    CTextEdge *pte;\n    BLOTK blotk;\n    BLOTI *bloti;\n    float x, y;\n    float xOn, yOn;\n    float dx, dy;\n    float width, height;\n    float uOn;\n    float dtAppear;\n    float dtVisible;\n    float dtDisappear;\n    float dtBlotsExtra;\n    BLOTS blots;\n    float tBlots;\n    float *ptNow;\n    int fActive;\n};\n\n// MARK: Timer\n\n/**\n * @brief Timer state.\n */\nenum TIMERS\n{\n    TIMERS_Nil = -1,\n    TIMERS_Expired = 0,\n    TIMERS_Paused = 1,\n    TIMERS_Running = 2,\n    TIMERS_Max = 3\n};\n\nstruct TIMER : public BLOT\n{\n    TIMERS timers;\n    float tTimers;\n    float dt;\n    float svt;\n    int nSecondsLast;\n    int nTenthsLast;\n    float dtThreshold;\n    RGBA rgbaThreshold;\n    void *pfntnThreshold; // should be a function pointer\n    int fThreshold;\n    float dtExpire;\n    void *pfntnExpire; // should be a function pointer\n    int fStopped;\n};\n\n// MARK: Counters\n\nstruct CTR : public BLOT\n{\n    int nDisplay;\n    int *pnActual;\n    int *pnTotal;\n    float dgDisplayMax;\n    float uRemain;\n    void (*pfnsmack)(void *);\n    void *pv;\n};\n\nstruct TRUNKCTR : public CTR\n{\n};\nstruct CRUSHERCTR : public CTR\n{\n};\nstruct LIFECTR : public CTR\n{\n};\nstruct CLUECTR : public CTR\n{\n};\nstruct KEYCTR : public CTR\n{\n};\nstruct COINCTR : public CTR\n{\n};\n\nextern LIFECTR g_lifectr;\nextern CLUECTR g_cluectr;\nextern KEYCTR g_keyctr;\nextern COINCTR g_coinctr;\n\n// MARK: Totals\n\nstruct TOTALS : public BLOT\n{\n    int fReshow;\n    GRFLS grflsReshow;\n};\n\nextern TOTALS g_totals;\n\n// MARK: Note\n\nstruct NOTE : public BLOT\n{\n    STRUCT_PADDING(6);\n    struct NOTE *unk278;\n};\n\nextern NOTE g_note;\n\n// MARK: Letterbox\n\nstruct LETTERBOX : public BLOT\n{\n    // empty\n};\n\n// MARK: Title\n\nstruct TITLE : public BLOT\n{\n    int fReshow;\n    char *pchzReshow;\n};\n\n// MARK: Attract\n\nstruct ATTRACT : public BLOT\n{\n    int fJoyValid;\n    int fReshow;\n    char *pchzReshow;\n};\n\n// MARK: Logo\n\nstruct LOGO : public BLOT\n{\n    SHD *pshd;\n};\n\n// MARK: CTextEdge\n\nclass CTextEdge\n{\n    CFont *m_pfont;\n    char m_ch;\n    // 3 empty bytes for alignment\n    float m_dxExtra;\n    float m_dyExtra;\n    float m_rxScaling;\n    float m_ryScaling;\n    RGBA m_rgba;\n};\n\n// Global blots\nextern LIFECTR g_lifectr;\nextern CLUECTR g_cluectr;\nextern KEYCTR g_keyctr;\nextern COINCTR g_coinctr;\n\nvoid StartupScreen();\n\nvoid PostBlotsLoad();\n\nvoid UpdateBlots();\n\nvoid ForceHideBlots();\n\nvoid ResetBlots();\n\nvoid RenderBlots();\n\nvoid DrawBlots();\n\nvoid InitBlot(BLOT *pblot, BLOTK blotk);\n\nvoid PostBlotLoad(BLOT *pblot);\n\nvoid UpdateBlot(BLOT *pblot);\n\nvoid SetBlotAchzDraw(BLOT *pblot, char *achzDraw);\n\nvoid FUN_001aa5a0(undefined1 *param_1);\n\nvoid SetBlotFontScale(float rFontScale, BLOT *pblot);\n\nvoid DrawBlot(BLOT *pblot);\n\nfloat DtAppearBlot(BLOT *pblot);\n\nfloat DtVisibleBlot(BLOT *pblot);\n\nfloat DtDisappearBlot(BLOT *pblot);\n\nvoid SetBlotDtAppear(BLOT *pblot, float dtAppear);\n\nvoid SetBlotDtVisible(BLOT *pblot, float dtVisible);\n\nvoid SetBlotDtDisappear(BLOT *pblot, float dtDisappear);\n\nvoid OnBlotReset(BLOT *pblot);\n\nvoid ShowBlot(BLOT *pblot);\n\nvoid HideBlot(BLOT *pblot);\n\nvoid SetBlotBlots(BLOT *pblot, BLOTS blots);\n\nint pfnFIncludeBlotForPeg(BLOT *pblot, BLOT *pblotOther);\n\nvoid ResizeBlot(BLOT *pblot, float dx, float dy);\n\nvoid RepositionBlot(BLOT *pblot);\n\nvoid RepositionBlotDependents(BLOT *pblot);\n\nvoid SetBlotClock(BLOT *pblot, float *pt);\n\nvoid PostCtrLoad(CTR *pctr);\n\nvoid UpdateCtr(CTR *pctr);\n\nvoid DrawCtr(CTR *pctr);\n\nvoid RebuildCtrAchzDraw(CTR *pctr);\n\nfloat DtVisibleCtr(CTR *pctr);\n\nvoid FUN_001ab600(BLOT *pblot);\n\nvoid UpdateTimer(TIMER *ptimer);\n\nvoid DrawTimer(TIMER *ptimer);\n\nvoid SetTimer(TIMER *ptimer, float dt);\n\nvoid SetTimerSpeed(TIMER *ptimer, float svt);\n\nvoid SetTimerExpire(TIMER *ptimer, float dt, void *pfntn);\n\nvoid StartTimer(TIMER *ptimer);\n\nvoid StartTimer(TIMER *ptimer);\n\nvoid RebuildTimerAchzDraw(TIMER *ptimer, float dt);\n\nvoid SetTimerTimers(TIMER *ptimer, TIMERS timers);\n\nfloat DtVisibleTrunkctr(TRUNKCTR *ptrunkctr);\n\nfloat DtVisibleCrusherctr(CRUSHERCTR *pcrusherctr);\n\nvoid FUN_001abe70(BLOT *pblot);\n\nvoid FUN_001ac060(BLOT *pblot);\n\nvoid FUN_001ac0e8(int param_1);\n\nvoid PostNoteLoad();\n\nvoid PostNoteLoad(BLOT *pblot);\n\nvoid SetNoteAchzDraw(NOTE *pnote, char *pchz);\n\nvoid DrawNote(BLOT *pblot);\n\nvoid FUN_001ac888(BLOT *pblot);\n\nvoid FUN_001ac910(undefined8 param_1, char *param_2);\n\nvoid FUN_001ac990(BLOT *pblot, int param_2);\n\nundefined4 FUN_001ac9e0(BLOT *pblot, BLOT *pblotOther);\n\nvoid FUN_001aca30(BLOT *pblot);\n\nvoid FUN_001aca68(BLOT *pblot);\n\nvoid DrawTitle(TITLE *ptitle);\n\nvoid PostTotalsLoad(TOTALS *ptotals);\n\nvoid FUN_001ace38(undefined8 param_1, long param_2);\n\nulong FUN_001acee0(char *pchz, uint *param_2, ulong param_3);\n\nvoid render_level_info_from_id(BLOT *pblot, uint level_id);\n\nvoid render_level_info(BLOT *pblot, uint world_id, uint map_id);\n\nvoid render_hideout_world_info(BLOT *pblot, int world_id);\n\nvoid SetTotalsBlots(TOTALS *ptotals, BLOTS blots);\n\nvoid ShowTotals(TOTALS *ptotals);\n\nvoid HideTotals(TOTALS *ptotals);\n\nvoid DrawTotals(TOTALS *ptotals);\n\nvoid FUN_001ad6a8(undefined8 param_1);\n\nvoid FUN_001ad718(BLOT *pblot);\n\nvoid FUN_001ad7b0(int param_1);\n\nvoid FUN_001ad940(BLOT *pblot);\n\nvoid FUN_001ad970(BLOT *pblot, uint blots);\n\nvoid DrawLetterbox(LETTERBOX *pletterbox);\n\nvoid FUN_001adc60(undefined8 param_1);\n\nvoid DrawLogo(LOGO *ploto);\n\nvoid FUN_001adf28(BLOT *pblot);\n\nvoid FUN_001adff0(BLOT *pblot);\n\nvoid FUN_001ae130(BLOT *pblot, int param_2);\n\nvoid UpdateAttract(ATTRACT *pattract);\n\nvoid DrawLineScreen(uint x1, uint y1, uint z1, uint x2, uint y2, uint z2, RGBA *rgba, int fDepthTest);\n\n#endif // SCREEN_H\n"
  },
  {
    "path": "include/sdk/ee/eekernel.h",
    "content": "/**\n * @file kernel.h\n *\n * @brief Control for semaphores and threads.\n */\n#ifndef KERNEL_H\n#define KERNEL_H\n\n// FlushCache modes\n#define WRITEBACK_DCACHE 0\n#define INVALIDATE_DCACHE 1\n#define INVALIDATE_ICACHE 2\n#define INVALIDATE_CACHE (INVALIDATE_DCACHE | INVALIDATE_ICACHE) /* XXX this is a bit extra, but should match SCE headers */\n\nextern \"C\" {\n    /**\n     * @brief Thread parameters for initialization\n     */\n    struct ThreadParam {\n        int status;             // Thread status\n        void (*entry)(void *);  // Thread entry point\n        void *stack;            // Stack address used by the thread (16-byte aligned)\n        int stackSize;          // Stack size in bytes, must be a multiple of 16\n        void *gpReg;            // GP register value\n        int initPriority;       // Initial thread priority (1-127). Must be specified when creating a thread\n        int currentPriority;    // Current thread priority\n        unsigned int attr;      // Reserved for system use\n        unsigned int option;    // Reserved for system use\n        int\twaitType;           // Wait type\n        int\twaitId;             // Semaphore ID if waitType is \"semaphore\"\n        int\twakeupCount;        // Wakeup request count\n    };\n\n    /**\n     * @brief Semaphore parameters for initialization\n     */\n    struct SemaParam {\n        int currentCount;    // Current semaphore count\n        int maxCount;        // Maximum semaphore count\n        int initCount;       // Initial semaphore count\n        int numWaitThreads;  // Number of threads waiting on the semaphore\n        unsigned int attr;   // Semaphore attributes\n        unsigned int option; // Optional user-defined data\n    };\n\n    /**\n     * @brief Create a counting semaphore object.\n     *\n     * @details Up to 256 semaphores can be created, 3 of which are reserved during runtime\n     * initialization by `crt0.s` (2 from `_InitSys` and 1 from `InitThread`).\n     *\n     * @param sparam Initial semaphore parameters\n     * @return Semaphore ID on success, -1 if creation would exceed the maximum number of semaphores\n     * or a negative value was passed for `sema->initCount`\n     */\n    int CreateSema(SemaParam *sparam);\n\n    /**\n     * @brief Get semaphore resource\n     *\n     * @param sema Semaphore ID\n     * @return Semaphore count on success, -1 on failure\n     */\n    int WaitSema(int sema);\n\n    /**\n     * @brief Release semaphore resource\n     *\n     * @details If the `sid` value is 0 and there is no free space in the semaphore queue,\n     * the thread at the wait queue start will be released and placed in READY state.\n     * In all other cases, the value of the semaphore is incremented.\n     *\n     * @param sid Semaphore ID\n     * @return Semaphore ID on success, -1 on failure\n     */\n    int SignalSema(int sid);\n\n    /**\n     * @brief Create a new thread\n     *\n     * @details The created thread is placed in a DORMANT state and not executed until the thread is started.\n     *\n     * @param tparam Initial thread parameters\n     *\n     * @return Thread ID on success, -1 on failure\n     */\n    int CreateThread(struct ThreadParam *tparam);\n\n    /**\n     * @brief Get the ID of the calling thread.\n     *\n     * @return Thread ID\n     */\n    int GetThreadId();\n\n    /**\n     * @brief Change the priority of a thread\n     *\n     * @details The thread will be entered at the end of the ready queue at the corresponding priority.\n     * The new priority setting will be valid until the thread is terminated or the priority is changed again.\n     *\n     * @param tid Thread ID\n     * @param priority New priority (1-127)\n     *\n     * @return The previous priority of the thread on success, -1 on failure\n     */\n    int ChangeThreadPriority(int tid, int priority);\n\n    /**\n     * @brief Flushes the cache.\n     * @param mode Can be WRITEBACK_DCACHE, INVALIDATE_DCACHE, INVALIDATE_ICACHE, or INVALIDATE_CACHE\n     */\n    void FlushCache(int mode);\n}\n\n#endif // KERNEL_H\n"
  },
  {
    "path": "include/sdk/ee/eestruct.h",
    "content": "/**\n * @file include/sdk/ee/eestruct.h\n *\n * @brief Graphics synthesizer.\n */\n#ifndef SCE_EESTRUCT_H\n#define SCE_EESTRUCT_H\n\n// TODO: Remove this.\n#include \"types.h\"\n\nextern \"C\"\n{\n    struct sceGsTex0\n    {\n        undefined4 unk_0x0;\n        undefined4 unk_0x4;\n    };\n\n    struct sceGsTex2\n    {\n        undefined4 unk_0x0;\n        undefined4 unk_0x4;\n    };\n\n    /**\n     * @todo Figure out is this in the right place.\n     */\n    void sceGsResetPath();\n}\n\n#endif // SCE_EESTRUCT_H\n"
  },
  {
    "path": "include/sdk/ee/libpad.h",
    "content": "/**\n * @file include/sdk/ee/libpad.h\n *\n * @brief Joypad (controller) library.\n */\n#ifndef PAD_H\n#define PAD_H\n\ntypedef unsigned char u_char;\n\nextern \"C\"\n{\n    int scePadInit(int mode);\n    int scePadPortOpen(int port, int slot, void *data);\n    int scePadGetState(int port, int slot);\n    int scePadInfoAct(int port, int slot, int actno, int term);\n    int scePadInfoMode(int port, int slow, int term, int offs);\n    int scePadSetMainMode(int port, int slow, int offs, int lock);\n    int scePadSetActDirect(int port, int slot, const u_char *data);\n    int scePadSetActAlign(int port, int slow, const u_char *data);\n    int scePadInfoPressMode(int port, int slot);\n    int scePadEnterPressMode(int port, int slot);\n    int scePadExitPressMode(int port, int slot);\n}\n\n#endif // PAD_H\n"
  },
  {
    "path": "include/sdk/ee/sifdev.h",
    "content": "#ifndef SIFDEV_H\n#define SIFDEV_H\n\nextern \"C\"\n{\nint sceSifLoadFileReset();\nint sceSifLoadModule(const char *filename, int args, const char *argp);\nint sceSifRebootIop(const char *img);\nint sceSifSyncIop(void);\n};\n\n#endif // SIFDEV_H\n"
  },
  {
    "path": "include/sdk/ee/sifrpc.h",
    "content": "#ifndef SIFRPC_H_\n#define SIFRPC_H_\n\nextern \"C\" {\n\ntypedef void (*sceSifEndFunc)(void*);\ntypedef void* (*sceSifRpcFunc)(unsigned, void*, int);\n\nstruct _sif_rpc_data { // 0x10\n    /* 0x0 */ void* paddr;\n    /* 0x4 */ unsigned int pid;\n    /* 0x8 */ int tid;\n    /* 0xc */ unsigned int mode;\n};\ntypedef _sif_rpc_data sceSifRpcData;\n\nstruct _sif_client_data { // 0x28\n    /* 0x00 */ struct _sif_rpc_data rpcd;\n    /* 0x10 */ unsigned int command;\n    /* 0x14 */ void* buff;\n    /* 0x18 */ void* cbuff;\n    /* 0x1c */ sceSifEndFunc func;\n    /* 0x20 */ void* para;\n    /* 0x24 */ struct _sif_serve_data* serve;\n};\ntypedef _sif_client_data sceSifClientData;\n\nstruct _sif_serve_data { // 0x44\n    /* 0x00 */ unsigned int command;\n    /* 0x04 */ sceSifRpcFunc func;\n    /* 0x08 */ void* buff;\n    /* 0x0c */ int size;\n    /* 0x10 */ sceSifRpcFunc cfunc;\n    /* 0x14 */ void* cbuff;\n    /* 0x18 */ int csize;\n    /* 0x1c */ sceSifClientData* client;\n    /* 0x20 */ void* paddr;\n    /* 0x24 */ unsigned int fno;\n    /* 0x28 */ void* receive;\n    /* 0x2c */ int rsize;\n    /* 0x30 */ int rmode;\n    /* 0x34 */ unsigned int rid;\n    /* 0x38 */ struct _sif_serve_data* link;\n    /* 0x3c */ struct _sif_serve_data* next;\n    /* 0x40 */ struct _sif_queue_data* base;\n};\ntypedef _sif_serve_data sceSifServeData;\n\nstruct _sif_queue_data { // 0x18\n    /* 0x00 */ int key;\n    /* 0x04 */ int active;\n    /* 0x08 */ struct _sif_serve_data* link;\n    /* 0x0c */ struct _sif_serve_data* start;\n    /* 0x10 */ struct _sif_serve_data* end;\n    /* 0x14 */ struct _sif_queue_data* next;\n};\ntypedef _sif_queue_data sceSifQueueData;\n\nvoid sceSifInitRpc(unsigned int mode);\nint sceSifBindRpc(sceSifClientData*, unsigned int, unsigned int);\nint sceSifCallRpc(sceSifClientData*, unsigned int, unsigned int, void*, int, void*, int, sceSifEndFunc, void*);\nint sceSifCheckStatRpc(sceSifRpcData*);\n}\n\n#endif // SIFRPC_H_\n"
  },
  {
    "path": "include/sdk/libcdvd.h",
    "content": "/**\n * @file include/sdk/libcdvd.h\n *\n * @brief DVD handler.\n */\n#ifndef EEDVD_H\n#define EEDVD_H\n\ntypedef unsigned char u_char;\ntypedef unsigned int u_int;\n\nextern \"C\"\n{\n    struct sceCdRMode {\n        u_char trycount;\n        u_char spindlctrl;\n        u_char datapattern;\n        u_char pad;\n    };\n\n\tenum SCECdvdMediaType {\n        SCECdGDTFUNCFAIL = -1,\n        SCECdNODISC      = 0x00,\n        SCECdDETCT,\n        SCECdDETCTCD,\n        SCECdDETCTDVDS,\n        SCECdDETCTDVDD,\n        SCECdUNKNOWN,\n\n        SCECdPSCD = 0x10,\n        SCECdPSCDDA,\n        SCECdPS2CD,\n        SCECdPS2CDDA,\n        SCECdPS2DVD,\n\n        SCECdDVDVR = 0xFC,\n        SCECdCDDA = 0xFD,\n        SCECdDVDV,\n        SCECdIllegalMedia\n    };\n\n    int sceCdSync(int mode);\n    int sceCdInit(int mode);\n    int sceCdDiskReady(int mode);\n    int sceCdMmode(int mode);\n    int sceCdRead(u_int lbn, u_int sectors, void *buf, sceCdRMode *mode);\n    int sceCdGetDiskType(void);\n    int sceCdGetError(void);\n    int sceCdBreak(void);\n};\n\n#endif // EEDVD_H\n"
  },
  {
    "path": "include/sensor.h",
    "content": "#ifndef SENSOR_H\n#define SENSOR_H\n\n#include \"common.h\"\n#include <alarm.h>\n#include <oid.h>\n#include <so.h>\n#include <cm.h>\n\n// Forward.\nstruct RO;\n\n/**\n * @brief Sensor state.\n */\nenum SENSORS\n{\n    SENSORS_Nil = -1,\n    SENSORS_SenseEnabling = 0,\n    SENSORS_SenseEnabled = 1,\n    SENSORS_SenseTriggered = 2,\n    SENSORS_SenseDisabling = 3,\n    SENSORS_DamageEnabling = 4,\n    SENSORS_DamageEnabled = 5,\n    SENSORS_DamageTriggered = 6,\n    SENSORS_DamageDisabling = 7,\n    SENSORS_Disabled = 8,\n    SENSORS_Max = 9\n};\n\n/**\n * @brief Sensor mode.\n */\nenum SENSM\n{\n    SENSM_Nil = -1,\n    SENSM_SenseOnly = 0,\n    SENSM_DamageTarget = 1,\n    SENSM_Max = 2\n};\n\n\n/**\n * @brief (?) state.\n */\nenum CSDTS\n{\n    CSDTS_Nil = -1,\n    CSDTS_Focus = 0,\n    CSDTS_Zap = 1,\n    CSDTS_Unfocus = 2,\n    CSDTS_Max = 3,\n};\n\n/**\n * @class _SENSOR\n * @brief Base class for security sensors.\n * @todo Implement the struct.\n */\nstruct SENSOR : public SO\n{\n    /* 0x550 */ ALARM *palarm; // Pointer to the alarm this sensor is associated with.\n    STRUCT_PADDING(1);\n    /* 0x558 */ SENSORS sensors; // Current sensor state.\n    STRUCT_PADDING(2);\n    /* 0x564 */ uint ctriggerObjects; // Current count of trigger object IDs.\n    /* 0x568 */ OID atriggerObjects[4]; // Array of trigger object IDs.\n    STRUCT_PADDING(4);\n    /* 0x578 */ uint cnoTriggerObjects; // Current count of no-trigger object IDs.\n    /* 0x57C */ OID anoTriggerObjects[4]; // Array of no-trigger object IDs.\n    STRUCT_PADDING(4);\n    /* 0x58c */ uint ctriggerClasses; // Current count of trigger class IDs.\n    /* 0x590 */ CID atriggerClasses[4]; // Array of trigger class IDs.\n    STRUCT_PADDING(4);\n    /* 0x5a0 */ uint cnoTriggerClasses; // Current count of no-trigger class IDs.\n    /* 0x5a4 */ CID anoTriggerClasses[4]; // Array of no-trigger class IDs.\n};\n\n/**\n * @class LASER_SENSOR\n * @brief Laser sensor for alarm systems.\n * @todo Implement the struct.\n */\nstruct LASEN : public SENSOR\n{\n    // ...\n};\n\n/**\n * @class CAMERA_SENSOR\n * @brief Camera sensor for alarm system.\n * @todo Implement the struct.\n */\nstruct CAMSEN : public SENSOR\n{\n    // ...\n};\n\n/**\n * @class PRESSURE_SENSOR\n * @brief Pressusre sensor for alarm systems.\n * @todo Implement the struct.\n */\nstruct PRSEN : public SENSOR\n{\n    // ...\n};\n\n/**\n * @brief Laser beam?\n * @todo Implement the struct.\n */\nstruct LBEAM\n{\n    // ...\n};\n\n// MARK: SENSOR methods\n/**\n * @brief Sets the default values for the sensor.\n *\n * @param psensor Pointer to the sensor to initialize.\n */\nvoid InitSensor(SENSOR *psensor);\n\n/**\n * @brief Sets the sensor's associated alarm.\n *\n * @param psensor Pointer to the sensor.\n * @param palarm Pointer to the alarm to associate with the sensor.\n */\nvoid SetSensorAlarm(SENSOR *psensor, ALARM *palarm);\n\n/**\n * @brief Sets the sensor's state and handles triggering the sensor's alarm.\n *\n * @param psensor Pointer to the sensor.\n * @param sensors New sensor state.\n *\n * If the sensor is transitioning from SENSORS_SenseEnabled to SENSORS_SenseTriggered,\n * it will trigger the associated alarm if one is set. If the sensor's state changes,\n * it will also notify any listeners of the change via an LO splice event.\n *\n */\nvoid SetSensorSensors(SENSOR *psensor, SENSORS sensors);\n\nint FCheckSensorObject(SENSOR *psensor, SO *psoOther);\n\nint FIgnoreSensorObject(SENSOR *psensor, SO *psoOther);\n\nint FOnlySensorTriggerObject(SENSOR *psensor, SO *psoOther);\n\nvoid PauseSensor(SENSOR *psensor);\n\nvoid UpdateSensor(SENSOR *psensor, float dt);\n\n/**\n * @brief Add an object ID to the sensor's trigger list.\n *\n * @param psensor Pointer to the sensor.\n * @param oid Object ID to add.\n */\nvoid AddSensorTriggerObject(SENSOR *psensor, OID oid);\n\n/**\n * @brief Add an object ID to the sensor's no-trigger list.\n *\n * @param psensor Pointer to the sensor.\n * @param oid Object ID to add.\n */\nvoid AddSensorNoTriggerObject(SENSOR *psensor, OID oid);\n\n/**\n * @brief Add a class ID to the sensor's trigger class list.\n *\n * @param psensor Pointer to the sensor.\n * @param cid Class ID to add.\n */\nvoid AddSensorTriggerClass(SENSOR *psensor, CID cid);\n\n/**\n * @brief Add a class ID to the sensor's no-trigger class list.\n *\n * @param psensor Pointer to the sensor.\n * @param cid Class ID to add.\n */\nvoid AddSensorNoTriggerClass(SENSOR *psensor, CID cid);\n\n// MARK: LASEN methods\nvoid InitLasen(LASEN *plasen);\n\nvoid LoadLasenFromBrx(LASEN *plasen, CBinaryInputStream *pbis);\n\nvoid BindLasen(LASEN *plasen);\n\nvoid PostLasenLoad(LASEN *plasen);\n\nvoid UpdateBusyLasenSenseTimes();\n\nvoid UpdateLasen(LASEN *plasen, float dt);\n\nvoid FreezeLasen(LASEN *plasen, int fFreeze);\n\nvoid RenderLasenSelf(LASEN *plasen, CM *pcm, RO *pro);\n\nint FFilterLasen(void *pv, SO *pso);\n\nvoid SenseLasen(LASEN *plasen, SENSORS *psensors);\n\nvoid EnableLasen(LASEN *plasen, SENSM sensm);\n\nvoid DisableLasen(LASEN *plasen);\n\nvoid OnLasenAlarmTriggered(LASEN *plasen);\n\nvoid SetLasenSensors(LASEN *plasen, SENSORS sensors);\n\nfloat SCalcLasenShapeExtent(LASEN *plasen, LBEAM *plbeam);\n\nvoid RetractLasen(LASEN *plasen, float dtRetract);\n\nvoid ExtendLasen(LASEN *plasen, float dtExpand);\n\n// MARK: CAMSEN methods\nvoid InitCamsen(CAMSEN *pcamsen);\n\nvoid PostCamsenLoad(CAMSEN *pcamsen);\n\nvoid UpdateCamsen(CAMSEN *pcamsen, float dt);\n\nvoid RenderCamsenSelf(CAMSEN *pcamsen, CM *pcm, RO *pro);\n\nint FIgnoreCamsenIntersection(CAMSEN *pcamsen, SO *psoOther);\n\nint FFilterCamsen(void *pv, SO *pso);\n\nvoid SenseCamsen(CAMSEN *pcamsen, SENSORS *psensors);\n\nvoid EnableCamsen(CAMSEN *pcamsen, SENSM sensm);\n\nvoid DisableCamsen(CAMSEN *pcamsen);\n\nvoid OnCamsenAlarmTriggered(CAMSEN *pcamsen);\n\nvoid SetCamsenSensors(CAMSEN *pcamsen, SENSORS sensors);\n\nvoid SetCamsenCsdts(CAMSEN *pcamsen, CSDTS csdts);\n\n// MARK: PRSEN methods\nvoid InitPrsen(PRSEN *pprsen);\n\nvoid PostPrsenLoad(PRSEN *pprsen);\n\nvoid UpdatePrsen(PRSEN *pprsen, float dt);\n\nvoid SensePrsen(PRSEN *pprsen, SENSORS *psensors);\n\nvoid EnablePrsen(PRSEN *pprsen, SENSM sensm);\n\nvoid DisablePrsen(PRSEN *pprsen);\n\nvoid OnPrsenAlarmTriggered(PRSEN *pprsen);\n\nvoid SetPrsenSensors(PRSEN *pprsen, SENSORS sensors);\n\nvoid UpdatePrsenLoopShader(PRSEN *pprsen);\n\n#endif // SENSOR_H\n"
  },
  {
    "path": "include/shadow.h",
    "content": "/**\n * @file shadow.h\n */\n#ifndef SHADOW_H\n#define SHADOW_H\n\n#include \"common.h\"\n#include <glob.h>\n#include <oid.h>\n#include <vec.h>\n#include <so.h>\n#include <sw.h>\n\n// Forward.\nstruct SHD;\n\n/**\n * @brief Shadow.\n * @todo Implement the struct.\n */\nstruct SHADOW\n{\n    /* 0x00 */ SHD *pshd;\n    /* 0x04 */ float sNearRadius;\n    /* 0x08 */ float sFarRadius;\n    /* 0x0c */ STRUCT_PADDING(13);\n    /* 0x40 */ float sNearCast;\n    /* 0x44 */ float sFarCast;\n    /* 0x48 */ STRUCT_PADDING(26);\n    /* 0xb0 */ OID oidDysh;\n    /* 0xb4 */ STRUCT_PADDING(3);\n    /* 0xc0 */ int cqwVifs;\n};\n\nvoid InitShadow(SHADOW *pshadow);\n\nvoid PostShadowLoad(SHADOW *pshadow);\n\nvoid InvalidateShadowVifs(SHADOW *pshadow);\n\nvoid RebuildShadowRegion(SHADOW *pshadow);\n\nvoid SetShadowShader(SHADOW *pshadow, OID oidShdShadow);\n\nint FShadowRadiusSet(SHADOW *pshadow);\n\nvoid SetShadowNearRadius(SHADOW *pshadow, float sNearRadius);\n\nvoid SetShadowFarRadius(SHADOW *pshadow, float sFarRadius);\n\nvoid SetShadowCastPosition(SHADOW *pshadow, VECTOR *pposCast);\n\nvoid SetShadowCastNormal(SHADOW *pshadow, VECTOR *pnormalCast);\n\nvoid SetShadowNearCast(SHADOW *pshadow, float sNearCast);\n\nvoid SetShadowFarCast(SHADOW *pshadow, float sFarCast);\n\nvoid SetShadowConeAngle(SHADOW *pshadow, float degConeAngle);\n\nvoid SetShadowFrustrumUp(SHADOW *pshadow, VECTOR *pvecUp);\n\nint FShadowValid(SHADOW *pshadow, GRFGLOB grfglob);\n\nint FFilterFastShadows(void *pv, SO *pso);\n\nvoid UpdateShadow(SHADOW *pshadow, float dt);\n\nvoid RebuildShadowVifs(SHADOW *pshadow);\n\nvoid DrawShadow(SHADOW *pshadow);\n\nint FShadowIntersectsSphere(SHADOW *pshadow, VECTOR *ppos, float sRadius);\n\nvoid FindSwShadows(SW *psw, VECTOR *ppos, float sRadius, int cpshadowMax, int *pcpshadow, SHADOW ** apshadow);\n\n#endif // SHADOW_H\n"
  },
  {
    "path": "include/shape.h",
    "content": "/**\n * @file shape.h\n */\n#ifndef SHAPE_H\n#define SHAPE_H\n\n#include \"common.h\"\n#include <crv.h>\n#include <bis.h>\n#include <alo.h>\n#include <lo.h>\n#include <dl.h>\n\n/**\n * @class SHAPE\n * @brief Unknown.\n */\nstruct SHAPE : public LO\n{\n    CRV *pcrv;\n};\n\nvoid LoadShapeFromBrx(SHAPE *pshape, CBinaryInputStream *pbis);\n\nvoid SetShapeParent(SHAPE *pshape, ALO *paloParent);\n\n#endif // SHAPE_H\n"
  },
  {
    "path": "include/shd.h",
    "content": "/**\n * @file shd.h\n *\n * @brief Shaders.\n */\n#ifndef SHD_H\n#define SHD_H\n\n#include \"common.h\"\n#include <sdk/ee/eestruct.h>\n#include <bis.h>\n#include <oid.h>\n#include <geom.h>\n#include <dmas.h>\n#include <gifs.h>\n\ntypedef struct SHD; // Forward declaration\ntypedef struct SHDP; // Forward declaration\n\ntypedef int GRFZON;\n\n/**\n * @brief (?) kind.\n */\nenum CTK\n{\n    CTK_Nil = -1,\n    CTK_Original = 0,\n    CTK_Pass0 = 0,\n    CTK_Ambient = 0,\n    CTK_Pass1 = 1,\n    CTK_Diffuse = 1,\n    CTK_Saturation = 2,\n    CTK_Pass2 = 2,\n    CTK_Max = 3,\n};\n\n// MARK: BMP\n\nstruct BMPF\n{\n    short dx;\n    short dy;\n    uint grfzon;\n    uchar psm;\n    uchar cgsRow;\n    short cgsPixels;\n    uint cbPixels;\n    uchar *pbPixels;\n};\n\nstruct BMP : public BMPF\n{\n    int cqwPixels;\n    sceGsTex0 tex0;\n};\n\n// MARK: CLUT\n\nstruct CLUTF\n{\n    uint grfzon;\n    ushort crgba;\n    ushort cgsColors;\n    RGBA *prgba;\n};\n\nstruct CLUT : public CLUTF\n{\n    int cqwColors;\n    sceGsTex2 tex2;\n};\n\n// MARK: Texture?\n\nstruct TCX\n{\n    float du;\n    float dv;\n};\n\nstruct TEXF\n{\n    ushort OID;\n    short grdtex;\n    uchar cibmp;\n    uchar ciclut;\n};\n\nstruct TEX : public TEXF\n{\n    ushort unk_0;\n    SHD *pshd;\n    BMP **apbmp;\n    CLUT **apclut;\n};\n\n// MARK: SAIR\n\nstruct SAIR\n{\n    SHDP *pshdp;\n    SUR *psur;\n    SAIR *psairNext;\n};\n\n// MARK: SAI\n\nstruct SAI\n{\n    int grfsai;\n    SHD *pshd;\n    int iframe;\n    TCX txt;\n    SAIR *psairFirst;\n    SAI *psaiNext;\n};\n\n\n// MARK: SAA\n\nenum SAAK\n{\n    SAAK_Nil = -1,\n    SAAK_None = 0,\n    SAAK_Loop = 1,\n    SAAK_PingPong = 2,\n    SAAK_Shuffle = 3,\n    SAAK_Hologram = 4,\n    SAAK_Eyes = 5,\n    SAAK_Scroller = 6,\n    SAAK_Circler = 7,\n    SAAK_Looker = 8,\n    SAAK_Max = 9\n};\n\nstruct SAA\n{\n    undefined4 unk_0;\n    float tUpdates;\n    SAAK saak;\n    OID oid;\n    SAI sai;\n};\n\n/**\n * @brief Unknown.\n */\nstruct SAAF\n{\n    // ...\n};\n\n// MARK: SHD\n\nenum SHDK\n{\n    SHDK_Nil = -1,\n    SHDK_ThreeWay = 0,\n    SHDK_Prelit = 1,\n    SHDK_Shadow = 2,\n    SHDK_SpotLight = 3,\n    SHDK_ProjectedVolume = 4,\n    SHDK_CreateTexture = 5,\n    SHDK_Background = 6,\n    SHDK_Foreground = 7,\n    SHDK_WorldMap = 8,\n    SHDK_MurkClear = 9,\n    SHDK_MurkFill = 10,\n    SHDK_Max = 11\n};\n\nstruct SHDP\n{\n    int cqwRegs;\n    QW *aaqwRegs;\n};\n\nstruct SHDF\n{\n    /* 0x00 */ uchar shdk;\n    /* 0x01 */ uchar grfshd;\n    /* 0x02 */ short oid;\n    RGBA rgba;\n    RGBA rgbaVolume;\n    uint grfzon;\n    ushort OidAltSat;\n    uchar rp;\n    uchar ctex;\n};\n\nstruct SHD : public SHDF\n{\n    TEX *atex;\n    int cshdp;\n    SHDP *ashdp;\n    int cframe;\n    SAA *psaa;\n};\n\n/**\n * @brief Unknown.\n * @todo Does this belong here?\n */\nstruct SLI\n{\n\n};\n\nsceGsTex0 Tex0FromTexIframeCtk(TEX *ptex, int iframe, CTK ctk);\n\nvoid PackTexGifs(TEX *ptex, int iframe, CTK ctk, SHDK shdk, GIFS *pgifs);\n\nvoid LoadClutFromBrx(CBinaryInputStream *pbis, CLUT *pclut);\n\nvoid LoadColorTablesFromBrx(CBinaryInputStream *pbis);\n\nvoid LoadBmpFromBrx(CBinaryInputStream *pbis, BMP *pbmp);\n\nvoid LoadBitmapsFromBrx(CBinaryInputStream *pbis);\n\nvoid LoadFontsFromBrx(CBinaryInputStream *pbis);\n\nvoid LoadTexFromBrx(CBinaryInputStream *pbis, TEX *ptex);\n\nvoid LoadShadersFromBrx(CBinaryInputStream *pbis);\n\nvoid UploadPermShaders();\n\nvoid PropagateShaders(GRFZON grfzonCamera);\n\nvoid FillShaders(GRFZON grfzon);\n\nvoid UnloadShaders();\n\nvoid ConvertRgbToHsv(VECTOR *pvecRGB, VECTOR *pvecHSV);\n\nvoid ConvertHsvToRgb(VECTOR *pvecHSV, VECTOR *pvecRGB);\n\nvoid ConvertUserHsvToUserRgb(VECTOR *pvecHSV, VECTOR *pvecRGB);\n\nvoid ConvertUserRgbToUserHsv(VECTOR *pvecRGB, VECTOR *pvecHSV);\n\nSHD *PshdFindShader(OID oid);\n\nvoid SetSaiIframe(SAI *psai, int iframe);\n\nvoid SetSaiDuDv(SAI *psai, float du, float dv);\n\nvoid PropagateSais();\n\nvoid UpdateShaders(float dt);\n\n#endif // SHD_H\n"
  },
  {
    "path": "include/shdanim.h",
    "content": "/**\n * @file shdanim.h\n *\n * @brief Shader animations.\n */\n#ifndef SHDANIM_H\n#define SHDANIM_H\n\n#include \"common.h\"\n#include <glob.h>\n#include <shd.h>\n\n// Forward.\nstruct UV;\nstruct UVQD;\nstruct POSAD;\nstruct RPL;\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct LOOP : public SAA\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct PINGPONG : public SAA\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct SHUFFLE : public SAA\n{\n    float dtPauseMin;\n    float dtPauseMax;\n    float dtPause;\n};\n\n/**\n * @brief Level transition hologram?\n * @todo Implement the struct.\n */\nstruct HOLOGRAM : public SAA\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct SCROLLER : public SAA\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct CIRCLER : public SAA\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct LOOKER : public SAA\n{\n    // ...\n};\n\nint CbFromSaak(SAAK saak);\nVTSAA *PvtsaaFromSaak(SAAK saak);\nSAA *PsaaLoadFromBrx(CBinaryInputStream *pbis);\nvoid InitSaa(SAA *psaa, SAAF *psaaf);\nvoid PostSaaLoad(SAA *psaa);\nint FUpdatableSaa(SAA *psaa);\nfloat UCompleteSaa(SAA *psaa);\nSAI *PsaiFromSaaShd(SAA *psaa, SHD *pshd);\nvoid InitLoop(LOOP *ploop, SAAF *psaaf);\nvoid PostLoopLoad(LOOP *ploop);\nvoid UpdateLoop(LOOP *ploop, float dt);\nfloat UCompleteLoop(LOOP *ploop);\nvoid InitPingpong(PINGPONG *ppingpong, SAAF *psaaf);\nvoid PostPingpongLoad(PINGPONG *ppingpong);\nvoid UpdatePingpong(PINGPONG *ppingpong, float dt);\nfloat UCompletePingpong(PINGPONG *ppingpong);\nvoid InitShuffle(SHUFFLE *pshuffle, SAAF *psaaf);\nvoid UpdateShuffle(SHUFFLE *pshuffle, float dt);\nvoid InitHologram(HOLOGRAM *phologram, SAAF *psaaf);\nvoid PostHologramLoad(HOLOGRAM *phologram);\nvoid NotifyHologramRender(HOLOGRAM *phologram, ALO *palo, RPL *prpl);\nvoid InitScroller(SCROLLER *pscroller, SAAF *psaaf);\nvoid UpdateScroller(SCROLLER *pscroller, float dt);\nfloat UCompleteScroller(SCROLLER *pscroller);\nvoid SetScrollerMasterSpeeds(SCROLLER *pscroller, float svu, float svv);\nvoid InitCircler(CIRCLER *pcircler, SAAF *psaaf);\nvoid UpdateCircler(CIRCLER *pcircler, float dt);\nfloat UCompleteCircler(CIRCLER *pcircler);\nvoid InitLooker(LOOKER *plooker, SAAF *psaaf);\nvoid SetLookerSgvr(LOOKER *plooker, SGVR *psgvr, GLOBSET *pglobset, GLOB *pglob, SUBGLOB *psubglob);\nvoid SetVecPosad(VECTOR *pvec, POSAD *pposad);\nvoid SetUvPuvqd(UV *puv, UVQD *puvqd);\nvoid NotifyLookerRender(LOOKER *plooker, ALO *palo, RPL *prpl);\n\n#endif // SHDANIM_H\n"
  },
  {
    "path": "include/sky.h",
    "content": "/**\n * @file sky.h\n *\n * @brief Skyboxes.\n */\n#ifndef SKY_H\n#define SKY_H\n\n#include \"common.h\"\n\n/**\n * @class SKY\n * @brief Skyboxes.\n *\n * @todo Fill out the structure.\n */\nstruct SKY\n{\n    // ...\n};\n\n/**\n * @brief Initializes the sky with default values.\n * Calls super function PostAloLoad().\n *\n * @param psky Pointer to the sky.\n */\nvoid PostSkyLoad(SKY *psky);\n\n/**\n * @brief Updates the given sky.\n *\n * @param psky Pointer to the sky.\n * @param dt Delta time.\n */\nvoid UpdateSky(SKY *psky, float dt);\n\n#endif // SKY_H\n"
  },
  {
    "path": "include/slotheap.h",
    "content": "/**\n * @file slotheap.h\n *\n * @brief Fixed-size memory pool allocator using a linked list of free slots.\n */\n#ifndef SLOTHEAP_H\n#define SLOTHEAP_H\n\n#include \"common.h\"\n\n/**\n * @brief Slot.\n */\nstruct SLOT\n{\n    /* 0x00 */ SLOT *pslotNext;\n}; // 0x04 bytes.\n\n/**\n * @brief Slot heap.\n */\nstruct SLOTHEAP\n{\n    /* 0x00 */ int cb;\n    /* 0x04 */ byte *ab;\n    /* 0x08 */ SLOT *pslotFree;\n}; // 0x0c bytes.\n\n/**\n * @brief Initializes a slot heap with a linked list of free slots.\n *\n * @param pslotheap Pointer to the slot heap.\n * @param cb        Size of a slot in bytes.\n * @param c         Number of slots to allocate.\n */\nvoid _InitSlotheap(SLOTHEAP *pslotheap, int cb, int c);\n\n/**\n * @brief Creates the slot heap with slots aligned to 8 bytes.\n *\n * @param pslotheap Pointer to the slot heap.\n * @param cb        Size of a slot in bytes.\n * @param c         Number of slots to allocate.\n */\nvoid CreateSlotheapSw(SLOTHEAP *pslotheap, int cb, int c);\n\n/**\n * @brief Creates the slot heap with slots aligned to 64 bytes.\n *\n * @param pslotheap Pointer to the slot heap.\n * @param cb        Size of a slot in bytes.\n * @param c         Number of slots to allocate.\n */\nvoid CreateSlotheapSwAlign64(SLOTHEAP *pslotheap, int cb, int c);\n\n/**\n * @brief Allocates a slot from the slot heap.\n *\n * @param pslotheap Pointer to the slot heap.\n *\n * @return Pointer to an allocated slot.\n */\nvoid *PvAllocSlotheapUnsafe(SLOTHEAP *pslotheap);\n\n/**\n * @brief Wrapper for PvAllocSlotheapUnsafe.\n *\n * @param pslotheap Pointer to the slot heap.\n *\n * @return Pointer to an allocated slot.\n */\nvoid *PvAllocSlotheapImpl(SLOTHEAP *pslotheap);\n\n/**\n * @brief Allocates a slot from the slot heap and clears it.\n *\n * @param pslotheap Pointer to the slot heap.\n *\n * @return Pointer to an allocated slot.\n */\nvoid *PvAllocSlotheapClearImpl(SLOTHEAP *pslotheap);\n\n/**\n * @brief Frees a slot and returns it to the slot heap.\n *\n * @param pslotheap Pointer to the slot heap.\n * @param pv        Pointer to the slot being freed.\n */\nvoid FreeSlotheapPv(SLOTHEAP *pslotheap, void *pv);\n\n#endif // SLOTHEAP_H\n"
  },
  {
    "path": "include/sm.h",
    "content": "/**\n * @file sm.h\n *\n * @brief Probabilistic finite state machines.\n */\n#ifndef SM_H\n#define SM_H\n\n#include \"common.h\"\n#include <dl.h>\n#include <mq.h>\n#include <lo.h>\n\n// Forward declatations.\nstruct SM;\nstruct SMA;\nstruct SMT;\nstruct SMS;\nstruct SMP;\nstruct SMPA; // todo define\nstruct ASEGA;\n\ntypedef int GRFAPL;\n\ntypedef int GRFSMT; // State machine transition integer type.\n\n/**\n * @class STATE_MACHINE\n * @brief State machine defined by a number of states and transitions.\n */\nstruct SM : public LO\n{\n    /* 0x34 */ int csms; // Count of states.\n    /* 0x38 */ SMS *asms; // Array of states.\n    /* 0x3c */ int csmt; // Count of transitions.\n    /* 0x40 */ SMT *asmt; // Array of transitions.\n    /* 0x44 */ int fDefault;\n    /* 0x48 */ DL dlSma;\n};\n\n/**\n * @class STATE_MACHINE_APPLICATION\n * @brief Unknown.\n */\nstruct SMA : public BASIC\n{\n    DLE dleSm;\n    DLE dleSw;\n    SM *psm;\n    ALO *paloRoot;\n    int grfapl;\n    ASEGA *pasegaCur;\n    int ismsCur;\n    int ismsNext;\n    int ismsGoal;\n    SMT *psmtCur;\n    float svtLocal;\n    MQ *pmqFirst;\n};\n\n/**\n * @brief State machine transition.\n */\nstruct SMT\n{\n    undefined4 unk_0;\n    int ismsFrom; // From state\n    int ismsTo; // To state\n    GRFSMT grfsmt; // Unknown\n    float gProbability; // Probability of transition\n};\n\n/**\n * @brief State machine state.\n */\nstruct SMS\n{\n    OID oid;\n    undefined4 unk_0;\n};\n\n/**\n * @brief State machine pace(?).\n *\n * @note Used for the Fast/Slow powerups.\n */\nstruct SMP\n{\n    float svFast; // todo check if this is correct\n    float svSlow;\n    float dtFast;\n};\n\nvoid LoadSmFromBrx(SM *psm, CBinaryInputStream *pbis);\n\nvoid PostSmLoad(SM *psm);\n\nvoid PostSmLoadCallback(SM *psm, MSGID msgid, void *pvData);\n\nSMA *PsmaApplySm(SM *psm, ALO *paloRoot, OID oidInitialState, GRFAPL grfapl);\n\nSMA *PsmaFindSm(SM *psm, ALO *paloRoot);\n\nint IsmsFindSmOptional(SM *psm, OID oid);\n\nint IsmsFindSmRequired(SM *psm, OID oid);\n\nOID OidFromSmIsms(SM *psm, int isms);\n\nvoid RetractSma(SMA *psma);\n\nvoid SetSmaGoal(SMA *psma, OID oid);\n\nvoid GetSmaGoal(SMA *psma, OID *poid);\n\nvoid GetSmaCur(SMA *psma, OID *poid);\n\nvoid GetSmaNext(SMA *psma, OID *poid);\n\nvoid SetSmaSvt(SMA *psma, float svt);\n\nvoid SeekSma(SMA *psma, OID oid);\n\nvoid ChooseSmaTransition(SMA *psma);\n\nvoid EndSmaTransition(SMA *psma);\n\nvoid HandleSmaMessage(SMA *psma, MSGID msgid, void *pv);\n\nvoid SkipSma(SMA *psma, float dtSkip);\n\nvoid SendSmaMessage(SMA *psma, MSGID msgid, void *pv);\n\nvoid NotifySmaSpliceOnEnterState(SMA *psma, int ismsFrom, int ismsTo);\n\n#endif // SM_H\n"
  },
  {
    "path": "include/smartguard.h",
    "content": "#ifndef SMARTGUARD_H\n#define SMARTGUARD_H\n\n#include \"common.h\"\n#include <stepguard.h>\n#include <actseg.h>\n#include <cid.h>\n#include <mq.h>\n#include <so.h>\n\nstruct SGFT\n{\n    /* 0x00 */ OID oidTarget;\n    /* 0x04 */ ALO *paloTarget;\n};\n\n/**\n * @class SMART_GUARD\n * @brief non-flashlight guard.\n */\nstruct SMARTGUARD : public STEPGUARD\n{\n    // ...\n    /* 0xc38 */ SGFT mpsgssgft[SGS_Max];\n    // ...\n};\n\nvoid InitSmartguard(SMARTGUARD *psmartguard);\n\nvoid PostSmartguardLoadFlashlight(SMARTGUARD *psmartguard);\n\nvoid UseSmartguardFlashlightTarget(SMARTGUARD *psmartguard, SGS sgs, OID oidTarget);\n\n/**\n * @todo Figure out what this function does, determine the right types and rename.\n */\nvoid FUN_001B7100(SMARTGUARD *psmartguard, int unk);\n\nvoid PostSmartguardLoad(SMARTGUARD *psmartguard);\n\nint FFilterSmartguardDetect(SMARTGUARD *psmartguard, SO *pso);\n\nint FDetectSmartguard(SMARTGUARD *psmartguard);\n\nvoid UpdateSmartguard(SMARTGUARD *psmartguard, float dt);\n\nvoid UpdateSmartguardFlashlight(SMARTGUARD *psmartguard);\n\nvoid OnSmartguardEnteringSgs(SMARTGUARD *psmartguard, SGS sgsPrev, ASEG *pasegOverride);\n\nint FCanSmartguardAttack(SMARTGUARD *psmartguard);\n\nSGAS SgasGetSmartguard(SMARTGUARD *psmartguard);\n\nvoid HandleSmartguardMessage(SMARTGUARD *psmartguard, MSGID msgid, void *pv);\n\nvoid FreezeSmartguard(SMARTGUARD *psmartguard, int fFreeze);\n\n#endif // SMARTGUARD_H\n"
  },
  {
    "path": "include/so.h",
    "content": "/**\n * @file so.h\n *\n * @brief Scene objects.\n*/\n#ifndef SO_H\n#define SO_H\n\n#include \"common.h\"\n#include <geom.h>\n#include <util.h>\n#include <mark.h>\n#include <alo.h>\n#include <mat.h>\n#include <vec.h>\n#include <sw.h>\n#include <sm.h>\n#include <cm.h>\n\n// Forward.\nclass CBinaryInputStream;\nstruct XA;\nstruct XP;\nstruct RO;\nstruct WKR;\nstruct ZPR;\nstruct WATER;\nstruct CNSTR;\nstruct CONSTR;\n\ntypedef int GRFFSO;\n\n/**\n * @brief Unknown.\n * @todo Does this belong here?\n */\nenum EGK\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n * @todo Does this belong here?\n */\nenum CT\n{\n    CT_Free = 0,\n    CT_Tangent = 1,\n    CT_Project = 2,\n    CT_Locked = 3\n};\n\nenum FSO\n{\n    FSO_FindChild = 0x1,\n    FSO_FindImmediateChild = 0x2,\n    FSO_FindParent = 0x3,\n    FSO_FindNearest = 0x4,\n    FSO_FindAll = 0x5,\n    GRFFSO_FindMask = 0xFF,\n    FSO_IncludeRemovedObjects = 0x100,\n    FSO_ReturnActualCount = 0x200\n};\n\n/**\n * @class OBJECT\n * @brief Unknown, related to level objects.\n *\n * @todo Implement struct.\n */\nstruct SO : public ALO\n{\n    // ...\n    //* 0x368 */ float mass;\n};\n\n/**\n * @brief Initialize the given SO.\n *\n * @param pso Pointer to the SO.\n */\nvoid InitSo(SO *pso);\n\n/**\n * @brief Event handler for SO added to world(?)\n *\n * @param pso Pointer to the SO.\n */\nvoid OnSoAdd(SO *pso);\n\n/**\n * @brief Event handler for SO removed from world(?)\n *\n * @param pso Pointer to the SO.\n */\nvoid OnSoRemove(SO *pso);\n\nvoid EnableSoPhys(SO *pso, int fPhys);\n\nvoid DisplaceSo(SO *pso, int fParentDirty);\n\nvoid ImpactSo(SO *pso, int fParentDirty);\n\nvoid PivotSo(SO *pso, int fParentDirty);\n\nvoid ExtendSoBounds(SO *pso, VECTOR *ppos, float sRadius);\n\nvoid UpdateSoBounds(SO *pso);\n\nvoid UpdateGeomWorld(GEOM *pgeomLocal, GEOM *pgeomWorld, VU_VECTOR pos, MATRIX3 *pmat);\n\nvoid UpdateSoXfWorldHierarchy(SO *pso);\n\nvoid UpdateSoXfWorld(SO *pso);\n\nint FIgnoreSoIntersection(SO *pso, SO *psoOther);\n\nvoid UpdateSoImpacts(SO *pso);\n\nfloat UProjectVector(VECTOR *ppos0, VECTOR *ppos1, VECTOR *ppos);\n\nvoid AdjustSoXpLocal(SO *pso, XP *pxp, int ixpd);\n\nvoid CalculateSoAngularEffectWorld(SO *pso, VECTOR *ptau, VECTOR *pdw);\n\nvoid AccelSoTowardPosSpring(SO *pso, VECTOR *pposTarget, CLQ *pclqPos, VECTOR *pvTarget, CLQ *pclqV, float dt);\n\nvoid AccelSoTowardMatSpring(SO *pso, MATRIX3 *pmatTarget, CLQ *pclqRot, VECTOR *pwTarget, CLQ *pclqW, float dt);\n\n/**\n * @brief TODO.\n */\nvoid PresetSoAccel(SO *pso, float dt);\n\nvoid DrawGeom(GEOM *pgeom, CM *pcm, RGBA *rgba);\n\nvoid RenderSoSelf(SO *pso, CM *pcm, RO *pro);\n\nvoid UpdateSo(SO *pso, float dt);\n\n/**\n * @brief Sets the mass of a scene object.\n *\n * @param pso Pointer to the SO.\n * @param m The new mass value.\n */\nvoid SetSoMass(SO *pso, float m);\n\nvoid AdjustSoMomint(SO *pso, float r);\n\nvoid DiscardSoXps(SO *pso);\n\nvoid UpdateSoPosWorldPrev(SO *pso);\n\nvoid TranslateSoToPos(SO *pso, VECTOR *ppos);\n\nvoid RotateSoToMat(SO *pso, MATRIX3 *pmat);\n\nvoid TranslateSoToPosSafe(SO *pso, VECTOR *ppos, VECTOR *pdpos);\n\nvoid SetSoVelocityVec(SO *pso, VECTOR *pv);\n\nvoid SetSoAngularVelocityVec(SO *pso, VECTOR *pw);\n\nvoid AddSoAcceleration(SO *pso, VECTOR *pdv);\n\nvoid AddSoAngularAcceleration(SO *pso, VECTOR *pdw);\n\nvoid SetSoConstraints(SO *pso, CT ctForce, VECTOR *pnormalForce, CT ctTorque, VECTOR *pnormalTorque);\n\nvoid SetSoParent(SO *pso, ALO *paloParent);\n\nvoid ApplySoProxy(SO *pso, PROXY *pproxyApply);\n\n/**\n * @brief TODO.\n */\nvoid AccelSoTowardMatSmooth(SO *pso, float dt, MATRIX3 *pmat, SMP *psmp);\n\nvoid GetSoCpdefi(SO *pso, float dt, CPDEFI *pcpdefi);\n\nint FIsSoTouching(SO *pso, SO *psoTarget);\n\nSO *PsoFirstSoTouching(SO *pso);\n\n/**\n * @brief Clones an SO.\n */\nvoid CloneSo(SO *pso, SO *psoBase);\n\nvoid ApplySoConstraintWorld(SO *pso, CONSTR *pconstr, VECTOR *pvecWorld, VECTOR *pvecConstr, VECTOR *pvecRemain);\n\nvoid ApplyConstr(CONSTR *pconstr, VECTOR *pvec, VECTOR *pvecConstr, VECTOR *pvecRemain);\n\nvoid ApplySoConstraintLocal(SO *pso, CONSTR *pconstr, VECTOR *pvecLocal, VECTOR *pvecConstr, VECTOR *pvecRemain);\n\nvoid AddSoXa(SO *pso, XA *pxaAdd);\n\nvoid RemoveSoXa(SO *pso, XA *pxaRemove);\n\nvoid AddSoWaterAcceleration(SO *pso, WATER *pwater, float dt);\n\nvoid AddSoExternalAccelerations(SO *pso, XA *pxa, float dt);\n\n/**\n * @brief Load SO from BRX.\n *\n * @param pso Pointer to the SO.\n * @param pbis Pointer to the binary input stream.\n */\nvoid LoadSoFromBrx(SO *pso, CBinaryInputStream *pbis);\n\nvoid SetSoSphere(SO *pso, float sRadius);\n\nvoid SetSoNoInteract(SO *pso, int fNoInteract);\n\nvoid ConstrFromCnstr(CNSTR cnstr, CT *pct, VECTOR *pnormal);\n\nvoid SetSoCnstrForce(SO *pso, CNSTR cnstr);\n\nvoid SetSoCnstrTorque(SO *pso, CNSTR cnstr);\n\nvoid SetSoCameraStyle(SO *pso, CMK cmk);\n\nvoid SetSoIgnoreLocked(SO *pso, int fIgnoreLocked);\n\nvoid SetSoIceable(SO *pso, int fIceable);\n\nvoid SetSoMtlk(SO *pso, MTLK mtlk);\n\nvoid SetSoEdgeGrab(SO *pso, EGK egk);\n\nvoid SendSoMessage(SO *pso, MSGID msgid, void *pv);\n\nXP *PxpFindSoGround(SO *psoRoot, SO *psoLeaf, int *pixpd);\n\nvoid SetSoNoGravity(SO *pso, int fNoGravity);\n\nvoid SetSoNoXpsAll(SO *pso, int fNoXps);\n\nvoid SetSoNoXpsSelf(SO *pso, int fNoXps);\n\nvoid SetSoNoXpsCenter(SO *pso, int fNoXps);\n\nvoid RebuildSoPhysHook(SO *pso);\n\nSO *PsoFindSoPhysHook(SO *psoLeaf, int ib);\n\nvoid RecalcSoLocked(SO *pso);\n\nint FGetSoContactList(SO *pso, void *pvstate);\n\nvoid GetSoContacts(SO *pso, int *pcpso, SO ***papso);\n\nint FSoInStsoList(STSO *pstsoFirst, SO *pso);\n\nvoid GenerateSoSpliceTouchingEvents(SO *pso);\n\nint FInflictSoZap(SO *pso, XP *pxp, ZPR *pzpr);\n\nvoid EnsureSoLvo(SO *pso);\n\nvoid ProjectSoLvo(SO *pso, float dt);\n\nvoid ProjectSoTransform(SO *pso, float dt, int fForce);\n\nvoid ApplySoImpulse(SO *pso, VECTOR *ppos, VECTOR *pv, float sftMax);\n\nvoid CalculateSoTrajectoryApex(SO *pso, VECTOR *pposTarget, float dzMax, VECTOR *pv);\n\nint FAbsorbSoWkr(SO *pso, WKR *pwkr);\n\nvoid CloneSoPhys(SO *pso, SO *psoPhys, int cposExtra);\n\n#endif // SO_H\n"
  },
  {
    "path": "include/solve.h",
    "content": "/**\n * @file solve.h\n */\n#ifndef SOLVE_H\n#define SOLVE_H\n\n#include <so.h>\n#include <dl.h>\n#include <vec.h>\n\ntypedef int GRFSG;\n\n/**\n * @brief Unknown.\n */\nenum DZK\n{\n    DZK_Normal = 0,\n    DZK_Friction = 1,\n    DZK_Equality = 2,\n};\n\n/**\n * @brief Unknown.\n */\nstruct FX\n{\n    VECTOR dv;\n    VECTOR dw;\n};\n\n/**\n * @brief Unknown.\n */\nstruct XP\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n *\n * @todo Based on the May 19 prototype.\n * May be incomplete and/or inaccurate.\n */\nstruct DZ\n{\n    XP *pxp;\n    undefined1 unknown[12];\n    VECTOR f;\n    FX *aafx[2];\n    DZK dzk;\n    int fMax;\n    float sfMax;\n    float sf;\n    float sdv;\n    float dsdv;\n    VECTOR *mpipxpdv;\n    float *mpidzg;\n    DZ *pdzOther;\n    DLE dle;\n    // ...\n};\n\nvoid RenumberSo(SO *pso, int *pcpso, SO **apso);\n\nvoid CalculateSoEffect(SO *pso, VECTOR *ppos, FX *pfx, VECTOR *pdv);\n\nvoid PropagateSoForce(SO *psoRoot, GRFSG grfsg, XP *pxp, int ixpd, DZ *pdz, FX *afx);\n\nvoid DistributeSoEffects(SO *psoRoot, GRFSG grfsg, int cpso, SO **apso, FX *afx);\n\nvoid SolveSwGroup(SW *psw, int cpsoRoot, SO **apsoRoot, int cpxp, XP **apxp, float dt, GRFSG grfsg);\n\nint CpxpBuildXpArray(int cpso, SO **apso, int cpxpMax, XP **apxp);\n\nvoid BuildContactGroup(SO *psoSeed, int *pcpso, SO **apso, int *pcpsoLocked, SO **apsoLocked);\n\nvoid SplitSoFreeze(SO *pso, int fFreeze);\n\nvoid SortSwGroup(int cpso, SO **apso);\n\nvoid SplitSwGroup(SW *psw, int cpso, SO **apso, float dt, GRFSG grfsg);\n\nvoid SolveSw(SW *psw, float dt, GRFSG grfsg);\n\n#endif // SOLVE_H\n"
  },
  {
    "path": "include/sort.h",
    "content": "/**\n * @file sort.h\n */\n#ifndef SORT_H\n#define SORT_H\n\n#include \"common.h\"\n\n/**\n * @brief Comparison function pointer for sorting.\n */\ntypedef int (* PFNCMP)(void *, void *);\n\n/**\n * @brief Swaps two entries in an array.\n * The swap is performed using 4-bytes at a time.\n *\n * @param afoo Pointer to the array.\n * @param cb   Size of each element in bytes.\n * @param i1   Index of the first element to swap.\n * @param i2   Index of the second element to swap.\n */\nvoid SwapEntries(void *afoo, int cb, int i1, int i2);\n\n/**\n * @brief Sorts an array in-place using the heap sort algorithm.\n *\n * @param afoo   Pointer to the array.\n * @param iMac   Number of elements in the array.\n * @param cb     Size of each element in bytes.\n * @param pfncmp Pointer to a comparison function.\n */\nvoid HeapSort(void *afoo, int iMac, int cb, PFNCMP pfncmp);\n\n#endif // SORT_H\n"
  },
  {
    "path": "include/sound.h",
    "content": "/**\n * @file sound.h\n *\n * @brief Sound playback.\n */\n#ifndef SOUND_H\n#define SOUND_H\n\n#include \"common.h\"\n#include <util.h>\n\n// Forward.\nstruct ALO;\n\n/**\n * @brief SFX ID.\n *\n * @todo Figure out what DAT_00262050 is as well as what value is being used in the following functions:\n *   WakeSoWater (Gets sound 0, 16, 32, or 48 from DAT_00262050)\n *   FireExplsExplso (Seems like an enemy or actor that moves and emits particles)\n *   StartSwIntermittentSounds()\n *   SetJtJtcs()\n *   FUN_001eb748\n */\nenum SFXID\n{\n    SFXID_UnkNeg2 = -2, // Found in FUN_001be8f8()\n    SFXID_Nil = -1,     // Used to call a sound in FUN_001a54f8() for some reason?\n    SFXID_UiTick = 0,   // Probably wrong value, but needed for UpdateCodes in joy.c. Also Found in FUN_001ed318\n    SFXID_Unk1 = 1,     // Found in RebuildTimerAchzDraw()\n    SFXID_Click1 = 2,\n    SFXID_Swoosh = 3,\n    SFXID_JtFootfall1 = 4,\n    SFXID_JtFootfall2 = 5,\n    SFXID_JtFootfall3 = 6,\n    SFXID_JtFootfall4 = 7,\n    SFXID_EnvCaneReach1 = 8,\n    SFXID_EnvCaneReach2 = 9,\n    SFXID_EnvCaneReach3 = 10,\n    SFXID_Cane_Attack1 = 11,\n    SFXID_EnvDartsHit = 12,\n    SFXID_CaneHandleLock = 13,\n    SFXID_Unk14 = 14,   // Found in SetJtJts()\n    SFXID_Unk15 = 15,   // Found in UndeinedFunction_001b17b0()\n    SFXID_Fire = 19,\n    SFXID_Thud1 = 20,\n    SFXID_EnvAlarmSounding = 21,\n    SFXID_EnvCricketChirp = 22,\n    SFXID_Splash = 22, // note: same value as EnvCricketChirp....No idea why theres a dupe.\n    SFXID_Unk26 = 26,   // Found in FUN_001b01b0()\n    SFXID_AmbElectric = 27,\n    SFXID_Unk33 = 33,   // Found in FUN_001999d0()\n    SFXID_Unk34 = 34,   // Found in FUN_001eef90()\n    SFXID_Ripoff_Something = 35,\n    SFXID_Env_Holographic_Marker = 40,\n    SFXID_Unk42 = 42,   // Found in BreakBrk()\n    SFXID_Bottle_Break = 44,\n    SFXID_Darts_Fire = 51,\n    SFXID_EnvDartsHi = 52,\n    SFXID_Unk53 = 53,   // Found in FUN_0013bf68()\n    SFXID_Roc_Hit = 55,\n    SFXID_Blaster_Fire = 58,\n    SFXID_Unk59 = 59,   // Found in FUN_0019b378\n    SFXID_Npc_Whistle = 63,\n    SFXID_Unk65 = 65,   // Found in FUN_0015ad80(), FUN_0015ae38(), FUN_0015b128()\n    SFXID_Unk71 = 71,   // Found in UpdateStepFootfall(). Most likely Land sound.\n    SFXID_Unk72 = 72,   // Found in UpdateStepFootfall(). Most likely Land sound.\n    SFXID_Jt_Land = 73,\n    SFXID_Unk74 = 74,   // Found in UpdateStepFootfall(). Most likely Land sound.\n    SFXID_Unk77 = 77,   // Found in SetJtJts()\n    SFXID_Unk78 = 78,   // Found in SetJtJts()\n    SFXID_Unk79 = 79,   // Found in SetJtJts()\n    SFXID_Unk80 = 80,   // Found in SetJtJts()\n    SFXID_Unk81 = 81,   // Found in ExitedRobRoh(), FUN_001eb748()\n    SFXID_Unk89 = 89,   // Found in SetJtJts()\n    SFXID_unk90 = 90,   // Found in UpdateSuvActive()\n    SFXID_Unk103 = 103, // Found in FUN_001d32d8()\n    SFXID_Collect_Life = 105,\n    SFXID_Last_Clue = 106,\n    SFXID_Yipee = 109,\n    SFXID_Binoc_Hum = 112,\n    SFXID_Binoc_Zoom = 113,\n    SFXID_Unk114 = 114,   // Found in RebuildTimerAchzDraw()\n    SFXID_Click2 = 115,\n    SFXID_Collect_Charm = 116,\n    SFXID_Sneaky_Footstep = 119,\n    SFXID_Collect_Coin = 120,\n    SFXID_Click3 = 121,\n    SFXID_Click4 = 122,\n    SFXID_Thud7 = 123,\n    SFXID_Unk126 = 126,   // Found in SetJtJts(), UpdateJtActive(), RebuildTimerAchzDraw(), runs_on_cane_hook_grab()\n    SFXID_Unk127 = 127,   // Found in RebuildTimerAchzDraw()\n    SFXId_unk138 = 138,   // Found in SetWmWms()\n    SFXId_unk139 = 139,   // Found in SetWmWms()\n    SFXID_Unk140 = 140,   // Found in SetTvTvgs()\n    SFXID_Unk141 = 141,   // Found in SetTvTvgs()\n    SFXID_Take_out_Binoc = 142,\n    SFXID_Put_Away_Binoc = 143,\n    SFXID_Unk148 = 148,   // Found in SetJtJts()\n    SFXID_Jt_Hurt = 163,\n    SFXID_Unk166 = 166,   // Found in FUN_001d5398()\n    SFXID_Unk333 = 333,   // Found in FUN_001a4070()\n    SFXID_Unk334 = 334,   // Found in FUN_001a54f8()\n    SFXID_Ripoff_Hit = 335,\n    SFXID_Unk336 = 336,   // Found in SetRovRovts()\n    SFXID_Honk = 337,\n    SFXID_Ricochet = 338,\n    SFXID_Unk429 = 429,   // Found in init_burning_rubber()\n    SFXID_Unk431 = 431,   // Found in init_burning_rubber()\n    SFXID_Unk443 = 443,   // Found in init_burning_rubber()\n    SFXID_Unk460 = 460,   // Found in FUN_0018ae38()\n    SFXID_Unk466 = 466,   // Found in init_burning_rubber()\n    SFXID_Unk637 = 637,   // Found in init_burning_rubber()\n    SFXID_Unk639 = 639,   // Found in init_burning_rubber()\n    SFXID_Unk640 = 640,   // Found in init_burning_rubber()\n    SFXID_Unk678 = 678,   // Found in init_burning_rubber()\n    SFXID_Unk731 = 731,   // Found in init_burning_rubber()\n    SFXID_Unk732 = 732,   // Found in init_burning_rubber()\n    SFXID_Unk733 = 733,   // Found in init_burning_rubber()\n    SFXID_Unk734 = 734,   // Found in init_burning_rubber()\n};\n\nenum MVGK\n{\n    MVGK_Effects = 0x0,\n    MVGK_Music = 0x1,\n    // MVGK_Dialog = 0x2,\n    // MVGK_User1 = 0x3,\n    // MVGK_User2 = 0x4,\n    // MVGK_UIser3 = 0x5,\n    // MVGK_User4 = 0x6,\n    // MVGK_External = 0x7,\n    // MVGK_Global = 0x8,\n    MVGK_Max = 0x9\n};\n\n/**\n * @brief Ambient sound.\n */\nstruct AMB\n{\n    SFXID sfxid;\n    int iSerial;\n    void *bnk;\n    AMB **ppamb;\n    float tStarted;\n    float uVolAtSource;\n    uint sfxh;\n    undefined4 unk_1;\n    VECTOR pos;\n    ALO *palo;\n    float sStart;\n    float sFull;\n    int fContinuous;\n    int fOutOfRange;\n    int fAttached;\n    int fStopped;\n    float volAttenuated;\n    float pan;\n    float frq;\n    float rDoppler;\n    int dnDoppler;\n    int fPitchOrig;\n    int ptchOrig;\n    float tNext;\n    LM lmRepeat;\n    LM lmRepDist;\n    undefined4 unk_2;\n    undefined4 unk_3;\n    undefined4 unk_4;\n};\n\n/**\n * @brief Sound Effect.\n */\nstruct SFX\n{\n    /* 0x00 */ SFXID sfxid;\n    /* 0x04 */ float sStart;\n    /* 0x08 */ float sFull;\n    /* 0x0c */ float uVol;\n    float uPitch;\n    LM lmRepeat;\n    /* 0x1c */ AMB *pamb;\n    /* 0x20 */ float uDoppler;\n};\n\n/**\n * @brief Excitement.\n * @todo Implement the struct.\n */\nstruct EXC\n{\n    int iexc;\n    DLE dle;\n};\n\ntypedef int IEXC;\n\nextern IEXC g_iexcHyst;\n\n/**\n * @brief Check if a VAG is playing.\n */\nint FVagPlaying();\n\n/**\n * @brief Set VAG unpaused state.\n */\nint SetVagUnpaused();\n\n/**\n * @brief Unknown.\n */\nvoid UnsetExcitement(EXC *pexc);\n\n/**\n * @brief Unknown.\n */\nvoid KillExcitement();\n\n/**\n * @brief Starts up the sound system.\n */\nvoid StartupSound();\n\n/**\n * @brief Ensures the soundbank is available.\n */\nvoid SbpEnsureBank(int bank);\n\n/**\n * @brief Create a new sound effect.\n */\nvoid NewSfx(SFX **ppsfx);\n\n/**\n * @brief Starts sound playback.\n *\n * @param sfxid The sound effect ID\n * @param ppamb Pointer to the ambient sound object\n * @param palo Pointer to the ALO object\n * @param ppos Position of the sound source\n * @param sStart The start time(?)\n * @param sFull The full time(?)\n * @param uVolAtSource Volume at the source\n * @param frq Frequency\n * @param uDoppler Doppler effect\n * @param plmRepeat Pointer to the repeat limit\n * @param plmRepDis Pointer to the repeat distance limit\n */\nvoid StartSound(SFXID sfxid, AMB **ppamb, ALO *palo, VECTOR *ppos, float sStart, float sFull, float uVolAtSource, float frq, float uDoppler, LM *plmRepeat, LM *plmRepDis);\n\n/**\n * @brief TODO\n */\nvoid StopSound(AMB *pamb, int msRampdown);\n\n/**\n * @brief TODO\n */\nvoid SetPambVol(AMB *pamb, float uVolAtSource);\n\n/**\n * @brief TODO\n */\nvoid SetPambFrq(AMB *pamb, float frq);\n\n/**\n * @brief Set the uvol of an mvgk.\n *\n * @note May version takes an mvgk as an argument, but this seems not to.\n */\nvoid SetMvgkUvol(float uvol);\n\n/**\n * @brief Unknown.\n */\nvoid MvgkUnknown1(MVGK mvgk);\n\n/**\n * @brief Sets the rvol of an mvgk.\n */\nvoid SetMvgkRvol(int channel, MVGK mvgk, float rvol);\n\n/**\n * @brief Unknown.\n */\nvoid MvgkUnknown2();\n\n/**\n * @brief Stops everything related to the sound system.\n */\nvoid KillSoundSystem();\n\n/**\n * @brief Unknown.\n */\nvoid KillSounds(int param_1);\n\n/**\n * @brief Unknown.\n */\nvoid FUN_001c0cb0();\n\n#endif // SOUND_H\n"
  },
  {
    "path": "include/spaprops.h",
    "content": "/**\n * @file spaprops.h\n */\n#ifndef SPAPROPS_H\n#define SPAPROPS_H\n\n#include \"common.h\"\n\nvoid BuildEopids();\n\n#endif // SPAPROPS_H\n"
  },
  {
    "path": "include/speaker.h",
    "content": "/**\n * @file speaker.h\n *\n * @brief Sound speaker management.\n */\n#ifndef SPEAKER_H\n#define SPEAKER_H\n\n#include \"common.h\"\n#include <alo.h>\n\n/**\n * @class SPEAKER\n * @brief Sound speaker.\n * @todo Implement the struct.\n */\nstruct SPEAKER : public ALO\n{\n    // ...\n};\n\n// ...\n\n#endif // SPEAKER_H\n"
  },
  {
    "path": "include/spire.h",
    "content": "/**\n * @file spire.h\n */\n#ifndef SPIRE_H\n#define SPIRE_H\n\n#include \"common.h\"\n#include <xform.h>\n\n/**\n * @class SPIRE\n * @brief Spire point that JT can balance on.\n */\nstruct SPIRE : public PNT\n{\n    DLE dleSpire;\n};\n\n#endif // SPIRE_H\n"
  },
  {
    "path": "include/splice/bif.h",
    "content": "/**\n * @file splice/bif.h\n */\n#ifndef SPLICE_BIF_H\n#define SPLICE_BIF_H\n\n#include \"common.h\"\n\n// Forward declaration.\nclass CRef;\nclass CFrame;\n\n/**\n * @enum BIFK\n *\n * @todo Fill in enum.\n */\nenum BIFK\n{\n    // ...\n    BIFK_AddO = 99,\n    BIFK_EnsureO = 100,\n    BIFK_SetO = 101,\n    BIFK_GetO = 102,\n    // ...\n};\n\n/**\n * @brief Comparison Kind.\n */\nenum CMPK\n{\n    CMPK_L = 0,\n    CMPK_LE = 1,\n    CMPK_G = 2,\n    CMPK_GE = 3,\n    CMPK_Max = 4,\n};\n\n/**\n * @brief (?) operation kind?\n */\nenum UFOK\n{\n    UFOK_Sqrt = 0,\n    UFOK_Sin = 1,\n    UFOK_Cos = 2,\n    UFOK_Tan = 3,\n    UFOK_Asin = 4,\n    UFOK_Acos = 5,\n    UFOK_Atan = 6,\n    UFOK_RadNormalize = 7,\n    UFOK_Max = 8,\n};\n\nCRef RefOpAdd(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpSub(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMult(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpDiv(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpPrint(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpPrintFrame(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpPrintSidebag(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIntEqual(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefCmp(CRef *aref, CMPK cmpk);\n\nCRef RefOpL(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpLE(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpG(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpGE(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpEqv(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefEqualHelper(CRef *prefA, CRef *prefB);\n\nCRef RefOpEqual(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsBoolean(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsNum(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsFloat(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsInteger(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsSymbol(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsVector(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsMatrix(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsClq(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsLm(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsSmp(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsList(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsNull(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsObject(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsNullObj(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsMethod(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsProcedure(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpAreNear(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpNot(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpCons(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpCar(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpCdr(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpSetCadr(int carg, CRef *aref, CFrame *pframe, BIFK bifk);\n\nCRef RefOpSetCar(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpSetCdr(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpLength(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpNth(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpIsMember(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpList(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpAppend(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMap(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFilter(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpForEach(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpEval(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVector(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrix(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpSetMusicRegister(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpClq(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpLm(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpSmp(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpGetElement(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpRandomSeed(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpRandom(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefUfo(CRef *pref, UFOK ufok);\n\nCRef RefOpSqrt(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpSin(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpCos(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpTan(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpAsin(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpAcos(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpAtan(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpRadNormalize(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpAtan2(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorDotProduct(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorCrossProduct(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorLth(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorDistance(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorDistanceSquared(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorNormalize(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorProjectNormal(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorProjectTangent(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorBallisticVelocity(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpVectorRadianNormal(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixTranspose(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixInvert(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixCalculateDmat(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixInterpolateRotate(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixDecomposeToTranslate(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixDecomposeToRotate(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixDecomposeToEuler(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixDecomposeToRadianNormal(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixLookAt(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMatrixTiltUpright(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpClqEvaluate(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpClqEvaluateLm(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpClqFit(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpLmLimit(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpLmCheck(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFloor(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpCeiling(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpRound(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpTruncate(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpAbs(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMaximum(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpMinimum(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpModulo(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpCurrentTime(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpScheduleCallback(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpDeferObjectUpdate(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpObjectOption(int carg, CRef *aref, CFrame *pframe, BIFK bifk);\n\nCRef RefOpAddO(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpEnsureO(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpSetO(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpGetO(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefPairFromAplo(int cplo, LO **aplo);\n\nCRef RefOpFindObject(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFindObjects(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFindNearestObject(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFindNearestObjects(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFindPlayerObject(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFindWorldObject(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFindCameraObject(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFindClassObjects(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFindObjectsInBoundingBox(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpFindObjectsInBoundingSphere(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpHitTestObjectsImpl(BIFK bifk, int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpHitTestObjects(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpHitTestObjectsFirst(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpConvertObjectPosition(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpConvertObjectVector(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpConvertObjectMatrix(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpNearClipCenter(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpStartSound(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpStopSound(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpStartRumble(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpEmitSmokeCloud(int carg, CRef *aref, CFrame *pframe);\n\nCRef RefOpPredictAnimationEffect(int carg, CRef *aref, CFrame *pframe);\n\n#endif // SPLICE_BIF_H\n"
  },
  {
    "path": "include/splice/eval.h",
    "content": "/**\n * @file splice/eval.h\n */\n#ifndef SPLICE_EVAL_H\n#define SPLICE_EVAL_H\n\n#include \"common.h\"\n\n// ...\n\n#endif // SPLICE_EVAL_H\n"
  },
  {
    "path": "include/splice/frame.h",
    "content": "/**\n * @file splice/frame.h\n */\n#ifndef SPLICE_FRAME_H\n#define SPLICE_FRAME_H\n\n#include \"common.h\"\n\n// Forward.\nclass CRef;\n\nclass CFrame\n{\nprivate:\n    /* 0x00 */ int m_cpframeParent;\n    /* 0x04 */ CFrame *m_apframeParent[4];\n    // ...\n\npublic:\n    void SetSingleParent(CFrame *pframeParent);\n    void AddParent(CFrame *pframeParent);\n    CFrame *RefAddBinding(int symid, CRef * pref);\n    CFrame *RefSetBinding(int symid, CRef *pref);\n    int FFindBinding(int symid, int fRecursive, CRef *pref);\n    CRef *PrefFindBinding(int symid, int fRecursive);\n    void CloneTo(CFrame *pframeClone);\n};\n\n/**\n * @brief Creates a new frame.\n */\nCFrame *PframeNew();\n\n/**\n * @brief Deletes the frame.\n */\nvoid DeleteFrame(CFrame *pframe);\n\n#endif // SPLICE_FRAME_H\n"
  },
  {
    "path": "include/splice/gc.h",
    "content": "/**\n * @file splice/gc.h\n */\n#ifndef SPLICE_GC_H\n#define SPLICE_GC_H\n\n#include \"common.h\"\n\nclass CFrame;\nclass CPair;\nclass CProc;\nclass CSidebag;\n\nclass CGc\n{\nprivate:\n    int m_cpframeRoot;\n    CFrame *m_apframeRoot[256];\n\n    STRUCT_PADDING(64);\n\n    int m_cpsidebagRoot;\n    CSidebag *m_apsidebagRoot[128];\n    int m_cpframeStack;\n    CFrame *m_apframeStack[512];\n    int m_cppairStack;\n    CPair *m_appairStack[256];\n    int m_cpprocStack;\n    CProc *m_approcStack[1024];\n\npublic:\n    CGc();\n    ~CGc();\n    void Startup();\n    void Shutdown();\n    void AddRootFrame(CFrame *pframe);\n    void AddRootSidebag(CSidebag *psidebag);\n    void PushFrame(CFrame *pframe);\n    CFrame *PframePop();\n    void PushPair(CPair *ppair);\n    CPair *PpairPop();\n    void PushProc(CProc *pproc);\n    CProc *PprocPop();\n    void UpdateRecyclable();\n    void MarkLiveObjects();\n    void Collect();\n};\n\nextern CGc g_gc;\n\n#endif // SPLICE_GC_H\n"
  },
  {
    "path": "include/splice/method.h",
    "content": "/**\n * @file splice/method.h\n */\n#ifndef SPLICE_METHOD_H\n#define SPLICE_METHOD_H\n\n#include \"common.h\"\n\nstruct BASIC;\n\n/**\n * @class CMethod\n */\nclass CMethod\n{\n    BASIC* m_pbasic;\n    void* m_pfnthunk; //todo: fix type?\n    int m_crefReq;\n};\n\nCMethod* PmethodNew();\n\n#endif // SPLICE_METHOD_H\n"
  },
  {
    "path": "include/splice/pair.h",
    "content": "/**\n * @file splice/pair.h\n */\n#ifndef SPLICE_PAIR_H\n#define SPLICE_PAIR_H\n\n#include \"common.h\"\n#include \"splice/ref.h\"\n\n/**\n * @class CPair\n *\n * @todo Fill in class.\n */\nclass CPair\n{\n    CRef m_ref;\n    CPair* m_ppairNext;\n\npublic:\n    void CloneTo(CPair* ppairClone, CFrame* pframeClone);\n};\n\nCPair* PpairNew();\nvoid DeletePair(CPair* ppair);\n\n#endif // SPLICE_PAIR_H\n"
  },
  {
    "path": "include/splice/proc.h",
    "content": "/**\n * @file splice/proc.h\n */\n#ifndef SPLICE_PROC_H\n#define SPLICE_PROC_H\n\n#include \"common.h\"\n\nclass CFrame;\nclass CPair;\n\n/**\n * @class CProc\n *\n * @todo Fill in class.\n */\nclass CProc\n{\nprivate:\n    CFrame *m_pframe;\n    CPair *m_ppair;\n    int m_crefReq;\n    int m_fVarArg;\n    CPair *m_ppairCodeExpr;\n\npublic:\n    void CloneTo(CProc *pprocClone, CFrame *pframeClone);\n};\n\nCProc *PprocNew();\n\n#endif // SPLICE_PROC_H\n"
  },
  {
    "path": "include/splice/ref.h",
    "content": "/**\n * @file splice/ref.h\n */\n#ifndef SPLICE_REF_H\n#define SPLICE_REF_H\n\n#include \"common.h\"\n#include <splice/proc.h>\n#include <splice/method.h>\n#include <splice/bif.h>\n#include <basic.h>\n#include <util.h>\n\nclass CPair;\n\nenum TAGK\n{\n    TAGK_Nil = -1,\n    TAGK_None = 0,\n    TAGK_Set = 1,\n    TAGK_Define = 2,\n    TAGK_DefineMacro = 3,\n    TAGK_DefineMacroLambda = 4,\n    TAGK_Assert = 5,\n    TAGK_If = 6,\n    TAGK_Or = 7,\n    TAGK_And = 8,\n    TAGK_Cond = 9,\n    TAGK_Else = 10,\n    TAGK_Case = 11,\n    TAGK_Let = 12,\n    TAGK_While = 13,\n    TAGK_Lambda = 14,\n    TAGK_Begin = 15,\n    TAGK_Import = 16,\n    TAGK_Quote = 17,\n    TAGK_Dot = 18,\n    TAGK_Pipe = 19,\n    TAGK_S32 = 20,\n    TAGK_F32 = 21,\n    TAGK_Vector = 22,\n    TAGK_Matrix = 23,\n    TAGK_Clq = 24,\n    TAGK_Lm = 25,\n    TAGK_Smp = 26,\n    TAGK_Bool = 27,\n    TAGK_Symid = 28,\n    TAGK_Bifk = 29,\n    TAGK_Pair = 30,\n    TAGK_Proc = 31,\n    TAGK_Basic = 32,\n    TAGK_Method = 33,\n    TAGK_Void = 34,\n    TAGK_Err = 35,\n    TAGK_Max = 36\n};\n\nunion TAG\n{\n    int m_n;\n    float m_g;\n    int m_bool;\n    uint m_symid;\n    BIFK m_bifk;\n    CPair* m_ppair;\n    CProc* m_pproc;\n    VECTOR* m_pvector;\n    MATRIX4* m_pmatrix;\n    CLQ* m_pclq;\n    LM* m_plm;\n    SMP* m_psmp;\n    BASIC* m_pbasic;\n    CMethod* m_pmethod;\n};\n\nclass CRef\n{\npublic:\n    TAGK m_tagk;\n    TAG m_tag;\n\n    CRef();\n    CRef(const CRef &ref);\n    ~CRef();\n    CRef &operator=(const CRef &ref);\n    bool operator==(const CRef &ref);\n    void CloneTo(CRef *prefClone, CFrame *pframeClone);\n    void Decref();\n    void Incref();\n    void SetTag(TAGK tagk);\n    void SetS32(int n);\n    void SetF32(float g);\n    void SetBool(int fBool);\n    void SetSymid(uint symid);\n    void SetBifk(BIFK bifk);\n    void SetPair(CPair *ppair);\n    void SetProc(CProc *pproc);\n    void SetVector(VECTOR *pvector);\n    void SetMatrix(MATRIX4 *pmatrix);\n    void SetClq(CLQ *pclq);\n    void SetLm(LM *plm);\n    void SetSmp(SMP *psmp);\n    void SetBasic(BASIC *pbasic);\n    void SetMethod(CMethod *pmethod);\n    int RefCoerceS32() const;\n    float RefCoerceF32() const;\n};\n\n#endif // SPLICE_REF_H\n"
  },
  {
    "path": "include/splice/serialize.h",
    "content": "/**\n * @file splice/serialize.h\n */\n#ifndef SPLICE_SERIALIZE_H\n#define SPLICE_SERIALIZE_H\n\n#include \"common.h\"\n\n// ...\n\n#endif // SPLICE_SERIALIZE_H\n"
  },
  {
    "path": "include/splice/sidebag.h",
    "content": "/**\n * @file splice/sidebag.h\n *\n * @brief Sidebag for splice.\n */\n#ifndef SPLICE_SIDEBAG_H\n#define SPLICE_SIDEBAG_H\n\n#include \"common.h\"\n\nclass CRef;\n\n/**\n * @brief Unknown.\n * @todo Find where this struct should be implemented.\n */\nstruct SBB\n{\n    int n;\n    // CRef ref;\n};\n\n/**\n * @brief Sidebag.\n */\nclass CSidebag\n{\nprivate:\n    int m_csbb;\n    SBB m_asbb[16];\n\npublic:\n    CSidebag& RefAddBinding(int n, CRef *pref);\n\n    CSidebag& RefSetBinding(int n, CRef *pref);\n\n    bool FFindBinding(int n, CRef *pref);\n\n    void CloneTo(CSidebag *psidebagClone);\n};\n\n/**\n * @brief Creates a new sidebag.\n *\n * @return A pointer to the newly created sidebag.\n */\nCSidebag *PsidebagNew();\n\n#endif // SPLICE_SIDEBAG_H\n"
  },
  {
    "path": "include/splice/spliceutils.h",
    "content": "/**\n * @file splice/spliceutils.h\n *\n * @brief Utility functions for the splice scripting engine.\n */\n#ifndef SPLICE_SPLICEUTILS_H\n#define SPLICE_SPLICEUTILS_H\n\n#include \"common.h\"\n\n/**\n * @brief Splice startup function.\n*/\nvoid StartupSplice();\n\n/**\n * @brief Startup function for the splice structured type factories.\n*/\nvoid StartupSpliceStructuredTypeFactories();\n\n#endif // SPLICE_SPLICEUTILS_H\n"
  },
  {
    "path": "include/splice/splotheap.h",
    "content": "/**\n * @file splice/splotheap.h\n */\n#ifndef SPLICE_SPLOTHEAP_H\n#define SPLICE_SPLOTHEAP_H\n\n#include \"common.h\"\n\ntypedef void (*PFNDELETE)(void *);\n\nstruct SPLOT\n{\n    SPLOT *psplotNext;\n    int fAlive;\n};\n\nclass CSplotheap\n{\nprivate:\n    int m_cb;\n    int m_c;\n    byte *m_ab;\n    SPLOT *m_psplotFree;\n    SPLOT *m_psplotAlloc;\n    SPLOT *m_psplotRecyclable;\n\npublic:\n    PFNDELETE m_pfndelete;\n\n    void Startup(int cb, int c);\n    void Shutdown();\n    void *PvAllocUnsafe();\n    void *PvAllocClear();\n    SPLOT *PsplotLookup(int i);\n    void UpdateRecyclable();\n    void UnmarkAll();\n    void FreeGarbage();\n};\n\nextern CSplotheap g_splotheapPair;\nextern CSplotheap g_splotheapFrame;\nextern CSplotheap g_splotheapUnk1;\nextern CSplotheap g_splotheapProc;\nextern CSplotheap g_splotheapMethod;\n\nstatic void *PvFromPsplot(SPLOT *psplot);\nstatic SPLOT *PsplotFromPv(void *pv);\nbool FIsPvGarbage(void *pv);\nvoid MarkPvAlive(void *pv);\n\n#endif // SPLICE_SPLOTHEAP_H\n"
  },
  {
    "path": "include/splice/vecmat.h",
    "content": "/**\n * @file splice/vecmat.h\n */\n#ifndef SPLICE_VECMAT_H\n#define SPLICE_VECMAT_H\n\n#include \"common.h\"\n#include <vec.h>\n#include <mat.h>\n#include <util.h>\n\nVECTOR *PvectorNew();\n\nvoid IncrefVector(VECTOR *pvector);\n\nvoid DecrefVector(VECTOR *pvector);\n\nvoid IncrefMatrix(MATRIX4 *pmatrix);\n\nvoid DecrefMatrix(MATRIX4 *pmatrix);\n\nvoid IncrefClq(CLQ *pclq);\n\nvoid DecrefClq(CLQ *pclq);\n\nvoid IncrefLm(LM *plm);\n\nvoid DecrefLm(LM *plm);\n\nSMP *PsmpNew();\n\nvoid IncrefSmp(SMP *psmp);\n\nvoid DecrefSmp(SMP *psmp);\n\nvoid StartupSpliceStructuredTypeFactories();\n\nvoid ShutdownSpliceStructuredTypeFactories();\n\n#endif // SPLICE_VECMAT_H\n"
  },
  {
    "path": "include/splicemap.h",
    "content": "/**\n * @file splicemap.h\n *\n * @brief Splice maps.\n */\n#ifndef SPLICEMAP_H\n#define SPLICEMAP_H\n\n#include \"common.h\"\n#include <splice/ref.h>\n#include <bis.h>\n#include <sw.h>\n\nvoid LoadSwSpliceFromBrx(SW *psw, CBinaryInputStream *pbis);\n\nCFrame *PframeFromIsplice(int isplice, SW *psw);\n\nCRef RefEvalModule(int isplice, SW *psw);\n\n#endif // SPLICEMAP_H\n"
  },
  {
    "path": "include/spliceobj.h",
    "content": "/**\n * @file spliceobj.h\n *\n * @brief Splice objects.\n */\n#ifndef SPLICEOBJ_H\n#define SPLICEOBJ_H\n\n#include \"common.h\"\n#include <splice/ref.h>\n#include <basic.h>\n#include <brx.h>\n\ntypedef void (*PFNGET)(OTYP);\n\nEOPID *PeopidFind(BASIC *pbasic, int optid);\n\nCRef RefGetObjectList(BASIC *pbasic, OTYP otyp, PFNGET pfnget);\n\nCRef RefGetPeopid(BASIC *pbasic, EOPID *peopid);\n\nint FAppendSpliceListElement(void *pvstate, void *pvdata);\n\nint FSpliceListElementExists(void *pvstate, void *pvdata);\n\nCRef RefSetPvsFromSplice(int cref, CRef *aref, OTYP *aotyp, void **apv);\n\nCRef RefSetArgListFromPvs(int cargs, OTYP *aotyp, void **apv);\n\nCRef RefSetPeopid(BASIC *pbasic, EOPID *peopid, CRef *prefValue);\n\nCRef RefGetOption(BASIC *pbasic, int optid);\n\nCRef RefSetOption(BASIC *pbasic, int optid, CRef *prefValue);\n\nCRef RefAddOption(BASIC *pbasic, int optid, CRef *prefValue);\n\nCRef RefEnsureOption(BASIC *pbasic, int optid, CRef *prefValue);\n\nCRef RefSetArgsFromSplice(int cref, CRef *aref, OTYP *aotyp);\n\n#endif // SPLICEOBJ_H\n"
  },
  {
    "path": "include/sprbuf.h",
    "content": "/**\n * @file sprbuf.h\n */\n#ifndef SPRBUF_H\n#define SPRBUF_H\n\n#include \"common.h\"\n\nvoid LoadSprBuf(int cb);\n\nvoid SaveSprBuf(void *pv);\n\n#endif // SPRBUF_H\n"
  },
  {
    "path": "include/sqtr.h",
    "content": "/**\n * @file sqtr.h\n */\n#ifndef SQTR_H\n#define SQTR_H\n\n#include \"common.h\"\n#include <render.h>\n#include <vec.h>\n#include <mat.h>\n#include <cm.h>\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct SQTRM\n{\n    // ...\n};\n\nvoid UpdateSqtrm(SQTRM *psqtrm, VECTOR *ppos, MATRIX3 *pmat, float swExtra, float dt);\n\nvoid RenderSqtrm(SQTRM *psqtrm, CM *pcm);\n\nvoid DrawSqtrm(RPL *prpl);\n\n#endif SQTR_H\n"
  },
  {
    "path": "include/step.h",
    "content": "/**\n * @file step.h\n */\n#ifndef STEP_H\n#define STEP_H\n\n#include \"common.h\"\n#include <po.h>\n#include <so.h>\n#include <sm.h>\n#include <cm.h>\n#include <bsp.h>\n#include <dzg.h>\n#include <alo.h>\n#include <util.h>\n\n// Forward.\nstruct FX;\nstruct XP;\nstruct SFF;\n\ntypedef int GRFSG;\ntypedef int GRFADJ;\n\n/**\n * @brief STEP_FIGURE\n * @brief Moving/waking characters.\n */\nstruct STEP : public PO\n{\n    ALO *paloLeftFoot;\n    ALO *paloRightFoot;\n    ALO *paloLeftHand;\n    ALO *paloRightHand;\n    ALO *paloLeftHeel;\n    ALO *paloRightHeel;\n    ALO *paloLeftBall;\n    ALO *paloRightBall;\n    float radJoy;\n    float uJoyDeflect;\n    float radTarget;\n    float uTarget;\n    VECTOR vTarget;\n    float zBaseTarget;\n    undefined4 unk_0x614[3];\n    MATRIX3 matTarget;\n    int fBaseXp;\n    float tBaseXp;\n    undefined4 unk_0x658[2];\n    VECTOR posBaseXp;\n    VECTOR normalBaseXp;\n    SO *psoBaseXp;\n    float uFootFall;\n    float tLastFootfall;\n    float dzBase;\n    int iposBase;\n    VECTOR *pposBase;\n    VECTOR *pposBumper;\n    SO *psoPhys;\n    SMP smpSpin;\n    undefined4 unk_0x6ac;\n    CLQ clqDradToURun;\n    float rGravity;\n    SMP smpCompress;\n    SMP smpExpand;\n    undefined4 unk_0x6dc;\n};\n\nvoid InitStep(STEP *pstep);\n\nvoid PostStepLoad(STEP *pstep);\n\nvoid LimitStepHands(STEP *pstep, int fLimit);\n\nvoid RetractStepExtremity(STEP *pstep, ALO *paloExtrem, float sRadius, ALO *paloAdjust, ALO *paloIkh);\n\nvoid RenderStepSelf(STEP *pstep, CM *pcm, RO *pro);\n\nvoid ReadStepJoystick(STEP *pstep, JOY *pjoy);\n\nvoid UpdateStepFootfall(STEP *pstep, float u, SFF *psff);\n\nvoid UpdateStepPhys(STEP *pstep);\n\nvoid SetStepPhys(STEP *pstep, SO *pso, int fForceSnap);\n\nvoid UpdateStep(STEP *pstep, float dt);\n\nCT CtTorqueStep(STEP *pstep);\n\nvoid PropagateStepForce(STEP *pstep, GRFSG grfsg, XP *pxp, int ixpd, DZ *pdz, FX *afx);\n\nvoid RotateStepToMat(STEP *pstep, MATRIX3 *pmat);\n\nvoid CloneStepPhys(STEP *pstep, SO *psoPhys, int cposExtra);\n\nvoid PresetStepAccel(STEP *pstep, float dt);\n\nvoid PresetStepAccelBase(STEP *pstep);\n\nint FCheckStepXpBase(STEP *pstep, XP *pxp, int ixpd);\n\nvoid AdjustStepNewXp(STEP *pstep, XP *pxp, int ixpd);\n\nvoid AdjustStepDz(STEP *pstep, GRFADJ grfadj, DZ *pdz, int ixpd, float dt);\n\nvoid AdjustStepDzBase(STEP *pstep, GRFADJ grfadj, DZ *pdz, int ixpd);\n\nvoid UpdateStepMatTarget(STEP *pstep);\n\nvoid AdjustStepXpVelocity(STEP *pstep, XP *pxp, int ixpd);\n\nvoid UpdateStepXfWorld(STEP *pstep);\n\nvoid AdjustStepXpVelocityBase(STEP *pstep, XP *pxp, int ixpd);\n\nvoid AdjustStepXps(STEP *pstep);\n\nvoid AddStepCustomXps(STEP *pstep, SO *psoOther, int cbspPruned, BSP *abspPruned, BSP *pbspPruned, XP **ppxpFirst);\n\nvoid AddStepCustomXpsBase(STEP *pstep, SO *psoOther, BSP *pbspPruned, XP **ppxpFirst);\n\nvoid FixStepAngularVelocity(STEP *pstep);\n\nvoid PredictStepPosition(STEP *pstep, float dtOffset, VECTOR *ppos, VECTOR *pv);\n\nvoid PredictStepRotation(STEP *pstep, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\nvoid SetStepSpinRatio(STEP *pstep, float r);\n\nvoid SetStepGravityRatio(STEP *pstep, float rGravity);\n\n#endif // STEP_H\n"
  },
  {
    "path": "include/stepact.h",
    "content": "/**\n * @file stepact.h\n */\n#ifndef STEPACT_H\n#define STEPACT_H\n\n#include \"common.h\"\n#include <act.h>\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct ACTADD : public ACT\n{\n    // ...\n};\n\nvoid GetActaddPositionGoal(ACTADD *pactadd, float dtOffset, VECTOR *ppos, VECTOR *pv);\nvoid GetActaddRotationGoal(ACTADD *pactadd, float dtOffset, MATRIX3 *pmat, VECTOR *pw);\n\n#endif // STEPACT_H\n"
  },
  {
    "path": "include/stepcane.h",
    "content": "/**\n * @file stepcane.h\n */\n#ifndef STEPCANE_H\n#define STEPCANE_H\n\n#include \"common.h\"\n#include <target.h>\n#include <break.h>\n#include <joy.h>\n#include <jt.h>\n\n// Forward.\nstruct ASEGBL;\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct BL\n{\n    // ...\n};\n\nvoid SetJtJtcs(JT *pjt, JTCS jtcs);\n\nvoid UpdateJtCane(JT *pjt);\n\nvoid UpdateJtActiveCane(JT *pjt, JOY *pjoy);\n\nvoid ChooseJtAttackTarget(JT *pjt, GRFTAK grftak, VECTOR *pposNaturalLocal, float dtProj, float dradMax, TARGET **pptarget, VECTOR *pdposProj);\n\nvoid ChooseJtSweepTarget(JT *pjt, BL *ablSweep, ASEGBL *pasegbl);\n\nvoid ChooseJtRushTarget(JT *pjt);\n\nvoid ChooseJtSmashTarget(JT *pjt);\n\n#endif // STEPCANE_H\n"
  },
  {
    "path": "include/stepguard.h",
    "content": "/**\n * @file stepguard.h\n */\n#ifndef STEPGUARD_H\n#define STEPGUARD_H\n\n#include \"common.h\"\n#include <alarm.h>\n#include <step.h>\n#include <zap.h>\n\n// Forward.\nstruct ASEG;\n\n/**\n * @brief Unknown.\n */\nenum SGAS\n{\n    SGAS_Nil = -1,\n    SGAS_No = 0,\n    SGAS_Yes = 1,\n    SGAS_Force = 2,\n    SGAS_Max = 3\n};\n\n/**\n * @brief Stepguard (?) state.\n */\nenum SGGS\n{\n    SGGS_Nil = -1,\n    SGGS_Patrol = 0,\n    SGGS_Search = 1,\n    SGGS_Attack = 2,\n    SGGS_Dead = 3,\n    SGGS_Max = 4\n};\n\n/**\n * @brief Stepguard State.\n */\nenum SGS\n{\n    SGS_Nil = -1,\n    SGS_Reset = 0,\n    SGS_Patrol = 1,\n    SGS_PatrolIdle = 2,\n    SGS_PatrolWaypoint = 3,\n    SGS_ReturnToPatrol = 4,\n    SGS_Search = 5,\n    SGS_SearchIdle = 6,\n    SGS_Discover = 7,\n    SGS_LostPlayer = 8,\n    SGS_GiveUpSearch = 9,\n    SGS_Taunt = 10,\n    SGS_Dying = 11,\n    SGS_Pursue = 12,\n    SGS_PursueIdle = 13,\n    SGS_Attack = 14,\n    SGS_AttackIdle = 15,\n    SGS_Stun = 16,\n    SGS_Max = 17\n};\n\n/**\n * @brief Stepguard (?).\n * @todo Implement the struct.\n */\nstruct SGG : public LO\n{\n    // ...\n    /* 0x168 */ int calarms;        // count of alarms\n    /* 0x16c */ ALARM **palarms;    // array of alarm pointers\n    // ...\n    /* 0x180 */ OID oidSync;\n    // ...\n};\n\n/**\n * @class STEP_GUARD\n * @brief Non-flashlight guard.\n */\nstruct STEPGUARD : public STEP\n{\n    // ...\n    /* 0x720 */ SGG *psgg;\n    /* 0x724 */ SGS sgs;\n    /* 0x728 */ STRUCT_PADDING(11);\n    /* 0x754 */ ASEGA *pasegaPatrol;\n    /* 0x758 */ STRUCT_PADDING(35);\n    /* 0x7e0 */ ASEGA *pasegaSgs;\n    /* 0x7e4 */ STRUCT_PADDING(203);\n    /* 0xb10 */ int ichkDead;\n    /* 0xb14 */ STRUCT_PADDING(24);\n    /* 0xb74 */ STEPGUARD *pstepguardBase;\n    // ...\n};\n\n/**\n * @brief Initializes the stepguard fields with default values.\n */\nvoid InitStepguard(STEPGUARD *pstepguard);\n\nvoid LoadStepguardFromBrx(STEPGUARD *pstepguard, CBinaryInputStream *pbis);\n\nvoid CloneStepguard(STEPGUARD *pstepguard, STEPGUARD *pstepguardBase);\n\nvoid BindStepguard(STEPGUARD *pstepguard);\n\nvoid PostStepguardLoadCallback(STEPGUARD *pstepguard, MSGID msgid, void *pv);\n\nvoid PostStepguardLoad(STEPGUARD *pstepguard);\n\nint FIgnoreStepguardIntersection(STEPGUARD *pstepguard, SO *psoOther);\n\nvoid OnStepguardAdd(STEPGUARD *pstepguard);\n\nvoid OnStepguardRemove(STEPGUARD *pstepguard);\n\nvoid PresetStepguardAccel(STEPGUARD *pstepguard, float dt);\n\nfloat DradEnemyStepguard(STEPGUARD *pstepguard);\n\nvoid SetStepguardTargetHeading(STEPGUARD *pstepguard, float radTarget, float radTilt);\n\nvoid UpdateStepguardDrive(STEPGUARD *pstepguard);\n\nvoid UpdateStepguard(STEPGUARD *pstepguard, float dt);\n\nSGS SgsNextStepguardAI(STEPGUARD *pstepguard);\n\nvoid SetStepguardGoal(STEPGUARD *pstepguard, VECTOR *pposGoal);\n\nint FReachedStepguardGoal(STEPGUARD *pstepguard);\n\nint FFilterStepguardJump(STEPGUARD *pstepguard, SO *pso);\n\nvoid MoveStepguardToGoal(STEPGUARD *pstepguard);\n\nvoid LookStepguardAtGoal(STEPGUARD *pstepguard);\n\nvoid UpdateStepguardGoal(STEPGUARD *pstepguard, int fEnter);\n\nvoid OnStepguardWaypointActive(STEPGUARD *pstepguard);\n\nvoid UpdateStepguardSgs(STEPGUARD *pstepguard);\n\nvoid SetStepguardSgs(STEPGUARD *pstepguard, SGS sgs, ASEG *pasegTargetOverride);\n\nvoid SetStepguardSgsExternal(STEPGUARD *pstepguard, SGS sgs, ASEG *pasegTargetOverride);\n\nvoid OnStepguardExitingSgs(STEPGUARD *pstepguard, SGS sgsNext);\n\nvoid OnStepguardEnteringSgs(STEPGUARD *pstepguard, SGS sgsPrev, ASEG *pasegTargetOverride);\n\nSGGS SggsGetStepguard(STEPGUARD *pstepguard);\n\nint FAbsorbStepguardWkr(STEPGUARD *pstepguard, WKR *pwkr);\n\nint FTakeStepguardDamage(STEPGUARD *pstepguard, ZPR *pzpr);\n\nvoid HandleStepguardGrfsgsc(STEPGUARD *pstepguard);\n\nvoid DoStepguardFreefallJump(STEPGUARD *pstepguard);\n\nvoid DoStepguardFreefallLanding(STEPGUARD *pstepguard);\n\nvoid HandleStepguardMessage(STEPGUARD *pstepguard, MSGID msgid, void *pv);\n\nSGAS SgasGetStepguard(STEPGUARD *pstepguard);\n\nint FCanStepguardAttack(STEPGUARD *pstepguard);\n\nvoid RenderStepguardSelf(STEPGUARD *pstepguard, CM *pcm, RO *pro);\n\nint FValidSgs(SGS sgs);\n\nvoid UseStepguardAnimation(STEPGUARD *pstepguard, SGS sgs, OID oidAseg);\n\nvoid UseStepguardAnimationImmediate(STEPGUARD *pstepguard, SGS sgs, OID oidAseg);\n\nvoid UseStepguardDeathAnimation(STEPGUARD *pstepguard, GRFTAK grftak, OID oidAseg);\n\nASEG *PasegFindStepguard(STEPGUARD *pstepguard, OID oidAseg);\n\nvoid LoadStepguardAnimations(STEPGUARD *pstepguard);\n\nvoid UseStepguardExpl(STEPGUARD *pstepguard, OID oidExpl);\n\nvoid UseStepguardRwm(STEPGUARD *pstepguard, OID oidRwm);\n\nvoid UseStepguardPhys(STEPGUARD *pstepguard, SGS sgs, OID oidPhys);\n\nvoid LoadStepguardPhys(STEPGUARD *pstepguard);\n\nvoid AddStepguardEffect(STEPGUARD *pstepguard, OID oidEffect, ZPK zpk);\n\nvoid SetStepguardPathzone(STEPGUARD *pstepguard, OID oidPathzone);\n\nSO *PsoEnemyStepguard(STEPGUARD *pstepguard);\n\nvoid SetStepguardEnemyObject(STEPGUARD *pstepguard, SO *psoEnemy);\n\nvoid RebindStepguardEnemy(STEPGUARD *pstepguard);\n\nvoid AdjustStepguardDz(STEPGUARD *pstepguard, GRFADJ grfadj, DZ *pdz, int ixpd, float dt);\n\nvoid SetStepguardAttackAngleMax(STEPGUARD *pstepguard, float degAttackMax);\n\nvoid AddStepguardAlarm(STEPGUARD *pstepguard, ALARM *palarm);\n\nvoid MatchStepguardAnimationPhase(STEPGUARD *pstepguard, OID oid0, OID oid1, OID oid2, OID oid3);\n\nvoid AddStepguardCustomXps(STEPGUARD *pstepguard, SO *psoOther, int cbspPruned, BSP *abspPruned, BSP *pbspPruned, XP **ppxp);\n\nvoid UpdateStepguardEffect(STEPGUARD *pstepguard);\n\nvoid SetStepguardPatrolAnimation(STEPGUARD *pstepguard, ASEG *pasegPatrol);\n\nint FInflictStepguardZap(STEPGUARD *pstepguard, XP *pxp, ZPR *pzpr);\n\nint FDetectStepguard(STEPGUARD *pstepguard);\n\nint FCheckStepguardEnemyHidden(STEPGUARD *pstepguard);\n\nSGG *PsggNew(SW *psw);\n\nvoid InitSgg(SGG *psgg);\n\nvoid AddSggGuard(SGG *psgg, STEPGUARD *pstepguard);\n\nvoid AddSggGuardName(SGG *psgg, OID oidGuard);\n\nvoid AddSggSearchXfmName(SGG *psgg, OID oidXfm);\n\nvoid RemoveSggGuard(SGG *psgg, STEPGUARD *pstepguard);\n\nvoid BindSgg(SGG *psgg);\n\nvoid PostSggLoadCallback(SGG *psgg, MSGID msgid, void *pv);\n\nvoid EnsureSggCallback(SGG *psgg);\n\nSO *PsoEnemySgg(SGG *psgg);\n\nvoid UpdateSggCallback(SGG *psgg, MSGID msgid, void *pv);\n\nSGGS SggsNextSgg(SGG *psgg);\n\nint FDetectSgg(SGG *psgg);\n\nint FAbandonSggSearch(SGG *psgg);\n\nvoid EnsureSggAlarm(SGG *psgg, ALARM *palarm);\n\nvoid TriggerSggAlarms(SGG *psgg, ALTK altk);\n\nvoid SetSggSggs(SGG *psgg, SGGS sggs);\n\nvoid AssignSggSearchPoints(SGG *psgg);\n\n#endif // STEPGUARD_H\n"
  },
  {
    "path": "include/stephang.h",
    "content": "/**\n * @file stephang.h\n */\n#ifndef STEPHANG_H\n#define STEPHANG_H\n\n#include \"common.h\"\n#include <joy.h>\n#include <jt.h>\n\n// Forward.\nstruct BL;\nstruct FX;\nstruct ASEGBL;\n\ntypedef int GRFAHX;\n\nvoid PostJtLoadSwing(JT *pjt, BL *ablSwing, ASEGBL **ppasegbl);\n\nvoid AnticipateJtForce_(JT *pjt, SO *psoOther, VECTOR *pposOther, VECTOR *pdv, FX *afx);\n\nvoid CalculateJtHangAccel(JT *pjt);\n\nvoid PresetJtAccelHang(JT *pjt);\n\nvoid AddJtExternalAccelerations(JT *pjt, XA *pxa, float dt);\n\nvoid UpdateJtActiveHang(JT *pjt, JOY *pjoy);\n\nvoid CheckJtUnhook(JT *pjt);\n\nvoid UpdateJtHookOx(JT *pjt, LO *ploHook, int fHook);\n\nvoid AddJtHookXps(JT *pjt, GRFAHX grfahx, LO *ploHook, VECTOR *pposHook, VECTOR *pvecHook, VECTOR *pposHang);\n\nvoid GetJtHangHeading(JT *pjt, float *pradForward);\n\nvoid UpdateJtIkHang(JT *pjt);\n\n#endif // STEPHANG_H\n"
  },
  {
    "path": "include/stephide.h",
    "content": "/**\n * @file stephide.h\n */\n#ifndef STEPHIDE_H\n#define STEPHIDE_H\n\n#include \"common.h\"\n#include <jt.h>\n\n// Forward.\nstruct MJR;\nstruct MJH;\nstruct XMG;\nstruct RAIL;\nstruct ACTADJ;\n\n/**\n * @brief Unknown.\n */\nenum HFDK\n{\n    HFDK_Nil = -1,\n    HFDK_Match = 0,\n    HFDK_Left = 1,\n    HFDK_Right = 2,\n    HFDK_Stand = 3,\n    HFDK_Max = 4\n};\n\nJTBS JtbsChooseJtHide(JT *pjt, LO *ploForce, JTHK *pjthk);\n\nvoid MeasureJtJumpToTarget(JT *pjt, VECTOR *pvJump, ALO *palo, VECTOR *pposTarget, VECTOR *pdvTarget, float *pdtJump, float *pgInteg, VECTOR *pposPredict, VECTOR *pvPredict);\n\nvoid GetJtRailLanding(JT *pjt, RAIL *prail, float uRail, VECTOR *ppos, VECTOR *pv);\n\nfloat GMeasureJumpRail(MJR *pmjr, float u);\n\nfloat GMeasureJumpHshape(MJH *pmjh, float s);\n\n// TODO: Add unknown functions here.\n\nvoid UpdateJtActiveHide(JT *pjt, JOY *pjoy);\n\nvoid MatchJtXmgRail(JT *pjt, XMG *pxmg, ACTADJ *pactadj);\n\nvoid UpdateJtHide(JT *pjt);\n\nvoid UpdateJtInternalXpsHide(JT *pjt);\n\nvoid SetJtHfdk(JT *pjt, HFDK hfdk);\n\nvoid ResetJtDynamicTunnel(JT *pjt);\n\nvoid PresetJtAccelHide(JT *pjt);\n\n#endif // STEPHIDE_H\n"
  },
  {
    "path": "include/steppipe.h",
    "content": "/**\n * @file steppipe.h\n */\n#ifndef STEPPIPE_H\n#define STEPPIPE_H\n\n#include \"common.h\"\n#include <pipe.h>\n#include <joy.h>\n#include <jt.h>\n\nvoid PostJtLoadPipe(JT *pjt);\n\nvoid GetJtPipeGoalMat(JT *pjt, PIPE *ppipe, float s, MATRIX3 *pmat);\n\nvoid PresetJtAccelPipe(JT *pjt);\n\nvoid UpdateJtActivePipe(JT *pjt, JOY *pjoy);\n\nvoid UpdateJtInternalXpsPipe(JT *pjt);\n\nvoid SetJtJtpdk(JT *pjt, JTPDK jtpdk);\n\nvoid PlaceJtOnPipe(JT *pjt, PIPE *ppipe);\n\n#endif // STEPPIPE_H\n"
  },
  {
    "path": "include/steppower.h",
    "content": "/**\n * @file steppower.h\n */\n#ifndef STEPPOWER_H\n#define STEPPOWER_H\n\n#include \"common.h\"\n#include <jt.h>\n#include <joy.h>\n#include <game.h>\n\n/**\n * @brief Selected powerup flags.\n */\nenum FSP\n{\n    FSP_Nil = -1,\n    FSP_Dive = 0,\n    FSP_Ball = 1,\n    FSP_SlowDownClock = 2,\n    FSP_Mine = 3,\n    FSP_SpeedUpClock = 4,\n    FSP_Decoy = 5,\n    FSP_Stun = 6,\n    FSP_Max = 7\n};\n\nextern FSP g_fsp;\n\n/*static const char *s_mpfspachz[] = {\n    \"&2T&.: Dive\",\n    \"&2T&.: Roll\",\n    \"&2T&.: Slow\",\n    \"&2T&.: Mine\",\n    \"&2T&.: Fast\",\n    \"&2T&.: Decoy\",\n    \"&2T&.: Stun\"\n};*/\nextern const char *s_mpfspachz[];\n\nextern float RT_JtSpeedUpClock;\nextern float RT_JtSlowDownClock;\n\nextern GRFVAULT s_mpfspgrfvault[]; // Should be static + initialized.\nextern SMP SMP_00274f78; // temp\n\n/**\n * @brief Set the selected powerup.\n *\n * @param fsp Bitflags representing a certain powerup.\n */\nvoid SetFsp(FSP fsp);\n\n/**\n * @brief Update the currently selected powerup.\n *\n * @param pjt Pointer to the jt to update.\n * @param pjoy Pointer to the joypad input.\n */\nvoid UpdateJtActivePowerUp(JT *pjt, JOY *pjoy);\n\n/**\n * @brief Rotate the selected powerup, making the next one in the cycle active.\n *\n * @param pjoy Pointer to the joypad input.\n * @param iCur Current powerup index.\n * @param iMax Maximum powerup index.\n * @param mpigrfvault Array of integer bitflags representing which powerups are available.\n *\n * @return Index of the newly active powerup.\n */\nint IRotatePowerUp(JOY *pjoy, int iCur, int iMax, int *mpigrfvault);\n\n#endif // STEPPOWER_H\n"
  },
  {
    "path": "include/steprail.h",
    "content": "/**\n * @file steprail.h\n *\n * @brief Rail behavior for STEP objects.\n */\n#ifndef STEPRAIL_H\n#define STEPRAIL_H\n\n#include \"common.h\"\n#include <jt.h>\n\n/**\n * @brief Unknown function, more research needed.\n */\nvoid func_001D31D0(LO *param_1, int param_2);\n\n/**\n * @brief Unknown function, more research needed.\n */\nvoid func_001D32D8(int param_1, JT *param_2, long param_3);\n\n#endif // STEPRAIL_H\n"
  },
  {
    "path": "include/steprun.h",
    "content": "/**\n * @file steprun.h\n */\n#ifndef STEPRUN_H\n#define STEPRUN_H\n\n#include \"common.h\"\n#include <stepcane.h>\n\n// Forward.\nstruct MRSG;\nstruct ASEGA;\nstruct ASEGBL;\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct BLRUN : public BL\n{\n    // ...\n};\n\nvoid PostStepLoadRun(STEP *pstep, BLRUN *ablrun, ASEGBL **ppasegbl);\n\nvoid CalculateBlrunV(int cblrun, BLRUN *ablrun, MRSG *amrsgBlend, VECTOR *pv);\n\nvoid ProjectStepRunPlant(STEP *pstep, BLRUN *ablrun, float uPlant, float rJt, int iblrunWalk, int iblrunRun, VECTOR *pposPlant);\n\nint FIntersectStepRunPlant(STEP *pstep, VECTOR *pposUp, VECTOR *pposDown, float *pu);\n\nint FReblendAbl2D(int cbBl, int c1, int c2, BL *abl);\n\nvoid AdjustStepRun(STEP *pstep, BLRUN *ablrun, ASEGBL *pasegbl, ASEGA *pasega);\n\nvoid SetStepRunTarget(STEP *pstep, float rad, float u, BLRUN *ablrun, ASEGBL *pasegbl);\n\n#endif // STEPRUN_H\n"
  },
  {
    "path": "include/stepside.h",
    "content": "/**\n * @file stepside.h\n */\n#ifndef STEPSIDE_H\n#define STEPSIDE_H\n\n#include \"common.h\"\n#include <stepcane.h>\n\n// Forward.\nstruct JT;\nstruct ASEGBL;\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct BLSS : public BL\n{\n    // ...\n};\n\nvoid PostJtLoadSidestep(JT *pjt, BLSS *ablss, ASEGBL **ppasegbl);\n\nvoid AdjustJtSidestep(JT *pjt, BLSS *ablss, ASEGBL *pasegbl);\n\nvoid SetJtSidestepTarget(JT *pjt, BLSS *ablss, ASEGBL *pasegbl, float rad, float u);\n\n#endif // STEPSIDE_H\n"
  },
  {
    "path": "include/stepzap.h",
    "content": "/**\n * @file stepzap.h\n */\n#ifndef STEPZAP_H\n#define STEPZAP_H\n\n#include \"common.h\"\n\n// ...\n\n#endif // STEPZAP_H\n"
  },
  {
    "path": "include/stream.h",
    "content": "/**\n * @file stream.h\n *\n * @brief Output stream.\n */\n#ifndef STREAM_H\n#define STREAM_H\n\n#include \"common.h\"\n\n/**\n * @brief Output stream.\n */\nstruct OSTRM\n{\n    uchar *m_abDest;\n    int m_cbDest;\n    int m_ibCur;\n    int m_fd;\n    int m_cbWritten;\n    int m_cbBuffered;\n    uchar m_abBuffered[1024];\n\n    /**\n     * @brief Create a new output stream that writes to a file.\n     *\n     * @param fd File descriptor.\n     */\n    OSTRM(int fd);\n\n    /**\n     * @brief Create a new output stream that writes to a buffer.\n     *\n     * @param abDest Pointer to the destination.\n     * @param cbDest Size of the destination in bytes.\n     */\n    OSTRM(void *abDest, int cbDest);\n\n    ~OSTRM();\n\n    int CbWrite(void *ab, int cb);\n\n    void Flush();\n};\n\n#endif // STREAM_H\n"
  },
  {
    "path": "include/suv.h",
    "content": "/**\n * @file suv.h\n *\n * @brief Smash-up vehicle (the van and other racecars).\n */\n#ifndef SUV_H\n#define SUV_H\n\n#include \"common.h\"\n\n/**\n * @class SMASHUP_VEHICLE\n * @brief Vehicles used in At the Dog Track, A Desperate Race, and Burning Rubber (not A Hazardous Path).\n *\n * @todo What is the base class?\n */\nstruct SUV // : TBD\n{\n    // ...\n};\n\nvoid InitSuv(SUV *psuv);\n\n#endif // SUV_H\n"
  },
  {
    "path": "include/sw.h",
    "content": "/**\n * @file sw.h\n *\n * @brief Scene world?\n */\n#ifndef SW_H\n#define SW_H\n\n#include \"common.h\"\n#include <slotheap.h>\n#include <light.h>\n#include <game.h>\n#include <bis.h>\n#include <vec.h>\n#include <lo.h>\n#include <mq.h>\n#include <cm.h>\n\ntypedef void (*PFNFILTER)(void *, SO *); // TODO: Figure out if this is correct.\n\n// Forward.\nstruct OXA;\nstruct VISMAP;\n\n/**\n * @class WORLD\n *\n * @brief Not fully understood, but everything in the\n * game world is owned by an instance of this struct.\n *\n * @todo Add the rest of the fields.\n */\nstruct SW : public LO\n{\n    /* 0x34   */ int cpsoAll;\n    /* 0x38   */ int cpsoRoot;\n    /* 0x3c   */ DL dlRoot;\n    /* 0x48   */ DL dlChild;\n    /* 0x54   */ DL dlMRD;\n    /* 0x60   */ DL dlBusy;\n    /* 0x6c   */ DL dlBusySo;\n    /* 0x78   */ DL dlMRDRealClock;\n    /* 0x84   */ DL adlHash[512];\n    /* 0x1884 */ LO *aploCidHead[154];\n    /* 0x1aec */ int fAaoxValid;\n    /* 0x1af0 */ SLOTHEAP slotheapOx;\n    /* 0x1afc */ STRUCT_PADDING(3); // Likely a SLOTHEAP.\n    /* 0x1b08 */ SLOTHEAP slotheapXa;\n    /* 0x1b14 */ SLOTHEAP slotheapMq;\n    /* 0x1b20 */ STRUCT_PADDING(14);\n    /* 0x1b58 */ SLOTHEAP slotheapAsega;\n    /* 0x1b64 */ STRUCT_PADDING(6);\n    /* 0x1b7c */ DL dlAsegaPending;\n    /* 0x1b88 */ STRUCT_PADDING(24);\n    /* 0x1be8 */ DL dlLight;\n    /* 0x1bf4 */ STRUCT_PADDING(6);\n    /* 0x1c0c */ SLOTHEAP slotheapStso;\n    /* 0x1c18 */ STRUCT_PADDING(9);\n    /* 0x1c3c */ DL dlProxy;\n    /* 0x1c48 */ DL dlFly;\n    /* 0x1c54 */ DL dlDprize;\n    /* 0x1c60 */ DL dlRat;\n    /* 0x1c6c */ DL dlRathole;\n    /* 0x1c78 */ DL dlDartFree;\n    /* 0x1c84 */ DL dlSpire;\n    /* 0x1c90 */ DL dlRail;\n    /* 0x1c9c */ DL dlLanding;\n    /* 0x1ca8 */ STRUCT_PADDING(9); // Likely 3 DL's.\n    /* 0x1ccc */ DL dlCrfod;\n    /* 0x1cd8 */ STRUCT_PADDING(36);\n    /* 0x1d68 */ LSM lsmDefault;\n    /* 0x1d70 */ STRUCT_PADDING(85);\n    /* 0x1ec4 */ VISMAP *pvismap;\n    /* 0x1ec8 */ MQ *pmqCallbackFirst;\n    /* 0x1ecc */ MQ *pmqCallbackLast;\n    /* 0x1ed0 */ STRUCT_PADDING(274);\n    /* 0x2318 */ float gexcMenu;\n    /* 0x231c */ int cHandsOff;\n    /* 0x2320 */ STRUCT_PADDING(11);\n    /* 0x234c */ float rDarken;\n    /* 0x2350 */ float rDarkenSmooth;\n    // ...\n\n    // MISALIGNED:\n    void (*pcbUpdate)(float fDelta);\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct and figure out where it belongs.\n */\nstruct XA\n{\n    /* 0x00 */ STRUCT_PADDING(3);\n    /* 0x0c */ XA *pxaNextTarget;\n}; // 0x10 bytes.\n\n/**\n * @brief Unknown.\n * @todo Implement the struct and figure out where it belongs.\n */\nstruct STSO\n{\n    /* 0x00 */ STRUCT_PADDING(1);\n    /* 0x04 */ STSO *pstsoNext;\n}; // 0x08 bytes.\n\nextern SW *g_psw;\n\nvoid InitSwDlHash(SW *psw);\n\nvoid InitSw(SW *psw);\n\nvoid DeleteSw(SW *psw);\n\nvoid SetupBulkDataFromBrx(int fLoadBulkData, CBinaryInputStream *pbis);\n\nvoid LoadBulkDataFromBrx(CBinaryInputStream *pbis);\n\nvoid SetSwGravity(SW *psw, float z);\n\n// TODO: Add unknown functions here.\n\nint FOverflowSwLo(SW *psw, LO *plo, int fHiPri);\n\nXA *PxaAllocSw(SW *psw);\n\nvoid FreeSwXaList(SW *psw, XA *pxaFirst);\n\nMQ *PmqAllocSw(SW *psw);\n\nvoid FreeSwMqList(SW *psw, MQ *pmq);\n\nvoid EnsureSwCallback(SW *psw, PFNMQ pfnmq, void *pvContext, MSGID msgid, void *pvCallbackData);\n\nvoid PostSwCallback(SW *psw, PFNMQ pfnmq, void *pvContext, MSGID msgid, void *pvCallbackData);\n\nvoid ClearSwCallbacks(SW *psw, GRFCMQ grfcmq, PFNMQ pfnmq, void *pvContext, MSGID msgid, void *pvCallback);\n\nvoid ProcessSwCallbacks(SW *psw);\n\nvoid ProcessSwSpliceScheduledCallbacks(SW *psw, float dt);\n\nSTSO *PstsoAllocSw(SW *psw);\n\nvoid FreeSwStsoList(SW *psw, STSO *pstsoFirst);\n\nvoid AddSwProxySource(SW *psw, LO *ploProxySource, int cploClone);\n\nLO *PloGetSwProxySource(SW *psw, int ipsl);\n\nvoid IntersectSwBoundingBox(SW *psw, SO *psoIntersect, VECTOR *ppos1, VECTOR *ppos2, PFNFILTER pfn, void *pvContext, int *pcpso, SO ***papso);\n\nvoid IntersectSwBoundingSphere(SW *psw, SO *psoIntersect, VECTOR *pposCenter, float sRadius, PFNFILTER pfn, void *pvContext, int *pcpso, SO ***papso);\n\nvoid RemoveOxa(OXA *poxa, OXA **ppoxaFirst);\n\nvoid InitSwAoxa(SW *psw);\n\nvoid AddOxa(OXA *poxa, OXA **ppoxaFirst);\n\nOXA *PoxaAllocSw(SW *psw, SO *pso);\n\nvoid FreeSwPoxa(SW *psw, OXA *poxa);\n\nvoid CreateSwDefaultLights(SW *psw);\n\nvoid CreateSwPrizes(SW *psw);\n\nvoid LoadSwFromBrx(SW *psw, CBinaryInputStream *pbis);\n\nint FClipLineHomogeneous(VECTOR4 *apos);\n\nvoid DrawLineWorld(VECTOR *ppos1, VECTOR *ppos2, RGBA *rgba, CM *pcm, int fDepthTest);\n\nvoid DrawAxesWorld(VECTOR *ppos, MATRIX3 *pmat, float sScale, CM *pcm, int fDepthTest);\n\nvoid DrawBezWorld(VECTOR *ppos0, VECTOR *pv0, VECTOR *ppos1, VECTOR *pv1, float dtSeg, RGBA *rgba, CM *pcm, int fDepthTest);\n\nvoid SetSwIllum(SW *psw, float uMidtone);\n\nvoid SetSwIllumShadow(SW *psw, float uShadow);\n\nvoid SetSwExcitement(SW *psw, float gexcMenu);\n\nint FLevelSwVisited(SW *psw, WID wid);\n\nint FLevelSwPrimary(SW *psw, WID wid);\n\nint FLevelSwSecondary(SW *psw, WID wid);\n\nint FLevelSwTertiary(SW *psw, WID wid);\n\n// TODO: Add unknown functions here.\n\nvoid SetSwPlayerSuck(SW *psw, float uSuck);\n\nvoid GetSwPlayerSuck(SW *psw, float *puSuck);\n\nvoid IncrementSwHandsOff(SW *psw);\n\nvoid DecrementSwHandsOff(SW *psw);\n\n/**\n * @note Not in the prototype, so name is unofficial.\n */\nint IsSwHandsOff(SW *psw);\n\nvoid IsSwVagPlaying(SW *psw, int *pfPlaying);\n\nvoid SetSwDarken(SW *psw, float rDarken);\n\nvoid SetSwDarkenSmooth(SW *psw, float rDarkenSmooth);\n\nvoid CancelSwDialogPlaying(SW *psw);\n\n#endif // SW_H\n"
  },
  {
    "path": "include/tail.h",
    "content": "/**\n * @file tail.h\n *\n * @brief JT tail physics.\n */\n#ifndef TAIL_H\n#define TAIL_H\n\n#include \"common.h\"\n\n/**\n * @class TAIL\n * @brief Used for Sly's tail, and the accessory on top of the Cooper van.\n */\nstruct TAIL\n{\n    // ...\n};\n\n#endif // TAIL_H\n"
  },
  {
    "path": "include/tank.h",
    "content": "/**\n * @file tank.h\n */\n#ifndef TANK_H\n#define TANK_H\n\n#include \"common.h\"\n#include <jt.h>\n#include <cm.h>\n#include <po.h>\n#include <joy.h>\n#include <zap.h>\n#include <step.h>\n#include <flash.h>\n\n// Forward.\nenum MSGID;\n\n/**\n * @brief Tank State.\n */\nenum TANKS\n{\n    TANKS_Nil = -1,\n    TANKS_Passive = 0,\n    TANKS_Active = 1,\n    TANKS_Zap = 2,\n    TANKS_Dead = 3,\n    TANKS_Peek = 4,\n    TANKS_Max = 5\n};\n\n/**\n * @class HOVER_TANK\n * @brief Hover tank used in A Ghastly Voyage and Rapid Fire Assault.\n */\nstruct TANK : public STEP\n{\n    // ...\n};\n\nvoid InitTank(TANK *ptank);\n\nvoid PostTankLoad(TANK *ptank);\n\nvoid UpdateTank(TANK *ptank, float dt);\n\nvoid UseTankCharm(TANK *ptank);\n\nvoid UpdateTankActive(TANK *ptank, JOY *pjoy, float dt);\n\nvoid OnTankActive(TANK *ptank, int fActive, PO *ppoOther);\n\nvoid RenderTankAll(TANK *ptank, CM *pcm, RO *pro);\n\nvoid ImpactTank(TANK *ptank, int fParentDirty);\n\nint FInvulnerableTank(TANK *ptank, ZPK zpk);\n\nvoid ApplyTankThrow(TANK *ptank, PO *ppo);\n\nint FTakeTankDamage(TANK *ptank, ZPR *pzpr);\n\n// TODO: Define XP.\n// void AdjustTankNewXp(TANK *ptank, XP *pxp, int ixpd);\n\nvoid HandleTankMessage(TANK *ptank, MSGID msgid, void *pv);\n\nJTHS JthsCurrentTank(TANK *ptank);\n\nvoid SetTankTanks(TANK *ptank, TANKS tanks);\n\n#endif // TANK_H\n"
  },
  {
    "path": "include/target.h",
    "content": "/**\n * @file target.h\n */\n#ifndef TARGET_H\n#define TARGET_H\n\n#include \"common.h\"\n#include <dl.h>\n#include <xform.h>\n\n/**\n * @class TARGET\n * @brief Target point defined by a transform, radius, and some other data.\n */\nstruct TARGET : public XFM\n{\n    /* 0x80 */ DLE dleTarget;\n    /* 0x88 */ int grftak;\n    /* 0x8c */ float sRadiusTarget;\n    /* 0x90 */ int fHitTest;\n    undefined4 unk0;\n    undefined4 unk1;\n    undefined4 unk2;\n};\n\nvoid StartupTarget();\n\nvoid ResetTargetList();\n\nvoid InitTarget(TARGET *ptarget);\n\nvoid OnTargetAdd(TARGET *ptarget);\n\nvoid OnTargetRemove(TARGET *ptarget);\n\nvoid CloneTarget(TARGET *ptarget, TARGET *ptargetBase);\n\n#endif // TARGET_H\n"
  },
  {
    "path": "include/text.h",
    "content": "/**\n * @file text.h\n *\n * @brief Text manipulation functions.\n */\n#ifndef TEXT_H\n#define TEXT_H\n\n#include \"common.h\"\n#include <stream.h>\n\n/**\n * @brief Text format value width.\n *\n * @note Based on may proto.\n */\nenum TFVW\n{\n    TFVW_Nil = -1,\n    TFVW_32 = 0,\n    TFVW_16 = 1,\n    TFVW_64 = 2,\n    TFVW_Max = 3\n};\n\n/**\n * @brief Text format type.\n *\n * @note Based on may proto.\n */\nenum TFTS\n{\n    TFTS_Nil = -1,\n    TFTS_Percent = 0,\n    TFTS_Flags = 1,\n    TFTS_Width = 2,\n    TFTS_Precision = 3,\n    TFTS_Type = 4,\n    TFTS_Conversion = 5,\n    TFTS_Done = 6,\n    TFTS_Max = 7\n};\n\n/**\n * @brief Text format structure.\n *\n * @note Based on may proto.\n */\nstruct TFT\n{\n    int fMinus;\n    int fPlus;\n    int fSpace;\n    int fHash;\n    int fZero;\n    int fZeroPrecision;\n    int cchWidth;\n    int cchPrecision;\n    TFVW tfvw;\n    int cCol;\n    int cRow;\n    uchar chConversion;\n    int fUpperize;\n};\n\nint CchParsePchzInt(char *pch, int *pn);\nint CchParsePchzTft(char *pchzFormat, TFT *ptft, char **pval);\nvoid WriteTftPchz(TFT *ptft, OSTRM *postrm, char *pchz);\nint FNegTftUl(TFT *ptft, union UL *pul); // todo: define type of pul\nuint UnRadixFromChConversion(int chConversion);\nint CchAchFromUl(char *achDest, int cchDest, ulong ul, uint unRadix);\nvoid WriteTftUl(TFT *ptft, OSTRM *postrm, ulong ul);\nint ExpFirstFromG(long g);\nchar ChDigitFromG(long g, int expFirst, int exp);\nint CchAchFromDouble(char *achDest, int cchDest, TFT *ptft, long g);\nvoid WriteTftDouble(TFT *ptft, OSTRM *postrm, long g);\nvoid WriteTft(TFT *ptft, OSTRM *postrm, char **pval, ulong param_4, ulong param_5, undefined8 param_6, double param_7);\nint CchOstrmPrintf(OSTRM *postrm, char *pchzFormat, char *val);\n\nextern \"C\"\n{\n    /**\n     * @todo Document this function.\n     */\n    int vprintf(char *pchzFormat, char *val);\n\n    /**\n     * @brief Print formatted output to stdout.\n     *\n     * @param pchzFormat The format string.\n     * @param ... The arguments to format.\n     *\n     * @return The number of characters written.\n     */\n    int printf(char *pchzFormat, ...);\n\n    /**\n     * @todo Document this function.\n     */\n    int vsprintf(char *pchzDest, char *pchzFormat, char *val);\n\n    /**\n     * @brief Write formatted output to a string.\n     *\n     * @param pchzDest The destination string.\n     * @param pchzFormat The format string.\n     * @param ... The arguments to format.\n     *\n     * @return The number of characters written.\n     */\n    int sprintf(char *pchzDest, char *pchzFormat, ...);\n\n    /**\n     * @todo Document this function.\n     */\n    int _vsnprintf(char *pchzDest, int cchDest, char *pchzFormat, char *val);\n\n    /**\n     * @brief Write formatted output to a string with a specified length.\n     *\n     * @param pchzDest The destination string.\n     * @param cchDest The maximum number of characters to write.\n     * @param pchzFormat The format string.\n     * @param ... The arguments to format.\n     *\n     * @return The number of characters written.\n     */\n    int _snprintf(char *pchzDest, int cchDest, char *pchzFormat, ...);\n\n    /**\n     * @brief Count the number of characters in a string.\n     *\n     * @param pchz The string to count.\n     */\n    //uint strlen(char *pchz); // conflicts with built-in strlen\n\n    /**\n     * @brief Copy a string.\n     *\n     * @param pchzDst The destination string.\n     * @param pchzSrc The source string.\n     */\n    //char *strcpy(char *pchzDst, char *pchzSrc); // conflicts with built-in strcpy\n\n    /**\n     * @brief Search for a character in a string.\n     *\n     * @param pchz The string to search.\n     * @param ch The character to search for.\n     *\n     * @return A pointer to the first occurrence of the character in the string, or NULL if the character is not found.\n     */\n    char *strchr(char *pchz, int ch);\n}\n\nvoid UpperizePchz(char *pchz);\n\n#endif // TEXT_H\n"
  },
  {
    "path": "include/thread.h",
    "content": "/**\n * @file thread.h\n *\n * @brief Semaphore, thread, and critical section utilities.\n */\n#ifndef THREAD_H\n#define THREAD_H\n\n#include \"common.h\"\n\n/**\n * @brief Details for a critical section\n */\nstruct CRITSECT\n{\n    int cEnter;\n    int thread;\n    int sema;\n};\n\n/**\n * @brief Create a semaphore.\n *\n * @param initCount Initial count.\n * @param maxCount Maximum count.\n * @return The semaphore ID.\n */\nint SemaCreate(int initCount, int maxCount);\n\n/**\n * @brief Initialize a critical section.\n *\n * @param pcritsect Critical section.\n */\nvoid InitCritSect(CRITSECT* pcritsect);\n\n/**\n * @brief Enter a critical section.\n *\n * @param pcritsect Critical section.\n */\nvoid EnterCritSect(CRITSECT* pcritsect);\n\n/**\n * @brief Leave a critical section.\n *\n * @param pcritsect Critical section.\n */\nvoid LeaveCritSect(CRITSECT* pcritsect);\n\n/**\n * @brief Initialize parameters for a rendering thread.\n */\nvoid StartupThread();\n\nextern CRITSECT g_athread;\n\n#endif // THREAD_H\n"
  },
  {
    "path": "include/tn.h",
    "content": "/**\n * @brief tn.h\n */\n#ifndef TN_H\n#define TN_H\n\n#include \"common.h\"\n#include <alo.h>\n#include <bsp.h>\n#include <vec.h>\n#include <cm.h>\n#include <mq.h>\n\n// Forward.\nstruct RO;\n\n/**\n * @brief Tunnel state?\n */\nenum TNS\n{\n    TNS_Nil = -1,\n    TNS_Out = 0,\n    TNS_In = 1,\n    TNS_Max = 2\n};\n\n/**\n * @class NEW_TUNNEL\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct TN : public ALO\n{\n    // ...\n};\n\n/**\n * @brief Tunnel something (?)\n * @todo Implement the struct.\n */\nstruct TNFN\n{\n    // ...\n};\n\nTNFN *PtnfnFromTn(TN *ptn);\n\nvoid GetTnfnNose(TNFN *ptnfn, CPDEFI *pcpdefi, VECTOR *pposNose, TN *ptnAdjust);\n\nvoid InitTn(TN *ptn);\n\nvoid OnTnRemove(TN *ptn);\n\nvoid LoadTnFromBrx(TN *ptn, CBinaryInputStream *pbis);\n\nvoid PostTnLoad(TN *ptn);\n\nvoid SetTnTns(TN *ptn, TNS tns);\n\nvoid UpdateTnCallback(TN *ptn, MSGID msgid, void *pv);\n\nvoid UpdateTn(TN *ptn, float dt);\n\nvoid RenderTnSelf(TN *ptn, CM *pcm, RO *pro);\n\nvoid FreezeTn(TN *ptn, int fFreeze);\n\nvoid SetTnFocusRatio(TN *ptn, float u);\n\nvoid CalculateTnCrv(TN *ptn, VECTOR *ppos, VECTOR *pdposCrv, VECTOR *pvecClosest);\n\nvoid CalculateTnPos(TN *ptn, VECTOR *pdposCrv, float sBase, float dsOffset, CLQ *aclq, LM *alm, FTND ftnd, VECTOR *pposOther);\n\nvoid ActivateCptn(CPTN *pcptn, void *pv);\n\nvoid DeactivateCptn(CPTN *pcptn, void *pv);\n\nvoid SetCptn(CPTN *pcptn, void *pv);\n\nvoid RevokeCptn(CPTN *pcptn, void *pv);\n\nvoid UpdateCptn(CPTN *pcptn, CPDEFI *pcpdefi, JOY *pjoy, float dt);\n\nvoid LoadTbspFromBrx(CBinaryInputStream *pbis, int *pctsurf, TSURF **patsurf, int *pctbsp, TBSP **patbsp);\n\nint FCheckTbspPoint(TBSP *atbsp, VECTOR *pposLocal);\n\n#endif TN_H\n"
  },
  {
    "path": "include/transition.h",
    "content": "/**\n * @file transition.h\n *\n * @brief Level transitions.\n */\n#ifndef TRANSITION_H\n#define TRANSITION_H\n\n#include \"common.h\"\n#include <oid.h>\n#include <cat.h>\n#include <game.h>\n\nclass CTransition;\nextern CTransition g_transition;\n\n/**\n * @brief Level Table Struct\n *\n * Holds data about the level file.\n *\n * @note Name is not official.\n*/\nstruct LevelTableStruct\n{\n    CFileLocation fileLocation; /* Ciphers for lsn and size */\n    uint search_val;\n    uint for_lsn;\n    uint search_cipher; /* Cipher for search val */\n    uint for_size;\n    uint level_id; /* Level ID */\n    uint level_name;  /* Pointer to level name string */\n    FLS tasks;         /* Tasks to complete (visited, key, vault, mts) */\n};\n\n/**\n * @brief Transition flags.\n */\nenum FTRANS\n{\n    FTRANS_None = 0,\n    FTRANS_Checkpoint = 1,\n    FTRANS_RetryWorld = 2,\n    FTRANS_ClearGame = 4,\n    FTRANS_SameWorld = 8,\n    FTRANS_ShowLives = 16\n};\n\n/**\n * @brief Transition flags integer type.\n */\ntypedef int GRFTRANS;\n\n/**\n * @brief Transition data\n *\n * Responsible for holding data bout a level transition.\n */\nstruct TRANS\n{\n    uint fSet;\n    LevelTableStruct *pchzWorld; // Current file thats loading struct\n    OID oidWarp;                        // Checkpoint Warps\n    OID oidWarpContet;\n    GRFTRANS grftrans; // Lost all lives flags\n};\n\n/**\n * @brief Transition\n */\nclass CTransition\n{\npublic:\n    int m_fPending;    // Basically like a level pending flag.\n    char *m_pchzWorld; // This is the ptr to enc level sector offset and size in memory\n    OID m_oidWarp;     // Which checkpoint you spawn at when you start a level\n    OID m_oidWarpContext;\n\n    GRFTRANS grftrans;       // Flags that affect level loading, one of them checks if you lost all lives when you die.\n    char m_achzWorldCur[64]; // File description contents.\n\n    /**\n     * @brief Constructor.\n     */\n    CTransition();\n\n    /**\n     * @brief Sets the conditions on the level if you died or loading a level.\n     */\n    void Set(char *pchzWorld, OID oidWarp, OID oidWarpContext, GRFTRANS grftrans);\n\n    /**\n     * @brief  Executes the conditions from CTransition::Set by setting some engine vaules to default and loading the level file.\n     */\n    void Execute();\n};\n\n/**\n * @brief Reloads the current level. The value of FTRANS affects the load.\n *\n * @param ftrans Transition flags.\n */\nvoid ResetWorld(FTRANS ftrans);\n\n#endif // TRANSITION_H\n"
  },
  {
    "path": "include/turret.h",
    "content": "/**\n * @file turret.h\n *\n * @brief Stationary turret from Murray levels(?).\n */\n#ifndef TURRET_H\n#define TURRET_H\n\n#include \"common.h\"\n#include <dialog.h>\n#include <alo.h>\n#include <joy.h>\n#include <so.h>\n#include <po.h>\n#include <mq.h>\n\n/**\n * @class TURRET\n * @brief Stationary turret (maybe the one used in the murray levels).\n */\nstruct TURRET : public PO\n{\n    // ...\n};\n\nvoid InitTurret(TURRET *pturret);\n\nvoid PostTurretLoad(TURRET *pturret);\n\nvoid UpdateTurret(TURRET *pturret, float dt);\n\nvoid UpdateTurretActive(TURRET *pturret, JOY *pjoy, float dt);\n\nvoid OnTurretActive(TURRET *pturret, int fActive, PO *ppoOther);\n\nint FFilterTurret(TURRET *pturret, SO *psoOther);\n\nvoid UpdateTurretAim(TURRET *pturret);\n\nvoid FireTurret(TURRET *pturret);\n\nvoid HandleTurretMessage(TURRET *pturret, MSGID msgid, void *pv);\n\nint FIgnoreTurretIntersection(TURRET *pturret, SO *psoOther);\n\nvoid CollectTurretPrize(TURRET *pturret, PCK pck, ALO *paloOther);\n\nvoid GetTurretDiapi(TURRET *pturret, DIALOG *pdialog, DIAPI *pdiapi);\n\n#endif // TURRET_H\n"
  },
  {
    "path": "include/tv.h",
    "content": "/**\n * @file tv.h\n */\n#ifndef TV_H\n#define TV_H\n\n#include \"common.h\"\n#include <speaker.h>\n#include <screen.h>\n#include <gifs.h>\n#include <alo.h>\n\n// Forward.\nstruct RPL;\n\n/**\n * @brief TV State.\n */\nenum TVS\n{\n    TVS_Nil = -1,\n    TVS_Listen = 0,\n    TVS_Talk = 1,\n    TVS_Max = 2\n};\n\n/**\n * @brief TV (?) State.\n */\nenum TVGS\n{\n    TVGS_Nil = -1,\n    TVGS_Opening = 0,\n    TVGS_Open = 1,\n    TVGS_Closing = 2,\n    TVGS_Closed = 3,\n    TVGS_Max = 4\n};\n\n/**\n * @brief Unknown.\n * @todo Implement the struct.\n */\nstruct TV : public BLOT\n{\n    // ...\n};\n\nvoid InitTv(TV *ptv, BLOTK blotk);\n\nvoid PostTvLoad(TV *ptv);\n\nvoid GetTvItvbMinMax(TV *ptv, int *pitvbDrawMin, int *pitvbDrawMax);\n\nvoid DrawTvArea(TV *ptv, GIFS *gifs, int z);\n\nvoid DrawTvBands(TV *ptv, GIFS *gifs);\n\nvoid DrawTvOutline(TV *ptv, GIFS *gifs);\n\nvoid DrawTv(TV *ptv);\n\nvoid SetTvTvs(TV *ptv, TVS tvs);\n\nvoid AcceptTvSpeaker(TV *ptv);\n\nvoid SetTvTvgs(TV *ptv, TVGS tvgs);\n\nvoid SetTvBlots(TV *ptv, BLOTS blots);\n\nvoid UpdateTv(TV *ptv);\n\nvoid RenderTv(TV *ptv);\n\nvoid PreTvContext(RPL *prpl);\n\nvoid PostTvContext(RPL *prpl);\n\nvoid SetTvSpeaker(TV *ptv, SPEAKER *pspeaker);\n\nvoid SetTvReplace(TV *ptv, ALO *paloReplace);\n\nvoid OnTvReset(TV *ptv);\n\n#endif // TV_H\n"
  },
  {
    "path": "include/types.h",
    "content": "/**\n * @file types.h\n *\n * @brief Common types used across the codebase.\n*/\n#ifndef TYPES_H\n#define TYPES_H\n\n#include <stddef.h>\n\n// Exact-width integers (don't use these in most cases)\ntypedef signed char      int8_t;\ntypedef short            int16_t;\ntypedef int              int32_t;\ntypedef long long        int64_t;\n\ntypedef unsigned char    uint8_t;\ntypedef unsigned short   uint16_t;\ntypedef unsigned int     uint32_t;\ntypedef unsigned long long uint64_t;\n\n// Unsigned aliases\ntypedef uint8_t     uchar;\ntypedef uint16_t    ushort;\ntypedef uint32_t    uint;\ntypedef uint64_t    ulong;\n\n// Helper types for unknown struct fields\ntypedef uchar   undefined1;\ntypedef ushort  undefined2;\ntypedef uint    undefined4;\ntypedef ulong   undefined8;\n\n// 128-bit quad-word type for lq/sq instructions\ntypedef unsigned long long qword __attribute__((mode(TI)));\n\n// Misc\ntypedef uchar byte;\ntypedef union QW;\n\n#endif // TYPES_H\n"
  },
  {
    "path": "include/ub.h",
    "content": "/**\n * @file ub.h\n *\n * @brief Underwater boss.\n */\n#ifndef UB_H\n#define UB_H\n\n#include \"common.h\"\n#include <gomer.h>\n#include <vec.h>\n#include <so.h>\n\n// Forward.\nstruct ASEG;\n\n/**\n * @class UW_BOSS_GOMER\n * @brief Underwater boss gomer (Raleigh).\n */\nstruct UBG : public GOMER\n{\n    // ...\n    /* 0xc58 */ OID oidPatrolGoal;\n    /* 0xc5c */ int cJump;\n    /* 0xc60 */ STRUCT_PADDING(1);\n    /* 0xc64 */ SO *apsoPads[6];\n    // ...\n};\n\nvoid InitUbg(UBG *pubg);\n\nvoid PostUbgLoad(UBG *pubg);\n\nSO *PsoPadUbgClosest(UBG *pubg, VECTOR *ppos);\n\nvoid OnUbgEnteringSgs(UBG *pubg, SGS sgsPrev, ASEG *pasegOverride);\n\nSGS SgsNextUbgAI(UBG *pubg);\n\nint FDetectUbg(UBG *pubg);\n\nint FCanUbgAttack(UBG *pubg);\n\nvoid DoUbgFreefallJump(UBG *pubg);\n\nvoid DoUbgFreefallLanding(UBG *pubg);\n\nvoid UpdateUbgGoal(UBG *pubg, int fEnter);\n\nvoid UpdateUbgSgs(UBG *pubg);\n\nint FIgnoreUbgIntersection(UBG *pubg, SO *psoOther);\n\n#endif // UB_H\n"
  },
  {
    "path": "include/ui.h",
    "content": "/**\n * @file ui.h\n *\n * @brief User interface.\n */\n#ifndef UI_H\n#define UI_H\n\n#include \"common.h\"\n#include <joy.h>\n\n/**\n * @brief User interface state.\n */\nenum UIS\n{\n    UIS_Nil = -1,\n    UIS_Splash = 0,\n    UIS_Attract = 1,\n    UIS_Playing = 2,\n    UIS_Pausing = 3,\n    UIS_Paused = 4,\n    UIS_Unpausing = 5,\n    UIS_WorldMap = 6,\n    // todo: What is 7?\n    UIS_Wiping = 8,\n    UIS_Max = 9\n};\n\n/**\n * @brief User interface.\n *\n * @note Roughly based on May proto, may be inaccurate.\n */\nstruct UI\n{\n    UIS uis;\n    int tUis;\n    BLOT *apblotActive;\n    int cpblotActive;\n    UIS uisPlaying;\n    float rvolMusicPrepause;\n    float rvolEffectsPrepause;\n    int unk1;\n    int unk2;\n    int unk3;\n    int unk4;\n    int unk5;\n    int unk6;\n};\n\nvoid StartupUi();\n\nvoid InitUi(UI *pui);\n\nvoid PostUiLoad(UI *pui);\n\nvoid UpdateUi(UI *pui);\n\nvoid PushUiActiveBlot(UI *pui, BLOT *pblot);\n\nvoid PopUiActiveBlot(UI *pui);\n\n/**\n * @brief Calls DrawBlots to draw the UI.\n */\nvoid DrawUi();\n\n/**\n * @brief Calls RenderBlots to render the UI.\n */\nvoid RenderUi();\n\n/**\n * @brief Resets the UI to its initial state.\n *\n * @param pui Pointer to UI struct\n */\nvoid ResetUi(UI *pui);\n\n/**\n * @brief Sets the UI state.\n *\n * @param pui Pointer to UI struct\n * @param uis UI state\n */\nvoid SetUiUis(UI *pui, UIS uis);\n\n/**\n * @brief Sets the UI pause state.\n *\n * @param pui Pointer to UI struct\n * @param rPause Pause state\n */\nvoid SetUiUPause(UI *pui, float rPause);\n\n// ...more functions...\n\nextern UI g_ui; // Global UI object\n\n#endif // UI_H\n"
  },
  {
    "path": "include/update.h",
    "content": "/**\n * @file update.h\n */\n#ifndef UPDATE_H\n#define UPDATE_H\n\n#include \"common.h\"\n#include <sw.h>\n\n/**\n * @brief Updates all objects in the given SW.\n *\n * @param psw The SW to update.\n * @param dt Delta time.\n */\nvoid UpdateSwObjects(SW *psw, float dt);\n\nvoid UpdateSwPosWorldPrev(SW *psw);\n\nvoid UpdateSwRealClock(SW *psw, float dt);\n\nvoid UpdateSwDarkening(SW *psw, float dt);\n\n/**\n * @brief Updates the given SW.\n *\n * @param psw The SW to update.\n * @param dt Delta time.\n */\nvoid UpdateSw(SW *psw, float dt);\n\n#endif // UPDATE_H\n"
  },
  {
    "path": "include/util.h",
    "content": "/**\n * @file util.h\n *\n * @brief Utility functions.\n */\n#ifndef UTIL_H\n#define UTIL_H\n\n#include \"common.h\"\n#include <vec.h>\n#include <mat.h>\n#include <sm.h>\n\n/**\n * @brief Constant Linear Quadratic.\n *\n * @note Quadratic curve representation\n */\nstruct CLQ\n{\n    union\n    {\n        struct\n        {\n            float g0, g1, g2, gUnused;\n        };\n        float ag[4];\n    };\n};\n\n/**\n * @brief Evaluates a quadratic curve at parameter x.\n *\n * @details Computes the quadratic equation: g0 + x*g1 + x²*g2\n *          Uses Horner's method for efficient evaluation: g0 + x*(g1 + x*g2)\n *          This reduces multiplications from 3 to 2 compared to the expanded form.\n *\n * @param pclq Pointer to the quadratic curve\n * @param x Parameter value\n * @return Evaluated curve value at x\n */\nstatic inline float GEvaluateClq(CLQ *pclq, float x)\n{\n    return pclq->g0 + x * (pclq->g1 + x * pclq->g2);\n}\n\n/**\n * @brief Linear interpolation between two values.\n *\n * @details Returns (1-t)*a + t*b, smoothly blending from a (at t=0) to b (at t=1).\n *\n * @param a Starting value\n * @param b Ending value\n * @param t Interpolation parameter (typically 0.0-1.0)\n * @return Interpolated value between a and b\n */\nstatic inline float GLerp(float a, float b, float t)\n{\n    return (1.0f - t) * a + t * b;\n}\n\n/**\n * @brief Limits for a float.\n */\nstruct LM\n{\n\tfloat gMin, gMax;\n};\n\nextern LM g_lmZeroOne;\n\n/**\n * @brief Normalizes a float to the range [-PI, PI].\n *\n * @param rad The float to normalize\n *\n * @retval The normalized float\n */\nfloat RadNormalize(float rad);\n\n/**\n * @brief Clamps the float to the inteval [-absLimit, absLimit]\n *\n * @param g The float to clamp\n * @param absLimit The limit to clamp to\n *\n * @retval The clamped float\n */\nfloat GLimitAbs(float g, float absLimit);\n\nfloat GSmooth(float gCur, float gTarget, float dt, SMP *psmp, float *pdgNext);\n\nfloat GSmoothA(float gCur, float dgCur, float gTarget, float dt, SMPA *psmpa, float *pdgNext);\n\nfloat RadSmooth(float radCur, float radTarget, float dt, SMP *psmp, float *pdradNext);\n\nfloat RadSmoothA(float radCur, float dradCur, float radTarget, float dt, SMPA *psmpa, float *pdradNext);\n\nVU_VECTOR PosSmooth(VU_VECTOR posCur, VU_VECTOR posTarget, float dt, SMP *psmp, VECTOR *pv);\n\nvoid SmoothMatrix(MATRIX3 *pmatPrev, MATRIX3 *pmatNext, SMP *psmp, float dt, MATRIX3 *pmatSmooth, VECTOR *pwSmooth);\n\n/**\n * @brief Gets a random int that falls between the given values.\n *\n * @param nLow The lower bound\n * @param nHigh The upper bound\n *\n * @retval A random int that falls between the given values\n */\nint NRandInRange(int nLow, int nHigh);\n\n/**\n * @brief Gets a random float that falls between the given values.\n *\n * @param gLow The lower bound\n * @param gHigh The upper bound\n *\n * @retval A random float that falls between the given values\n */\nfloat GRandInRange(float gLow, float gHigh);\n\n/**\n * @brief Returns a random number from the Gaussian distribution.\n *\n * @param gMean The mean of the distribution\n * @param gDeviation The standard deviation of the distribution\n * @param gLimit The limit of the distribution\n *\n * @retval A random number from the Gaussian distribution\n */\nfloat GRandGaussian(float gMean, float gDeviation, float gLimit);\n\n/**\n * @brief Checks if two floats are within a given epsilon of each other.\n *\n * @param g1 The first float\n * @param g2 The second float\n * @param gEpsilon The epsilon\n *\n * @retval true if the floats are within the epsilon of each other\n * @retval false otherwise\n */\nint FFloatsNear(float g1, float g2, float gEpsilon);\n\n/**\n * @brief Solves a quadratic equation.\n *\n * A quadratic equation is of the form ax^2 + bx + c = 0. The solutions (if any)\n * are stored in ax[0] and ax[1].\n *\n * @param a The coefficient of the x^2 term\n * @param b The coefficient of the x term\n * @param c The constant term\n * @param ax The array to store the solutions in\n *\n * @return The number of solutions found (0, 1, or 2)\n */\nint CSolveQuadratic(float a, float b, float c, float *ax);\n\n/**\n * @todo Add documentation for this function.\n */\nvoid PrescaleClq(CLQ *pclqSrc, float ru, float du, CLQ *pclqDst);\n\n/**\n * @brief Calculates the sine and cosine of a given angle.\n *\n * @param rad The angle\n * @param pgSin The pointer to store the sine in\n * @param pgCos The pointer to store the cosine in\n */\nvoid CalculateSinCos(float rad, float *pgSin, float *pgCos);\n\n/**\n * @brief Truncates a double precision floating point number to an integer value,\n * rounding up if the fractional part is exactly 0.5.\n *\n * @param g The double precision floating point number to truncate\n */\ndouble GTrunc(double g);\n\n/**\n * @brief Truncates a single precision floating point number to an integer value,\n * rounding up if the fractional part is exactly 0.5.\n *\n * @param g The single precision floating point number to truncate\n */\nfloat GTrunc(float g);\n\n/**\n * @brief Calculates the positive remainder of dividing the dividend by the divisor.\n *\n * If the result is negative, it is adjusted to be positive by adding the divisor.\n *\n * @param gDividend The dividend.\n * @param gDivisor The divisor.\n *\n * @return The positive remainder of the division.\n */\nfloat GModPositive(float gDividend, float gDivisor);\n\nvoid FitClq(float g0, float g1, float u, float gU, CLQ *pclq);\n\n/**\n * @brief Checks if a float falls within the given limit.\n *\n * @param plm Pointer to the limit\n * @param g The float to check\n */\nint FCheckLm(LM *plm, float g);\n\n/**\n * @brief Limits a float to the given range.\n *\n * @param plm Pointer to the limit\n * @param g The float to limit\n */\nfloat GLimitLm(LM *plm, float g);\n\n/**\n * @brief Stubbed function, does nothing.\n */\nvoid Force(void *pv);\n\n// todo: see if these exist and/or in the right oder\n//int CSolveClq(CLQ* pclq, float g, float* ag);\n//float DtSmooth(float gCur, float gTarget, SMP* psmp, float* pdg);\n//void ExtendRange(PFNGG pfn, void* pv, float g, float dg, float gMax, float* pgMic, float* pgMac);\n//int NRoundG(float g);\n//void SmoothMulti(int c, float dt, float r);\n\n#endif // UTIL_H\n"
  },
  {
    "path": "include/vb.h",
    "content": "/**\n * @file vb.h\n *\n * @brief Voodoo boss.\n */\n#ifndef VB_H\n#define VB_H\n\n#include <stepguard.h>\n\n/**\n * @class V_BOSS_GUARD\n * @brief Voodoo boss guard (Mz Ruby).\n */\nstruct VBG : public STEPGUARD\n{\n    // ...\n};\n\n#endif // VB_H\n"
  },
  {
    "path": "include/vec.h",
    "content": "/**\n * @file vec.h\n *\n * @brief Vector math.\n */\n#ifndef VEC_H\n#define VEC_H\n\n#include \"common.h\"\n\nstruct SO;\n\n/**\n * @brief Vector3 with X, Y, and Z\n * @todo This probably needs to be 16-byte aligned?\n */\nstruct VECTOR\n{\n    float x, y, z;\n};\n\nstruct VECTOR4\n{\n    float x, y, z, w;\n};\n\n/**\n * @todo Should be 16-byte aligned.\n */\nstruct VU_VECTOR\n{\n    ushort data;\n};\n\n/**\n * @brief Sets the coordinates of a vector using cylindrical coordinates.\n *\n * @param pvec Pointer to the vector\n * @param rad Degrees in radians\n * @param sXY XY-Scale/Radius\n * @param sZ Z Offset\n */\nvoid SetVectorCylind(VECTOR *pvec, float rad, float sXY, float sZ);\n\n/**\n * @brief Sets the coordinates of a vector using spherical coordinates.\n *\n * @param pvec Pointer to the vector\n * @param radPan Angle around Z axis\n * @param radTilt Angle above horizontal\n * @param s Scale/Radius\n */\nvoid SetVectorSphere(VECTOR *pvec, float radPan, float radTilt, float s);\n\n/**\n * @brief Projects one vector onto another using scalar projection.\n *\n * @param pvec1 Vector to project\n * @param pvec2 Vector to project onto\n *\n * @return Scalar projection of vec1 onto vec2\n */\nfloat SProjectVector(VECTOR *pvec1, VECTOR *pvec2);\n\n/**\n * @brief Gets the normal vectors of a vector.\n *\n * @param param_1 Unknown\n * @param param_2 Unknown\n * @param param_3 Unknown\n * @param param_4 Unknown\n *\n * @todo Static analysis\n */\nvoid GetNormalVectors(VECTOR *param_1, VECTOR *param_2, VECTOR *param_3, VECTOR *param_4);\n\n/**\n * @brief Gets the normal vector of a vector.\n *\n * @param pvec Pointer to the vector\n * @param presult Pointer to store the resulting normal vector\n */\nvoid GetNormalVector(VECTOR *pvec, VECTOR *presult);\n\n/**\n * @brief Calculates the angle between vectors in radians.\n *\n * @param pvecStart Unknown\n * @param pvecFinish Unknown\n * @param pnormal Unknown\n *\n * @return Angle between vectors in radians.\n */\nlong RadBetweenVectors(VECTOR *pvecStart, VECTOR *pvecFinish, VECTOR *pnormal);\n\n/**\n * @brief Finds the closest point between the lines AB and CD.\n *\n * @param pA Pointer to the first point of line AB\n * @param pB Pointer to the second point of line AB\n * @param pC Pointer to the first point of line CD\n * @param pD Pointer to the second point of line CD\n * @param unk_float1 Unknown float\n * @param unk_float2 Unknown float\n * @param presult Pointer to store the resulting point\n */\nvoid FindClosestPointBetweenLines(VECTOR *pA, VECTOR *pB, VECTOR *pC, VECTOR **pD, float *unk_float1, float *unk_float2, VECTOR *presult);\n\n/**\n * @brief Finds the closest point between two line segments.\n *\n * @todo Static analysis of parameters and return values.\n */\nvoid FindClosestPointBetweenLineSegments(VECTOR *param_1, VECTOR *param_2, VECTOR *param_3, VECTOR *param_4, VECTOR param_5, float *param_6, VECTOR *param_7);\n\n/**\n * @brief Calculates the pan and tilt of a vector\n *\n * @param pvec Pointer to the vector\n * @param pradPan Float pointer to store the pan result\n * @param pradTilt Float pointer to store the tilt result\n */\nvoid CalculateVectorPanTilt(VECTOR *pvec, float *pradPan, float *pradTilt);\n\n/**\n * @brief Creates a vector from a rotation vector and an offset vector\n *\n * @details Use the peul vector to define euler angles for a vector,\n * Using the forward vector as a reference direction,\n * pdeul's X is a Rightward offset\n * pdeul's Y is a Forward offset\n * pdeul's Z is a Vertical offset\n *\n * @param peul Rotation vector, defines a \"forward\"\n * @param pdeul Offset vector\n * @param pw Resultant Vector\n */\nvoid ConvertDeulToW(VECTOR *peul, VECTOR *pdeul, VECTOR *pw);\n\n/**\n * @brief Calculates the muzzle velocity of a projectile.\n *\n * @param pposLaunch Initial position\n * @param pposTarget Target position\n * @param radVert Vertical angle?\n * @param pvecMuzzle Target velocity\n * @param psoLaunch Unknown\n *\n * @note This is an educated guess and may not be accurate.\n */\nint FCalculateMuzzleVelocity(VECTOR *pposLaunch,VECTOR *pposTarget,float radVert,VECTOR *pvecMuzzle,SO *psoLaunch);\n\n/**\n * @brief Calculates the muzzle velocity angle of a projectile.\n *\n * @param param_1 Initial position\n * @param param_2 Target position\n * @param param_3 Target velocity\n * @param param_4 Unknown\n *\n * @note The name/paremeters for this function are an educated guess and may not be accurate.\n */\nint FCalculateMuzzleVelocityAngle(VECTOR *pposLaunch, VECTOR *pposTarget, float radTilt, VECTOR *pvecMuzzle, SO *psoLaunch);\n\n/**\n * @brief Limits the length of a vector.\n *\n * @param pvec Pointer to the vector\n * @param glength Length to limit the vector to\n * @param presult Pointer to store the resulting vector\n */\nvoid LimitVectorLength(VECTOR *pvec, float glength, VECTOR *presult);\n\n#endif // VEC_H\n"
  },
  {
    "path": "include/vifs.h",
    "content": "/**\n * @file vifs.h\n */\n#ifndef VIFS_H\n#define VIFS_H\n\n#include \"common.h\"\n#include <dmas.h>\n#include <gifs.h>\n\n/**\n * @brief Unpack kind?\n */\nenum UPK\n{\n    UPK_Nil = -1,\n    UPK_S32 = 0,\n    UPK_S16 = 1,\n    UPK_S8 = 2,\n    UPK_V2_32 = 4,\n    UPK_V2_16 = 5,\n    UPK_V2_8 = 6,\n    UPK_V3_32 = 8,\n    UPK_V3_16 = 9,\n    UPK_V3_8 = 10,\n    UPK_V4_32 = 12,\n    UPK_V4_16 = 13,\n    UPK_V4_8 = 14,\n    UPK_V4_5 = 15,\n    UPK_Max = 16\n};\n\n/**\n * @brief Vector Interface System?\n */\nclass VIFS : public DMAS\n{\npublic:\n    /* 0x1c */ uint m_unMask;\n    /* 0x20 */ int m_fCheckCnt;\n\n    VIFS();\n\n    void Align(int iun);\n    void AddVifBaseOffset(int iqwBase, int diqwOffset);\n    void AddVifMscal(void *pv);\n    void AddVifMscalf(void *pv);\n    void AddVifFlush();\n    void AddVifFlusha();\n    void AddVifFlushe();\n    void AddVifStcycl(int wl, int cl);\n    void AddVifStrow(QW *pqw);\n    void AddVifStmask(uint unMask);\n    int CbUnpackSetup(UPK upk, int c, int iqw);\n    void UnpackHelper(UPK upk, int c, int iqw, int *pcb, uint **ppun);\n    void AddVifUnpack(UPK upk, int c, void *pvSrc, int iqw);\n    void AddVifUnpackRefs(UPK upk, int c, void *pvSrc, int iqw, void ***pppv);\n    void AddVifDirect(int cqw, QW *aqw, int fInt);\n    void AddVifDirectRefs(int cqw, QW *aqw, int fInt);\n    void AddVifGifs(GIFS *pgifs);\n};\n\n#endif // VIFS_H\n"
  },
  {
    "path": "include/vis.h",
    "content": "/**\n * @file vis.h\n *\n * @brief Visibility map.\n */\n#ifndef VIS_H\n#define VIS_H\n\n#include \"common.h\"\n#include <bsp.h>\n#include <bis.h>\n#include <vec.h>\n#include <lo.h>\n\ntypedef int GRFZON;\n\n/**\n * @class VISMAP\n * @brief Visibility map.\n */\nstruct VISMAP : public LO\n{\n    /* 0x30 */ int cvbsp;\n    /* 0x34 */ VBSP *avbsp;\n    /* 0x3c */ int cgrfzon;\n    /* 0x40 */ GRFZON *agrfzonOneHop;\n};\n\nvoid InitVismap(VISMAP *pvismap);\n\nvoid LoadVismapFromBrx(VISMAP *pvismap, CBinaryInputStream *pbis);\n\nGRFZON GrfzonOneHop(VISMAP *pvismap, VBSP *pvbsp);\n\nvoid ClipVbspSphereOneHop(VISMAP *pvismap, VBSP *pvbsp, VU_VECTOR pos, float sRadius, GRFZON *pgrfzon);\n\nvoid ClipVismapSphereOneHop(VISMAP *pvismap, VECTOR *ppos, float sRadius, GRFZON *pgrfzon);\n\nvoid ClipVismapPointNoHop(VISMAP *pvismap, VECTOR *ppos, GRFZON *pgrfzon);\n\n#endif // VIS_H\n"
  },
  {
    "path": "include/vol.h",
    "content": "/**\n * @file vol.h\n *\n * @brief Volume object.\n *\n * @note Not referenced in any debug symbols, but it doesn't make sense\n * to put the VOL struct anywhere else.\n */\n#ifndef VOL_H\n#define VOL_H\n\n#include \"common.h\"\n#include <xform.h>\n\n/**\n * @class VOLUME\n * @brief Volume in space defined by transform, tsurf, and tbsp.\n */\nstruct VOL : public XFM\n{\n    int ctsurf;\n    TSURF *atsurf;\n    int ctbsp;\n    TBSP *atbsp;\n};\n\n#endif // VOL_H\n"
  },
  {
    "path": "include/vtables.h",
    "content": "/**\n * @file vtables.h\n *\n * @brief Manually crafted vtables for various structs.\n */\n#ifndef VTABLES_H\n#define VTABLES_H\n\n#include <cid.h>\n#include <mq.h>\n\ntypedef int GRFCID;\n\n/**\n * @brief Generic VT struct. Used to determine which VTables an entity inherits at runtime.\n */\nstruct VT\n{\n    VT *pvtSuper;\n    CID cid;\n    GRFCID grfcid;\n    int cb;\n};\n\n\n/*****************************************************************\n * BASIC-DERIVED VTABLES\n *****************************************************************/\n\nstruct CBinaryInputStream;\nstruct LO;\n\n/**\n * @brief VT for basic objects.\n */\nstruct VTBASIC\n{\n    VT *pvtSuper;\n    CID cid;\n};\n\n/**\n * @brief VT for LO objects.\n */\nstruct VTLO : VT\n{\n    void (*pfnInitLo)(LO *);\n    void (*pfnSetLoDefaults)(LO *);\n    void (*pfnAddLo)(LO *);\n    void (*pfnRemoveLo)(LO *);\n    void (*pfnAddLoHierarchy)(LO *);\n    void (*pfnRemoveLoHierarchy)(LO *);\n    void (*pfnOnLoAdd)(LO *);\n    void (*pfnOnLoRemove)(LO *);\n    void (*pfnCloneLoHierarchy)(LO *, LO *);\n    void (*pfnCloneLo)(LO *, LO *);\n    void (*pfnLoadLoFromBrx)(LO *, CBinaryInputStream *);\n    void (*pfnAddLoRecursive)(/* @todo: null in release & proto? */);\n    void (*pfnRemoveLoRecursive)(/* @todo: null in release & proto? */);\n    void (*pfnHandleLoMessage)(LO *, MSGID, void *);\n    void (*pfnSendLoMessage)(LO *, MSGID, void *);\n    void (*pfnBindLo)(LO *);\n    void (*pfnPostLoLoad)(LO *);\n\n    /**\n     * @todo From prototype, not confirmed if in release\n     */\n    void (*pfnUpdateLo)();\n    void (*pfnUpdateLoXfWorld)();\n    void (*pfnUpdateLoXfWorldHierarchy)();\n    void (*pfnFreezeLo)();\n    void (*pfnSetLoParent)();\n    void (*pfnApplyLoProxy)();\n    void (*pfnSubscribeLoObject)();\n    void (*pfnUnsubscribeLoObject)();\n    void (*pfnSubscribeLoStruct)();\n    void (*pfnUnsubscribeLoStruct)();\n    void (*pfnGetLoParams)();\n    void (*pfnUpdateLoLiveEdit)();\n};\n\n/*****************************************************************\n * BLOT-DERIVED VTABLES\n *****************************************************************/\n\nstruct BLOT;\n\n/**\n * @brief VT for generic blots.\n */\nstruct VTBLOT\n{\n    void (*pfnInitBlot)(BLOT *);\n    void (*pfnPostBlotLoad)(BLOT *);\n    void (*pfnUpdateBlot)(BLOT *);\n    void (*pfnOnBlotActive)(BLOT *);\n    void (*pfnUpdateBlotActive)(BLOT *);\n    void (*pfnOnBlotReset)(BLOT *);\n    void (*pfnOnBlotPush)(BLOT *);\n    void (*pfnOnBlotPop)(BLOT *);\n    void (*pfnSetBlotAchzDraw)(BLOT *, const char *);\n    void (*pfnDrawBlot)(BLOT *);\n    void (*pfnRenderBlot)(BLOT *);\n    void (*pfnDtAppearBlot)(BLOT *);\n    void (*pfnDtVisibleBlot)(BLOT *);\n    void (*pfnDtDisappearBlot)(BLOT *);\n    void (*pfnShowBlot)(BLOT *);\n    void (*pfnHideBlot)(BLOT *);\n    void (*pfnSetBlotBlots)(BLOT *);\n    void (*pfnSetBlotClock)(BLOT *);\n    int  (*pfnFIncludeBlotForPeg)(BLOT *);\n};\n\n/**\n * @brief VT for the note blot.\n */\nstruct VTNOTE\n{\n    void (*pfnInitBlot)(BLOT *);\n    void (*pfnPostNoteLoad)(BLOT *);\n    void (*pfnUpdateBlot)(BLOT *);\n    void (*pfnOnBlotActive)(BLOT *);\n    void (*pfnUpdateBlotActive)(BLOT *);\n    void (*pfnOnBlotReset)(BLOT *);\n    void (*pfnOnBlotPush)(BLOT *);\n    void (*pfnOnBlotPop)(BLOT *);\n    void (*pfnSetNoteAchzDraw)(BLOT *, const char *);\n    void (*pfnDrawNote)(BLOT *);\n    void (*pfnRenderBlot)(BLOT *);\n    void (*pfnDtAppearBlot)(BLOT *);\n    void (*pfnDtVisibleBlot)(BLOT *);\n    void (*pfnDtDisappearBlot)(BLOT *);\n    void (*pfnShowBlot)(BLOT *);\n    void (*pfnHideBlot)(BLOT *);\n    void (*pfnSetBlotBlots)(BLOT *);\n    void (*pfnSetBlotClock)(BLOT *);\n    int  (*pfnFIncludeBlotForPeg)(BLOT *);\n};\n\n/**\n * @brief VT for the binoc blot.\n */\nstruct VTBINOC\n{\n    void (*pfnInitBinoc)(BLOT *);\n    void (*pfnPostBinocLoad)(BLOT *);\n    void (*pfnUpdateBlot)(BLOT *);\n    void (*pfnOnBinocActive)(BLOT *);\n    void (*pfnUpdateBinocActive)(BLOT *);\n    void (*pfnOnBinocReset)(BLOT *);\n    void (*pfnOnBinocPush)(BLOT *);\n    void (*pfnOnBinocPop)(BLOT *);\n    void (*pfnSetBinocAchzDraw)(BLOT *, const char *);\n    void (*pfnDrawBinoc)(BLOT *);\n    void (*pfnRenderBlot)(BLOT *);\n    void (*pfnDtAppearBinoc)(BLOT *);\n    void (*pfnDtVisibleBlot)(BLOT *);\n    void (*pfnDtDisappearBinoc)(BLOT *);\n    void (*pfnShowBlot)(BLOT *);\n    void (*pfnHideBlot)(BLOT *);\n    void (*pfnSetBinocBlots)(BLOT *);\n    void (*pfnSetBlotClock)(BLOT *);\n    int  (*pfnFIncludeBlotForPeg)(BLOT *);\n};\n\n/**\n * @brief VT for the timer blot.\n */\nstruct VTTIMER\n{\n    void (*pfnInitBlot)(BLOT *);\n    void (*pfnPostTimerLoad)(BLOT *);\n    void (*pfnUpdateTimer)(BLOT *);\n    void (*pfnOnBlotActive)(BLOT *);\n    void (*pfnUpdateBlotActive)(BLOT *);\n    void (*pfnOnBlotReset)(BLOT *);\n    void (*pfnOnBlotPush)(BLOT *);\n    void (*pfnOnBlotPop)(BLOT *);\n    void (*pfnSetBlotAchzDraw)(BLOT *, const char *);\n    void (*pfnDrawTimer)(BLOT *);\n    void (*pfnRenderBlot)(BLOT *);\n    void (*pfnDtAppearBlot)(BLOT *);\n    void (*pfnDtVisibleBlot)(BLOT *);\n    void (*pfnDtDisappearBlot)(BLOT *);\n    void (*pfnShowBlot)(BLOT *);\n    void (*pfnHideBlot)(BLOT *);\n    void (*pfnSetBlotBlots)(BLOT *);\n    void (*pfnSetBlotClock)(BLOT *);\n    int  (*pfnFIncludeBlotForPeg)(BLOT *);\n};\n\n/**\n * @brief VT for the totals blot.\n */\nstruct VTTOTALS\n{\n    void (*pfnInitBlot)(BLOT *);\n    void (*pfnPostBlotLoad)(BLOT *);\n    void (*pfnUpdateBlot)(BLOT *);\n    void (*pfnOnBlotActive)(BLOT *);\n    void (*pfnUpdateBlotActive)(BLOT *);\n    void (*pfnOnBlotReset)(BLOT *);\n    void (*pfnOnBlotPush)(BLOT *);\n    void (*pfnOnBlotPop)(BLOT *);\n    void (*pfnSetBlotAchzDraw)(BLOT *, const char *);\n    void (*pfnDrawBlot)(BLOT *);\n    void (*pfnRenderBlot)(BLOT *);\n    void (*pfnDtAppearBlot)(BLOT *);\n    void (*pfnDtVisibleBlot)(BLOT *);\n    void (*pfnDtDisappearBlot)(BLOT *);\n    void (*pfnShowBlot)(BLOT *);\n    void (*pfnHideBlot)(BLOT *);\n    void (*pfnSetBlotBlots)(BLOT *);\n    void (*pfnSetBlotClock)(BLOT *);\n    int (*pfnFIncludeBlotForPeg)(BLOT *);\n};\n\nstruct GAME;\n\n/**\n * @brief VT for the game struct.\n */\nstruct VTGAME\n{\n    // ...\n};\n\nstruct GOMER;\n\n/**\n * @brief VT for the gomer struct.\n */\nstruct VTGOMER\n{\n    // ...\n};\n\n/**\n * @brief VT for a waypoint related struct.\n */\nstruct VTWPSG\n{\n    // ...\n};\n\n/**\n * @brief VT for a shader related struct.\n */\nstruct VTSAA\n{\n    // ...\n};\n\n/**\n * @brief VT for an act related struct.\n */\nstruct VTACT\n{\n    // ...\n};\n\n#endif // VTABLES_H\n"
  },
  {
    "path": "include/water.h",
    "content": "/**\n * @file water.h\n *\n * @brief Good ol' H20.\n */\n#ifndef WATER_H\n#define WATER_H\n\n#include \"common.h\"\n#include <zap.h>\n#include <vec.h>\n#include <so.h>\n#include <mq.h>\n\n// Forward.\nstruct XA;\nstruct XP;\n\n/**\n * @class WATER\n * @brief Water?\n */\nstruct WATER : public SO\n{\n    // ...\n};\n\nvoid InitWater(WATER *pwater);\n\nvoid PostWaterLoad(WATER *pwater);\n\nvoid CalculateWaterCurrent(WATER *pwater, VECTOR *ppos, VECTOR *pv, VECTOR *pw);\n\nvoid UpdateSwXaList(SW *psw, XA **ppxa);\n\nvoid UpdateWater(WATER *pwater, float dt);\n\nvoid AddWaterExternalAccelerations(WATER *pwater, XA *pxa, float dt);\n\nvoid HandleWaterMessage(WATER *pwater, MSGID msgid, void *pv);\n\nvoid UpdateWaterMergeGroup(WATER *pwater);\n\nfloat UGetWaterSubmerged(WATER *pwater, SO *pso, VECTOR *pposSurface, VECTOR *pnormalSurface);\n\nvoid UpdateWaterBounds(WATER *pwater);\n\nint FInflictWaterZap(WATER *pwater, XP *pxp, ZPR *pzpr);\n\nZPD *PzpdEnsureWater(WATER *pwater, ENSK ensk);\n\n#endif // WATER_H\n"
  },
  {
    "path": "include/waypoint.h",
    "content": "/**\n * @file waypoint.h\n */\n#ifndef WAYPOINT_H\n#define WAYPOINT_H\n\n#include \"common.h\"\n#include <alo.h>\n#include <oid.h>\n#include <mq.h>\n\n// Forward.\nstruct SGG;\n\n/**\n * @brief Waypoint state.\n */\nenum WPS\n{\n    WPS_Nil = -1,\n    WPS_Passive = 0,\n    WPS_Sync = 1,\n    WPS_Active = 2,\n    WPS_Max = 3\n};\n\n/**\n * @class WAY_POINT\n * @brief Waypoint.\n */\nstruct WAYPOINT : public ALO\n{\n    undefined1 unknown[2];\n    WPS wps;\n    float tWps;\n    float dtPause;\n    // ...\n};\n\n/**\n * @brief Stepguard waypoint?\n */\nstruct WPSG\n{\n    /* 0x00 */ VTWPSG *pvtwpsg;\n    /* 0x04 */ uint cpwaypoint;\n    /* 0x08 */ WAYPOINT *apwaypoint[8];\n    /* 0x28 */ int fCallback;\n    /* 0x2c */ SGG *psgg;\n};\n\nvoid InitWaypoint(WAYPOINT *pwaypoint);\n\nvoid PostWaypointLoad(WAYPOINT *pwaypoint);\n\nvoid SetWaypointRsmg(WAYPOINT *pwaypoint, int fOnTrigger, OID oidRoot, OID oidSm, OID oidGoal);\n\nvoid UpdateWaypoint(WAYPOINT *pwaypoint, float dt);\n\nvoid SetWaypointWps(WAYPOINT *pwaypoint, WPS wps);\n\nvoid HandleWaypointMessage(WAYPOINT *pwaypoint, MSGID msgid, void *pv);\n\nWPSG *PwpsgNew();\n\nvoid AddWpsgWaypoint(WPSG *pwpsg, WAYPOINT *pwaypoint);\n\nvoid RemoveWpsgWaypoint(WPSG *pwpsg, WAYPOINT *pwaypoint);\n\nvoid UpdateWpsgCallback(WPSG *pwpsg, MSGID msgid, void *pv);\n\nvoid EnsureWpsgCallback(WPSG *pwpsg);\n\n#endif // WAYPOINT_H\n"
  },
  {
    "path": "include/wipe.h",
    "content": "/**\n * @file wipe.h\n *\n * @brief Screen wipes.\n *\n * @todo Figure out if the function signatures are correct.\n */\n#ifndef WIPE_H\n#define WIPE_H\n\n#include \"common.h\"\n#include <transition.h>\n#include <oid.h>\n#include <joy.h>\n\n/**\n * @brief Wipe Kind.\n */\nenum WIPEK\n{\n    WIPEK_Fade = 0,\n    WIPEK_Keyhole = 1,\n    WIPEK_WorldMap = 2,\n    WIPEK_Frozen = 3,\n    WIPEK_Max = 4\n};\n\n/**\n * @brief Wipe State.\n */\nenum WIPES\n{\n    WIPES_Nil = -1,\n    WIPES_Idle = 0,\n    WIPES_WipingOut = 1,\n    WIPES_Black = 2,\n    WIPES_WipingIn = 3,\n    WIPES_Max = 4\n};\n\n/**\n * @brief Screen wipe.\n */\nstruct WIPE\n{\n    undefined4 unk_0x0;\n    WIPES wipes;\n    float tWipes;\n    float uBlack;\n    TRANS transButton;\n    WIPEK wipek;\n    WIPEK wipekButton;\n};\n\nextern WIPE *g_pwipe;\nextern WIPE g_wipe;\n\nvoid InitWipe(WIPE *pwipe);\n\nvoid UpdateWipe(WIPE *pwipe, JOY *pjoy);\n\nvoid DrawWipe(WIPE *pwipe);\n\nvoid ActivateWipe(WIPE *pwipe, TRANS *ptrans, WIPEK wipek);\n\nvoid SetWipeButtonTrans(WIPE *pwipe, TRANS *ptrans, WIPEK wipek);\n\nint FCatchWipeButtonTrans(WIPE *pwipe, JOY *pjoy, WIPES wipesNew);\n\nvoid SetWipeWipes(WIPE *pwipe, WIPES wipes);\n\nextern \"C\" void WipeToWorldWarp(const void *pchzWorld, OID oidWarp, WIPEK wipek);\n\n#endif // WIPE_H\n"
  },
  {
    "path": "include/wm.h",
    "content": "/**\n * @file wm.h\n *\n * @brief World map?\n */\n#ifndef WM_H\n#define WM_H\n\n#include \"common.h\"\n#include <flash.h>\n#include <game.h>\n#include <vec.h>\n#include <joy.h>\n#include <alo.h>\n#include <cm.h>\n#include <mq.h>\n\ntypedef int GRFDS;\n\n/**\n * @brief World map state.\n */\nenum WMS\n{\n    WMS_Nil = -1,\n    WMS_Hidden = 0,\n    WMS_Appearing = 1,\n    WMS_Manual = 2,\n    WMS_Warping = 3,\n    WMS_Disappearing = 4,\n    WMS_Max = 5\n};\n\n/**\n * @brief World map direction.\n */\nenum WMD\n{\n    WMD_Nil = -1,\n    WMD_Up = 0,\n    WMD_Down = 1,\n    WMD_Left = 2,\n    WMD_Right = 3,\n    WMD_Max = 4\n};\n\n/**\n * @brief World map something (?)\n * @todo Implement the struct.\n */\nstruct WMC\n{\n    // ...\n};\n\n/**\n * @class WORLD_MAP\n * @brief World map accessed from the hideout, by pressing Select, or Pause > View Map.\n * @todo Implement the struct.\n */\nstruct WM : public ALO\n{\n    // ...\n};\n\nvoid PostWmLoad(WM *pwm);\n\nvoid BindWm(WM *pwm);\n\nvoid RefreshWmMoveStats(WM *pwm, WORLDLEVEL worldlevel);\n\nvoid ThrowWmDisplayState(WM *pwm, WORLDLEVEL worldlevel, int fReverse);\n\nvoid CatchWmDisplayState(WM *pwm);\n\nvoid UpdateWm(WM *pwm, float dt);\n\nvoid RenderWmAll(WM *pwm, CM *pcm, RO *pro);\n\nvoid HandleWmMessage(WM *pwm, MSGID msgid, void *pv);\n\n/**\n * @brief Sets the WM state.\n *\n * @param pwm Pointer to the WM.\n * @param pwms Pointer to the WM state.\n*/\nvoid SetWmWms(WM* pwm, WMS wms);\n\nvoid ShowWm(WM *pwm, WORLDLEVEL worldlevel, WMS wmsActive);\n\nvoid HideWm(WM *pwm);\n\nvoid MoveWm(WM *pwm, WMD wmd);\n\nvoid GetWmWorldPosScreen(WM *pwm, WORLDLEVEL worldlevel, VECTOR *pposScreen);\n\nvoid SetWmCursor(WM *pwm, WORLDLEVEL worldlevel);\n\nvoid PostWmcLoad(WMC *pwmc);\n\nvoid UpdateWmcActive(WMC *pwmc, JOY *pjoy);\n\nvoid OnWmcActive(WMC *pwmc, int fActive);\n\nvoid DrawWmFan(float xCenter, float yCenter, float sRadius, float rad, int cseg, RGBA *rgbaCenter, RGBA rgbaEdge, GRFDS grfds);\n\nvoid DrawWmc(WMC *pwmc);\n\n#endif // WM_H\n"
  },
  {
    "path": "include/wr.h",
    "content": "/**\n * @file wr.h\n * @note At the time of writing all structs were\n * based on the may prototype so they can be inaccurate.\n */\n#ifndef WR_H\n#define WR_H\n\n#include \"common.h\"\n#include <difficulty.h>\n#include <glob.h>\n#include <oid.h>\n#include <mat.h>\n#include <alo.h>\n#include <lo.h>\n#include <mq.h>\n\n// Forward.\nstruct WR;\n\n/**\n * @brief (?) Kind.\n */\nenum WEK\n{\n    WEK_Nil = -1,\n    WEK_XYZ = 0,\n    WEK_XY = 1,\n    WEK_XZ = 2,\n    WEK_YZ = 3,\n    WEK_X = 4,\n    WEK_Y = 5,\n    WEK_Z = 6,\n    WEK_Max = 7\n};\n\n/**\n * @brief (?) Kind.\n */\nenum WREK\n{\n    WREK_Nil = -1,\n    WREK_Circle = 0,\n    WREK_Bend = 1,\n    WREK_Max = 2\n};\n\n/**\n * @brief Unknown.\n */\nstruct ONZE\n{\n    float uAmpl;\n    float gFreq;\n    float gPhase;\n    float uRandom;\n};\n\n/**\n * @brief Unknown.\n */\nstruct ONZ\n{\n    LM lm;\n    float uBias;\n    int conze;\n    ONZE aonze[4];\n};\n\n/**\n * @brief Unknown.\n */\nstruct WEKI\n{\n    WEK wek;\n    float sInner;\n    float uInner;\n    float sOuter;\n    float uOuter;\n    undefined1 unknown[12];\n    MATRIX4 dmat;\n};\n\n/**\n * @brief Unknown.\n */\nstruct WRE\n{\n    WREK wrek;\n    int imat;\n    STRUCT_PADDING(50);\n};\n\n/**\n * @brief Unknown.\n */\nstruct WRBG\n{\n    ALO *palo;\n    GLOB *pglob;\n    OID oid;\n    WR *pwr;\n    int cmat;\n    int fDpos;\n    int fDuv;\n    undefined1 unknown[4];\n    WEKI weki;\n    WRBG *pwrbgNextGlobset;\n    WRBG *pwrbgNextWr;\n};\n\n/**\n * @class SPACE_WARM\n * @brief Unknown.\n */\nstruct WR : public LO\n{\n    /* 0x34  */ float tLastUpdate;\n    /* 0x38  */ int cwre;\n    int cmat;\n    /* 0x40  */ int imatHalf;\n    /* 0x44  */ STRUCT_PADDING(3);\n    /* 0x50  */ WRE awre[8];\n    /* 0x6d0 */ int iwreCur;\n    /* 0x6d4 */ STRUCT_PADDING(3);\n    MATRIX4 amatDpos[4];\n    MATRIX4 amotDuv[4];\n    void *pwrbgFirst;\n    /* 0x8e4 */ int fValuesChanged;\n};\n\nvoid InitWr(WR *pwr);\n\nvoid HandleWrMessage(WR *pwr, MSGID msgid, void *pv);\n\nvoid ApplyWrGlob(WR *pwr, ALO *palo, GLOB *pglob);\n\nvoid UpdateWrStateVectors(WR *pwr);\n\nvoid WarpWrTransform(WR *pwr, float sWavelengthMin, VECTOR *pposSrc, MATRIX3 *pmatSrc, VECTOR *pposDst, MATRIX3 *pmatDst, VECTOR *pvDst);\n\nvoid GetWrBounds(WR *pwr, VECTOR * pdpos);\n\nfloat UNoise(int n);\n\nfloat UNoise(float gFreq, float gPhase, float uRandom);\n\nfloat UBias(float u, float uBias);\n\nfloat GFromOnz(ONZ *ponz);\n\nvoid UpdateWrMatrixes(WR *pwr);\n\nvoid AddWrCircleWarp(WR *pwr);\n\nvoid AddWrBendWarp(WR *pwr);\n\nWRE *PwreGetWrCur(WR *pwr, ENSK ensk, WREK wrek);\n\nWRE *PwreGetWrCircle(WR *pwr, ENSK ensk);\n\nWRE *PwreGetWrBend(WR *pwr, ENSK ensk);\n\nvoid SetWrWavelength(WR *pwr, float sWavelength);\n\nvoid GetWrWavelength(WR *pwr, float *psWavelength);\n\nvoid AddOnzOnze(ONZ *ponz, float uAmpl, float gFreq, float gPhase, float uRandom);\n\nvoid AddWrBendNoise(WR *pwr, float uAmpl, float gFreq, float gPhase, float uRandom);\n\nvoid AddWrSwivelNoise(WR *pwr, float uAmpl, float gFreq, float gPhase, float uRandom);\n\n#endif // WR_H\n"
  },
  {
    "path": "include/xform.h",
    "content": "/**\n * @file xform.h\n *\n * @brief Transform.\n */\n#ifndef XFORM_H\n#define XFORM_H\n\n#include \"common.h\"\n#include <vec.h>\n#include <mat.h>\n#include <alo.h>\n#include <util.h>\n#include <dl.h>\n#include <geom.h>\n#include <game.h>\n#include <oid.h>\n#include <wipe.h>\n#include <bis.h>\n#include <proxy.h>\n#include <rs.h>\n#include <pnt.h>\n\n// Forward declarations\nstruct XF;\nstruct XFM;\nstruct EXPL;\nstruct EXPLG;\nstruct EXPLO;\nstruct EXPLS;\nstruct EXPLSO;\nstruct EXPLSTE;\nstruct CAMERA;\nstruct ASEG;\n\n/**\n * @class TRANSFORM\n * @brief Transform defined by position vector + local matrix.\n */\nstruct XFM : public LO\n{\n    /* 0x34 */ STRUCT_PADDING(3);\n    /* 0x40 */ VECTOR posLocal;\n    uint padding; // TODO: Remove once VECTOR is 16 bytes long.\n    /* 0x50 */ MATRIX3 matLocal;\n};\n\n/**\n * @class _EXPLODE_BASE\n * @brief Base class for explodes.\n */\nstruct EXPL : public XFM\n{\n    // ...\n};\n\n/**\n * @class EXPLODE_GROUP\n * @brief Group of explode objects.\n */\nstruct EXPLG : public EXPL\n{\n    // ...\n};\n\n/**\n * @class BLACK_HOLD\n * @brief Unknown.\n */\nstruct EXPLO : public EXPL\n{\n    // ...\n};\n\n/**\n * @class EXPLODE_STYLE\n * @brief Unknown.\n */\nstruct EXPLS : public EXPLO\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct EXPLSO\n{\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct EXPLSTE\n{\n    // ...\n};\n\n/**\n * @class WARP\n * @brief Unknown.\n */\nstruct WARP : XFM\n{\n    WID widMenu;\n    undefined4 unk0_0x4;\n    undefined4 unk1_0x8;\n    undefined4 unk2_0xC;\n    VECTOR v;\n    int fDefault;\n    float radCmInit;\n    int cpaseg;\n    ASEG **apaseg;\n    int coidHide;\n    OID *aoidHide;\n    int coidShowWhenDifficult;\n    OID aoidShowWhenDifficult[4];\n    OID oidAlias;\n    int crsmg;\n    RSMG arsmg[4];\n    undefined4 unk3;\n    undefined4 unk4;\n    undefined4 unk5;\n};\n\n/**\n * @struct CAMERA\n * @brief Game camera instance.\n */\nstruct CAMERA : public ALO\n{\n    OID oidTarget;\n    PNT *ppntTarget;\n    ALO *paloTarget;\n    undefined4 unk_1;\n    VECTOR posEye;\n    VECTOR vecView;\n    VECTOR vecUp;\n    int fSetCplcy;\n    undefined4 unk_2;\n    undefined4 unk_3;\n    undefined4 unk_4;\n};\n\n/**\n * @brief Exit state.\n */\nenum EXITS\n{\n    EXITS_Nil = -1,\n    EXITS_Blocked = 0,\n    EXITS_Unblocked = 1,\n    EXITS_Disabled = 2,\n    EXITS_Enabled = 3,\n    EXITS_Totals = 4,\n    EXITS_Exiting = 5,\n    EXITS_Max = 6\n};\n\n/**\n * @brief Exit destination kind.\n */\nenum EDK\n{\n    EDK_Nil = -1,\n    EDK_DestinationKey = 0,\n    EDK_CurrentKey = 1,\n    EDK_Max = 2\n};\n\n/**\n * @class EXIT\n * @brief Exit to another worldlevel.\n */\nstruct EXIT : public ALO\n{\n    int fDefault;\n    /* 0x2e4 */ EXITS exits;\n    EXITS fKeyed;\n    float fFollowDefault;\n    int fTotals;\n    /* 0x2e8 */ float tExits;\n    int ctsurf;\n    TSURF *atsurf;\n    int ctbsp;\n    TBSP *atbsp;\n    WID widWarp;\n    OID oidWarp;\n    EDK edkAlt;\n    WID widAlt;\n    OID oidAlt;\n    int cpaseg;\n    ASEG *apaseg;\n    WIPEK wipek;\n    float tWipe;\n    float dtUnblock;\n    float dtTriggerWipe;\n};\n\nvoid InitXfm(XFM *pxfm);\n\nvoid LoadXfmFromBrx(XFM *pxfm, CBinaryInputStream *pbis);\n\nvoid SetXfmParent(XFM *pxfm, ALO *paloParent);\n\nvoid ApplyXfmProxy(XFM *pxfm, PROXY *pproxyApply);\n\nvoid ConvertXfmWorldToLocal(XFM *pxfm, VECTOR *pposWorld, VECTOR *pposLocal);\n\nvoid GetXfmPos(XFM *xfm, VECTOR *ppos);\n\nvoid GetXfmMat(XFM *pxfm, MATRIX3 *pmat);\n\nWARP *PwarpFromOid(OID oid, OID oidContext);\n\nvoid LoadWarpFromBrx(WARP *pwarp, CBinaryInputStream *pbis);\n\nvoid CloneWarp(WARP *pwarp, WARP *pwarpBase);\n\nvoid PostWarpLoad(WARP *pwarp);\n\nvoid TriggerWarp(WARP *pwarp);\n\nvoid SetWarpRsmg(WARP *pwarp, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal);\n\nvoid TeleportSwPlayer(SW *psw, OID oidWarp, OID oidWarpContext);\n\nEXIT *PexitDefault();\n\nvoid TriggerDefaultExit(int fInhibitAsegs, WIPEK wipek);\n\nvoid LoadExitFromBrx(EXIT *pexit, CBinaryInputStream *pbis);\n\nvoid PostExitLoad(EXIT *pexit);\n\n/**\n * @brief Sets the EXIT state.\n *\n * @param pexit Pointer to the EXIT.\n * @param exits EXIT state.\n*/\nvoid SetExitExits(EXIT *pexit, EXITS exits);\n\nvoid TriggerExit(EXIT *pexit);\n\nvoid WipeExit(EXIT *pexit);\n\nvoid UpdateExit(float dt, EXIT *pexit);\n\nvoid InitCamera(CAMERA *pcamera);\n\nvoid PostCameraLoad(CAMERA *camera);\n\nvoid EnableCamera(CAMERA *pcamera);\n\n#endif // XFORM_H\n"
  },
  {
    "path": "include/zap.h",
    "content": "/**\n * @file zap.h\n *\n * @brief Zap (damage) system.\n */\n#ifndef ZAP_H\n#define ZAP_H\n\n#include \"common.h\"\n#include <ensure.h>\n#include <oid.h>\n#include <so.h>\n\n// Forward.\nstruct XP;\nstruct PO;\nstruct ZPD;\n\ntypedef void (*PFNZAP)(ZPD *pzpd, PO *ppo);\n\n/**\n * @brief Zap kind.\n */\nenum ZPK\n{\n    ZPK_Nil = -1,\n    ZPK_Blunt = 0,\n    ZPK_Electric = 1,\n    ZPK_Fire = 2,\n    ZPK_Water = 3,\n    ZPK_Crush = 4,\n    ZPK_Pit = 5,\n    ZPK_Max = 6\n};\n\n/**\n * @brief Zap _?_ Kind\n *\n * @todo Figure out what the O stands for.\n*/\nenum ZOK\n{\n    ZOK_Nil = -1,\n    ZOK_Inherit = 0,\n    ZOK_Zap = 1,\n    ZOK_NoZap = 2,\n    ZOK_Ignore = 3,\n    ZOK_ZapAndIgnore = 4,\n    ZOK_Max = 5\n};\n\n/**\n * @brief Unknown.\n */\nstruct ZPD\n{\n    /* 0x00 */ SO *pso;\n    /* 0x04 */ ZPK zpk;\n    float dzThrow;\n    int fThrowCut;\n    int coidThrow;\n    OID aoidThrow[32];\n    /* 0x94 */ int cploThrow;\n    /* 0x98 */ LO *aploThrow[32];\n};\n\n/**\n * @brief Zap.\n */\nstruct ZAP\n{\n    // ...\n};\n\n/**\n * @brief TOUCH_ZAPPER\n * @brief Zapper trigger on touching the player.\n *\n * @todo Does it inherit from ZAP?\n*/\nstruct TZP : public SO\n{\n    // ...\n    /* 0x550 */ ZPD zpd;\n    // ...\n};\n\n/**\n * @brief Unknown.\n */\nstruct ZPR\n{\n    /* 0x00 */ ZPK zpk;\n    LO *ploSource;\n    /* 0x08 */ void *pv;\n    /* 0x0c */ PFNZAP pfnzap;\n};\n\n/**\n * @brief Zap volume?\n * @todo Implement the struct.\n */\nstruct VOLZP : public TZP\n{\n    // ...\n};\n\nvoid InitTzp(TZP *ptzp);\n\nvoid PostTzpLoad(TZP *ptzp);\n\nvoid UpdateTzp(TZP *ptzp, float dt);\n\nvoid CloneTzp(TZP *ptzp, TZP *ptzpBase);\n\nvoid RenderTzpAll(TZP *ptzp, CM *pcm, RO *pro);\n\nint FInflictTzpZap(TZP *ptzp, XP *pxp, ZPR *pzpr);\n\nZPD *PzpdEnsureTzp(TZP *ptzp, ENSK ensk);\n\n/**\n * @todo Rename.\n */\nvoid FUN_001F5210(TZP *ptzp);\n\nvoid InitVolzp(VOLZP *pvolzp);\n\nvoid UpdateVolzp(VOLZP *pvolzp, float dt);\n\nvoid InitZpd(ZPD *pzpd, SO *pso);\n\nvoid PostZpdLoad(ZPD *pzpd);\n\nvoid ApplyZpdThrow(ZPD *pzpd, PO *ppo);\n\nvoid InflictZpdZap(ZPD *pzpd, XP *pxp, ZPR *pzpr);\n\nvoid AddZpdZapObject(ZPD *pzpd, OID oid);\n\nvoid AddZpdZapLo(ZPD *pzpd, LO *plo);\n\nvoid RemoveZpdZapLo(ZPD *pzpd, LO *plo);\n\n#endif // ZAP_H\n"
  },
  {
    "path": "requirements.txt",
    "content": "splat64[mips]>=0.36.0,<1.0.0\nspimdisasm>=1.36.1,<2.0.0\nrabbitizer==1.13.0\ntqdm\nn64img\npygfxd\ncrunch64\nninja\nninja_syntax\nmapfile_parser\n"
  },
  {
    "path": "scripts/build.sh",
    "content": "#!/bin/bash\nset -e\n\nPROJECT_DIR=\"$(dirname \"$0\")/..\"\n\n# Ensure disc/SCUS_971.98 exists\nif [ ! -f \"$PROJECT_DIR/disc/SCUS_971.98\" ]; then\n    echo \"Error: SCUS_971.98 not found. Copy it from your own game disc to the 'disc' directory of this project.\" >&2\n    exit 1\nfi\n\npushd $PROJECT_DIR > /dev/null\ntrap \"popd > /dev/null\" EXIT\n\nif [ -z \"$VIRTUAL_ENV\" ]; then\n    source \"env/bin/activate\"\nfi\npython3 \"configure.py\" --clean\nninja\n"
  },
  {
    "path": "scripts/check_progress.py",
    "content": "import json\nimport sys\n\ntry:\n    with open(\"report.json\", \"r\") as f:\n        data = json.load(f)\nexcept FileNotFoundError:\n    print(\"Error: \\\"report.json\\\" not found. Please run \\\"./scripts/checks.sh --report\\\" first to generate the report file.\")\n    sys.exit(1)\n\nfor category in data[\"categories\"]:\n    name = category.get(\"name\")\n    if name != \"Engine\" and name != \"Splice\":\n        continue\n    \n    measures = category.get(\"measures\", {})\n\n    fuzzy_match_percent = measures.get(\"fuzzy_match_percent\", 0.0)\n    total_code = int(measures.get(\"total_code\", 0)) / 1024\n    matched_code = int(measures.get(\"matched_code\", 0)) / 1024\n    matched_code_percent = measures.get(\"matched_code_percent\", 0.0)\n\n    total_data = int(measures.get(\"total_data\", 0)) / 1024\n    matched_data = int(measures.get(\"matched_data\", 0)) / 1024\n    matched_data_percent = measures.get(\"matched_data_percent\", 0.0)\n\n    total_functions = measures.get(\"total_functions\")\n    matched_functions = measures.get(\"matched_functions\")\n    \n    print(f\"{name}:\")\n    print(f\"  - Fuzzy match:       {fuzzy_match_percent:.2f}%\")\n    print(f\"  - Perfect match:     {matched_code_percent:.2f}% ({matched_code:.2f} KiB / {total_code:.2f} KiB)\")\n    print(f\"  - Matched data:      {matched_data_percent:.2f}% ({matched_data:.2f} KiB / {total_data:.2f} KiB)\")\n    print(f\"  - Matched functions: {matched_functions} / {total_functions}\\n\")\n"
  },
  {
    "path": "scripts/checks.sh",
    "content": "#!/bin/bash\nset -e\n\nPROJECT_DIR=\"$(dirname \"$0\")/..\"\n\npushd $PROJECT_DIR > /dev/null\ntrap \"popd > /dev/null\" EXIT\n\nif [ -z \"$VIRTUAL_ENV\" ]; then\n    source \"env/bin/activate\"\nfi\npython3 \"configure.py\" --clean && ninja\npython3 \"configure.py\" --clean --objects && ninja\n\n# Output the progress report to a file if --report is not passed, otherwise discard it.\nif [[ \"$1\" == \"--report\" ]]; then\n    ./tools/objdiff/objdiff-cli report generate > report.json\nelse\n    ./tools/objdiff/objdiff-cli report generate > /dev/null\nfi\n"
  },
  {
    "path": "scripts/codematcher/match_all.sh",
    "content": "#!/bin/bash\n\n# Set working dir to codematcher directory\nproject_dir=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)/..\"\ncodematcher_path=\"$project_dir/tools/codematcher\"\npushd $codematcher_path > /dev/null\n\n# Invoke codematcher to compile and match source tree\necho \"Matching source tree...\"\nsource_tree_path=\"$project_dir/src/P2\"\n./codematcher may_proto.elf --compile $source_tree_path\n\n# Done\npopd > /dev/null\n"
  },
  {
    "path": "scripts/codematcher/match_file.sh",
    "content": "#!/bin/bash\n\n# Get the name of the source file as a parameter\nsource_file=\"$1\"\n\n# Check if the source file parameter is empty\nif [ -z \"$source_file\" ]; then\n    echo \"No source file specified!\"\n    echo \"    Usage: $0 <source_file>\"\n    exit 1\nfi\n\n# Strip the extension from the source file\nsource_basename=\"$(basename \"$source_file\" | cut -d. -f1)\"\n\n# Set working dir to project dir and make object file\nproject_dir=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)/..\"\ncodematcher_path=\"$project_dir/tools/codematcher\"\npushd $project_dir > /dev/null\necho \"Compiling $source_basename.o...\"\nmake clean > /dev/null\nmake obj/debug/$source_basename.o > /dev/null\n\n# CD to codematcher directory and invoke codematcher with the compiled object file\necho \"Matching $source_basename.o...\"\ncd tools/codematcher >/dev/null\n./codematcher may_proto.elf --match \"$project_dir/obj/debug/$source_basename.o\"\n\n# Move back to the original directory\npopd >/dev/null\npopd >/dev/null\n"
  },
  {
    "path": "scripts/codematcher/match_function_live.sh",
    "content": "#!/bin/bash\n\n# Get name of source file and target function as parameters\nsource_file=\"$1\"\ntarget_function=\"$2\"\n\n# Check if the source file parameter is empty\nif [ -z \"$source_file\" ]; then\n    echo \"No source file specified!\"\n    echo \"    Usage: $0 <source_file> <target_function>\"\n    exit 1\nfi\n\n# Check if the target function parameter is empty\nif [ -z \"$target_function\" ]; then\n    echo \"No target function specified!\"\n    echo \"    Usage: $0 <source_file> <target_function>\"\n    exit 1\nfi\n\n# Strip the extension from the source file\nsource_basename=\"$(basename \"$source_file\" | cut -d. -f1)\"\n\n# Match command: match_file script grepped with relevant lines\nmatch_cmd=\"./match_file.sh $source_file | grep -e'------------' -e'+' -e'$target_function'\"\n\n# Print command: ee-objdump grepped with regex matching everything from the function name to a blank line\nobjdump_cmd=\"wine ~/.wine/drive_c/usr/local/sce/ee/gcc/bin/ee-objdump.exe -d ../obj/debug/$source_basename.o | grep -e'$target_function' -A1000 -e'^$'\"\n\n# Watch the match_single script with the source file and dump file commands\nwatch -n 1 --color \"( $match_cmd && $objdump_cmd )\"\n"
  },
  {
    "path": "scripts/diff.sh",
    "content": "#!/bin/bash\nset -e\n\nif [ -z \"$1\" ]; then\n\techo \"Usage: $0 FunctionName [ObjectName]\" >&2\n\texit 1\nfi\n\ncd \"$(dirname \"$0\")/..\"\nif [ -z \"$VIRTUAL_ENV\" ]; then\n\tsource \"env/bin/activate\"\nfi\npython3 configure.py --objects\nninja\n\nif [ -n \"$2\" ]; then\n\t./tools/objdiff/objdiff-cli diff --project . -u \"$2\" \"$1\"\nelse\n\t./tools/objdiff/objdiff-cli diff --project . \"$1\"\nfi\n"
  },
  {
    "path": "scripts/extract_elf.sh",
    "content": "#!/bin/bash\nset -e\n\nISO_FILE=\"$1\"\n\n# Check for ISO\n[ -z \"$ISO_FILE\" ] && {\n    echo \"Error: No ISO path provided.\" >&2;\n    echo \"Usage: $0 /path/to/game.iso\" >&2;\n    exit 1;\n}\n\n[ ! -f \"$ISO_FILE\" ] && {\n    echo \"Error: ISO file not found: $ISO_FILE\" >&2;\n    exit 1;\n}\n\nPROJECT_DIR=\"$(dirname \"$0\")/..\"\nELF_FILE=\"$PROJECT_DIR/disc/SCUS_971.98\"\nCHECKSUM=\"57dc305db57932ad3f1122966cdb695d2e62a47a\"\n\n# Extract SCUS_971.98\necho \"Extracting from $ISO_FILE...\"\nif command -v bsdtar &>/dev/null; then\n    bsdtar --no-same-permissions --no-same-owner -xf \"$ISO_FILE\" -C \"$PROJECT_DIR/disc\" SCUS_971.98\n    elif command -v 7z &>/dev/null; then\n    7z e \"$ISO_FILE\" -o\"$PROJECT_DIR/disc\" SCUS_971.98 -y\n    elif command -v isoinfo &>/dev/null; then\n    isoinfo -i \"$ISO_FILE\" -x /SCUS_971.98 > \"$ELF_FILE\"\nelse\n    echo \"Error: No extraction tool found. Install bsdtar, 7z, or isoinfo.\" >&2\n    exit 1\nfi\n\n[ ! -f \"$ELF_FILE\" ] && { echo \"Extraction failed.\" >&2; exit 1; }\nchmod 644 \"$ELF_FILE\"\n\n# Verify checksum\necho \"Verifying SCUS_971.98...\"\nACTUAL=$(sha1sum \"$ELF_FILE\" | awk '{print $1}')\nif [ \"$ACTUAL\" != \"$CHECKSUM\" ]; then\n    echo \"Error: Checksum mismatch! Expected: $CHECKSUM, Got: $ACTUAL\" >&2\n    echo \"Please ensure you have the correct version of the game (NTSC-U).\" >&2\n    exit 1\nfi\n\necho \"SCUS_971.98 is ready!\"\n"
  },
  {
    "path": "scripts/frogress/mapfile_progress.sh",
    "content": "#!/bin/bash\n\nset -e\n\nscript_dir=$(dirname $0)\npushd $script_dir/../.. > /dev/null\n\nif [[ \"$1\" == \"--help\" || \"$1\" == \"-h\" ]]; then\n    echo \"Usage: $0 [--skip-build]\"\n    echo \"  --skip-build: Skip building and just check progress\"\n    exit 0\nfi\n\nif [[ \"$1\" != \"--skip-build\" ]]; then\n    ./scripts/build.sh\nfi\n\npython3 -m mapfile_parser progress out/SCUS_971.98.map asm asm/nonmatchings/\n\npopd > /dev/null\n"
  },
  {
    "path": "scripts/frogress/upload_progress.py",
    "content": "\"\"\"\nScript for uploading progress reported by mapfile_parser to the Frogress API.\n\nAdapted from https://github.com/zeldaret/af/blob/aeb01dcb95e8281f89f355604dbeba519ef073d5/tools/progress.py\nMIT License: https://opensource.org/license/mit\n\"\"\"\nfrom pathlib import Path\nfrom datetime import datetime\nimport argparse\nimport mapfile_parser\n\nASMPATH = Path(\"asm\")\nNONMATCHINGS = \"nonmatchings\"\nBASE_URL = \"https://progress.deco.mp\"\nSLUG = \"slycooper1\"\nVERSION = \"us\"\n\ndef getProgressFromMapFile(mapFile: mapfile_parser.MapFile, asmPath: Path, nonmatchings: Path, aliases: dict[str, str]=dict(), pathIndex: int=2) -> tuple[mapfile_parser.ProgressStats, dict[str, mapfile_parser.ProgressStats]]:\n    totalStats = mapfile_parser.ProgressStats()\n    progressPerFolder: dict[str, mapfile_parser.ProgressStats] = dict()\n\n    for segment in mapFile:\n        for file in segment:\n            if len(file) == 0:\n                continue\n\n            folder = file.filepath.parts[pathIndex]\n\n            if \".a\" in folder:\n                folder = folder.split('.a')[0]\n\n            if folder in aliases:\n                folder = aliases[folder]\n\n            if folder not in progressPerFolder:\n                progressPerFolder[folder] = mapfile_parser.ProgressStats()\n\n            originalFilePath = Path(*file.filepath.parts[pathIndex:])\n\n            extensionlessFilePath = originalFilePath\n            while extensionlessFilePath.suffix:\n                extensionlessFilePath = extensionlessFilePath.with_suffix(\"\")\n\n            fullAsmFile = asmPath / extensionlessFilePath.with_suffix(\".s\")\n\n            handwrittenAsmFiles = [Path(\"sce/crt0.o\")]\n\n            if originalFilePath in handwrittenAsmFiles:\n                wholeFileIsUndecomped = False\n            else:\n                wholeFileIsUndecomped = fullAsmFile.exists()\n\n            for func in file:\n                funcAsmPath = nonmatchings / extensionlessFilePath / f\"{func.name}.s\"\n\n                symSize = 0\n                if func.size is not None:\n                    symSize = func.size\n\n                if wholeFileIsUndecomped:\n                    totalStats.undecompedSize += symSize\n                    progressPerFolder[folder].undecompedSize += symSize\n                elif funcAsmPath.exists():\n                    totalStats.undecompedSize += symSize\n                    progressPerFolder[folder].undecompedSize += symSize\n                else:\n                    totalStats.decompedSize += symSize\n                    progressPerFolder[folder].decompedSize += symSize\n\n    return totalStats, progressPerFolder\n\ndef getProgress(mapPath: Path) -> tuple[mapfile_parser.ProgressStats, dict[str, mapfile_parser.ProgressStats]]:\n    \"\"\"\n    Gets the progress of the using the mapfile parser.\n    \"\"\"\n    mapFile = mapfile_parser.MapFile()\n    mapFile.readMapFile(mapPath)\n\n    for segment in mapFile:\n        for file in segment:\n            if len(file) == 0:\n                continue\n\n            filepathParts = list(file.filepath.parts)\n            file.filepath = Path(*filepathParts)\n\n    nonMatchingsPath = ASMPATH / NONMATCHINGS\n\n    progress = getProgressFromMapFile(mapFile.filterBySectionType(\".text\"), ASMPATH, nonMatchingsPath, aliases={\"ultralib\": \"libultra\"})\n\n    return progress\n\ndef main(args: argparse.ArgumentParser) -> None:\n    \"\"\"\n    Main function, calculates the progress and uploads it to the frogress.\n    \"\"\"\n    frogress_api_key = args.frogress_api_key\n    if not frogress_api_key:\n        raise ValueError(\"Missing frogress API key.\")\n\n    mapPath = \"out/SCUS_971.98.map\"\n\n    codeTotalStats, codeProgressPerFolder = getProgress(mapPath)\n    codeEntries: dict[str, int] = mapfile_parser.frontends.upload_frogress.getFrogressEntriesFromStats(codeTotalStats, codeProgressPerFolder, verbose=True)\n    print(codeEntries)\n\n    url = mapfile_parser.utils.generateFrogressEndpointUrl(BASE_URL, SLUG, VERSION)\n    mapfile_parser.frontends.upload_frogress.uploadEntriesToFrogress(codeEntries, \"all\", url, apikey=frogress_api_key, verbose=True)\n\nif __name__ == \"__main__\":\n    parser = argparse.ArgumentParser(description=\"Upload progress to the frogress\")\n    parser.add_argument(\"--frogress_api_key\", help=\"API key for the frogress\")\n\n    args = parser.parse_args()\n    main(args)\n"
  },
  {
    "path": "scripts/quickstart.sh",
    "content": "#!/bin/bash\nset -e\n\n### Install Dependencies ###\n\nPACKAGES=\"binutils-mips-linux-gnu ninja-build python3 python3-pip python3-venv\"\nISO_ARG=\"$1\"\nPROJECT_DIR=\"$(dirname \"$0\")/..\"\nDISC_DIR=\"$PROJECT_DIR/disc\"\nTOOLS_DIR=\"$PROJECT_DIR/tools\"\nWIBO_URL=\"https://github.com/decompals/wibo/releases/download/1.0.0/wibo-i686\"\n\n# If no ISO specified, look for one in the disc directory\nif [ -z \"$ISO_ARG\" ] && [ ! -f $PROJECT_DIR/disc/SCUS_971.98 ]; then\n\techo \"No ISO file specified, looking in disc directory...\"\n\tISO_FILES=(\"$DISC_DIR\"/*.iso)\n\tif [ -f \"${ISO_FILES[0]}\" ]; then\n\t\tISO_ARG=\"${ISO_FILES[0]}\"\n\t\techo \"Found ISO: $(basename \"$ISO_ARG\")\"\n\telse\n\t    echo \"No ISO found in disc directory. Skipping executable extraction.\"\n\tfi\nfi\n\n# If ISO is specified, validate it\nif [ -n \"$ISO_ARG\" ]; then\n\tif [ ! -f \"$ISO_ARG\" ]; then\n\t\techo \"Error: ISO file not found: $ISO_ARG\" >&2\n\t\texit 1\n\tfi\n\tISO_ARG=\"$(realpath \"$ISO_ARG\")\"\n    PACKAGES=\"$PACKAGES libarchive-tools\"\nfi\n\n# Download Wibo\nWIBO_PATH=\"$TOOLS_DIR/wibo-i686\"\necho \"Downloading Wibo...\"\nmkdir -p \"$TOOLS_DIR\"\nif wget -q -O \"$WIBO_PATH\" \"$WIBO_URL\"; then\n\tchmod +x \"$WIBO_PATH\"\nelse\n\techo \"Wibo download failed, adding wine32 to dependencies instead...\"\n\tPACKAGES=\"$PACKAGES wine32\"\nfi\n\n# Install missing dependencies\nif ! sudo -n true 2>/dev/null; then\n    echo \"Root privileges are required to install dependencies. Please enter your password.\"\nfi\n\nif ! sudo -v; then\n    echo \"Error: Unable to obtain root privileges\" >&2\n    exit 1\nfi\n\necho \"Adding i386 architecture support...\"\nsudo dpkg --add-architecture i386\n\necho \"Updating package lists...\"\nsudo apt-get update -qq > /dev/null\n\necho \"Dependencies: $PACKAGES\"\necho \"Installing missing dependencies...\"\nsudo apt-get install -y -qq $PACKAGES > /dev/null\n\npushd $PROJECT_DIR > /dev/null\ntrap \"popd > /dev/null\" EXIT\n\n# Set up Python virtual environment\necho \"Setting up Python virtual environment...\"\npython3 -m venv env\nsource env/bin/activate\necho \"Installing Python packages...\"\npip install -q -U -r requirements.txt\n\n### Download ProDG compilers and runtimes ###\n\necho \"Starting ProDG setup script...\"\n./scripts/setup_prodg_linux.sh\n\n## Extract ELF ###\n\nif [ -n \"$ISO_ARG\" ]; then\n    echo \"Extracting executable from ISO...\"\n    ./scripts/extract_elf.sh \"$ISO_ARG\"\nfi\n\npopd > /dev/null\ntrap - EXIT\n\n### Final Instructions ###\n\necho \"\"\necho \"Quickstart complete!\"\necho \"\"\nif [ ! -f $PROJECT_DIR/disc/SCUS_971.98 ]; then\n    echo \"Copy SCUS_971.98 from your copy of the game to the 'disc' directory of this project.\"\nfi\necho \"To build the project, run '$(dirname \"$0\")/build.sh'\"\n"
  },
  {
    "path": "scripts/readme.md",
    "content": "# Scripts\n\nThis directory contains the following scripts used to setup and build the project. There are a few others, but they are not used in the normal contributing workflow.\n\n## Setup scripts\n\n### quickstart.sh\n\nInstalls the necessary dependencies using pip/apt and sets up the build environment. This will run all the other setup scripts for you. You only need to run this script once.\n\n### setup_prodg_linux.sh\n\nInstalls the compiler needed to build the project on Linux. `quickstart.sh` will run this script for you, so you don't need to run both.\n\nThere is an equivalent script for Windows, but the assembler does not work on Windows, so you can't build the project on Windows. You must use Linux or WSL.\n\n## Utility scripts\n\n### build.sh\n\nRuns a clean reconfigure (deletes build files and splits the binary), then builds the project. Will warn you if `disc/SCUS_971.98` is not present.\n\n### diff.sh\n\nCompares a decompiled function against the original using objdiff. Takes a function name as a required argument and an optional object name.\n\n### run.sh\n\nRuns the last successful build in an emulator. Before using, you must install PCSX2, build the project, and either place an ISO in the `disc` directory or specify one as an argument. The script will boot the emulator using the compiled elf, and load the assets from the provided ISO.\n\nPCSX2 will be auto detected in this order:\n* System PATH\n* Flatpak\n* AppImage in the `tools` directory with \"pcsx2\" in the file name\n* XDG Desktop entry with \"pcsx2\" in the file name\n\n### checks.sh\n\nRuns the same build commands that GitHub actions uses to verify that the project builds successfully. This must pass before a pull request will be merged. If the argument `--report` is passed it outputs the current project progress to `report.json`.\n\n### check_progress.py\n\nPrints the current project progress based on the data in `report.json`.\n"
  },
  {
    "path": "scripts/run.sh",
    "content": "#!/bin/bash\nset -e\n\nPROJECT_DIR=\"$(dirname \"$0\")/..\"\nELF=\"$PROJECT_DIR/out/SCUS_971.98\"\n\n# Parse Arguments\nif [[ $# -gt 1 ]]; then\n    echo \"Usage: $0 [/path/to/game.iso]\" >&2\n    exit 1\nfi\n\nif [[ $# -eq 1 ]]; then\n    ISO=\"$1\"\nelse # Find any ISO in disc directory\n    ISO=$(find \"$PROJECT_DIR/disc\" -maxdepth 1 -type f -iname \"*.iso\" -print -quit 2>/dev/null)\n    if [[ -z \"$ISO\" ]]; then\n        echo \"Error: No ISO found in $PROJECT_DIR/disc\" >&2\n        exit 1\n    fi\n    echo \"Using ISO: $(basename \"$ISO\")\"\nfi\n\n# Verify Files\nif [[ ! -f \"$ISO\" ]]; then\n    echo \"Error: ISO not found: $ISO\" >&2\n    exit 1\nfi\n\nif [[ ! -f \"$ELF\" ]]; then\n    echo \"Error: ELF not found: $ELF\" >&2\n    echo \"Build the project first with: ./configure.py && ninja\" >&2\n    exit 1\nfi\n\n# Resolve full paths for sandboxed environments\nISO=\"$(realpath \"$ISO\")\"\nELF=\"$(realpath \"$ELF\")\"\n\nfind_pcsx2() {\n    # Check system PATH\n    if command -v pcsx2 &>/dev/null; then\n        printf \"pcsx2\"\n        return 0\n    fi\n\n    # Check flatpak\n    if command -v flatpak &>/dev/null && flatpak list --app 2>/dev/null | grep -q \"net.pcsx2.PCSX2\"; then\n        printf \"flatpak run net.pcsx2.PCSX2\"\n        return 0\n    fi\n\n    # Check for AppImage in tools directory\n    local appimage=$(find \"$PROJECT_DIR/tools\" -maxdepth 1 -type f -iname \"*pcsx2*.appimage\" -executable -print -quit 2>/dev/null)\n    if [[ -n \"$appimage\" ]]; then\n        printf '%q' \"$appimage\"\n        return 0\n    fi\n\n    # Check XDG Desktop entries\n    local desktop_file=$(find ~/.local/share/applications /usr/share/applications /usr/local/share/applications \\\n        -maxdepth 1 -type f -iname \"*pcsx2*.desktop\" -print -quit 2>/dev/null)\n    if [[ -n \"$desktop_file\" ]]; then\n        # Extract executable path, stripping env vars and desktop file arguments\n        local exec_line=$(grep -m1 \"^Exec=\" \"$desktop_file\" | \\\n            sed 's/^Exec=//' | \\\n            sed 's/^env //' | \\\n            sed 's/[A-Z_][A-Z0-9_]*=[^ ]* *//g' | \\\n            sed 's/ %.*//' | \\\n            awk '{print $1}')\n        printf '%q' \"$exec_line\"\n        return 0\n    fi\n\n    return 1\n}\n\nPCSX2=$(find_pcsx2)\n\nif [[ -z \"$PCSX2\" ]]; then\n    echo \"Error: PCSX2 not found. Install it via:\" >&2\n    echo \"  - System package manager (pcsx2)\" >&2\n    echo \"  - Flatpak: flatpak install net.pcsx2.PCSX2\" >&2\n    echo \"  - Download AppImage to $PROJECT_DIR/tools/\" >&2\n    exit 1\nfi\n\nrun_verbose() {\n    ( PS4=''; set -x; \"$@\" )\n}\n\n# Grant Flatpak Permissions\nif [[ \"$PCSX2\" == \"flatpak run\"* ]]; then\n    run_verbose flatpak override --user net.pcsx2.PCSX2 \\\n        --filesystem=\"$ISO\":ro \\\n        --filesystem=\"$ELF\":ro\nfi\n\n# Launch PCSX2\nrun_verbose $PCSX2 -elf \"$ELF\" -fastboot -nogui -- \"$ISO\"\n"
  },
  {
    "path": "scripts/setup_prodg_linux.sh",
    "content": "#!/bin/bash\n# Sets up the ProDG compilers + SCE Runtime Library to build the project.\nset -e\n\nPROJECT_DIR=\"$(dirname \"$0\")/..\"\nTOOLS_DIR=\"$PROJECT_DIR/tools\"\nDOWNLOAD_URL=\"https://github.com/TheOnlyZac/compilers/releases/download/ee-gcc2.95.2-SN-v2.73a/ee-gcc2.95.2-SN-v2.73a.tar.gz\"\n\necho \"Downloading compiler...\"\nwget -q -O - \"$DOWNLOAD_URL\" | tar -xz -C \"$TOOLS_DIR\"\necho \"ProDG setup complete!\"\n"
  },
  {
    "path": "scripts/windows/backup_registry.bat",
    "content": "REM backup registry to C:\\usr\\local\\sce\\regbackup.reg\necho Backing up registry, please accept the UAC prompt\nregedit /E C:\\usr\\local\\sce\\regbackup.reg \"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\"\n"
  },
  {
    "path": "scripts/windows/run.bat",
    "content": "@echo off\n\nREM ##############################################################################\nREM Set these paths to point to your PCSX2 1.7 executable and your copy of the game\nset PCSX2_PATH=\"C:\\path\\to\\pcsx2.exe\"\nset ISO_PATH=\"\"\nREM ##############################################################################\n\ngoto :start\n\nREM die: MESSAGE\nREM perl-style `die` expressions.\n:die\necho run.bat: error: %*\nexit /b 1\n\nREM start\nREM main entrypoint\n:start\nif not defined PCSX2_PATH (\n    call :die \"PCSX2 path is empty, please edit the paths in 'run.bat'\"\n)\nif not defined ISO_PATH (\n    echo Warning: ISO path is empty, please edit the paths in 'run.bat'\n)\nif not exist \"!ISO_PATH!\" (\n    call :die \"Game ISO not found at '!ISO_PATH!'\"\n)\nif not exist \"!PCSX2_PATH!\" (\n    call :die \"PCSX2 executable not found at '!PCSX2_PATH!'\"\n)\nif not \"!PCSX2_PATH:~-4!\"==\".exe\" (\n    call :die \"PCSX2 exe is not executable\"\n)\n\nREM Switch to the project root directory\npushd \"%~dp0..\\..\" > nul\n\nREM Build the game\necho Compiling ELF...\n::make clean > nul\nmake > nul\n\nREM Run the game\necho Booting ELF in PCSX2...\n\"%PCSX2_PATH%\" -elf \".\\bin\\debug\\SCUS_971.98\" %ISO_PATH%\n\nREM Switch back to the original directory\npopd > nul\necho Done.\n"
  },
  {
    "path": "scripts/windows/setup_prodg_windows.bat",
    "content": "@echo off\nsetlocal\n\nREM The SDK (Runtime Library) version to install.\nset SDK_VER=242\n\necho Starting ProDG setup script...\ngoto :start\n\n\nREM die: MESSAGE\nREM perl-style `die` expressions.\n:die\necho Error: %*\nexit /b 1\n\n\nREM download_file: URL\nREM downloads file using curl\n:download_file\necho Downloading %~1...\nset output_file=%TEMP%\\progd.zip\ncurl -L %~1 -o %output_file%\nif exist \"%output_file%\" (\n    echo File downloaded to %output_file%\n) else (\n    call :die Failed to download file\n)\ngoto :eof\n\n\nREM start\nREM main entrypoint\n:start\necho NOTE This script is untested with the new build system and may not work as expected!\necho Please report any issues on github or discord.\necho\n\nREM download required files (registry + SDK package)\ncall :download_file \"https://github.com/TheOnlyZac/compilers/releases/download/ee-gcc2.95.2-SN-v2.73a/ee-gcc2.95.2-SN-v2.73a.zip\"\n\n::REM apply environment variables from the registry file\n::echo Applying environment variables, please accept the UAC prompt\n::regedit %TEMP%\\prodg_env.reg\n\nREM Extract the compiler to the project/tools directory\necho Extracting compiler to tools directory...\n7z x -y %TEMP%\\progd.zip -otools\n\n::echo Removing temporary files\necho Removing temporary files...\n::del %TEMP%\\ee-gcc2.95.2-SN-v2.73a.zip\n\necho Setup complete!\nendlocal\n"
  },
  {
    "path": "src/P2/989snd.c",
    "content": "#include \"989snd.h\"\n\n#include <sdk/ee/eekernel.h>\n#include <sdk/ee/sifrpc.h>\n#include <sdk/libcdvd.h>\n\n#include <common.h>\n#include <text.h>\n\ntypedef unsigned int u_int;\ntypedef unsigned long u_long;\n\n// Linux style volatile access macro's\n#define READ_ONCE(x) (*(const volatile typeof(x)*)(&x))\n#define WRITE_ONCE(x, val) (*(volatile typeof(x)*)(&x) = (val))\n\nu_int snd_SendIOPCommandAndWait(int command, int data_used, char* in_data);\nvoid snd_SendIOPCommandNoWait(int command, int data_used, char* in_data, SndCompleteProc done, u_long u_data);\nint snd_GotReturns(void);\nvoid snd_SendCurrentBatch(void);\nvoid snd_PostMessage(void);\n\nstruct SndCommandReturnDef { // 0x10\n    /* 0x0 */ SndCompleteProc done;\n    /* 0x8 */ u_long u_data;\n};\n\nstruct SndCommandBuffer { // 0x1000\n    /* 0x0000 */ int num_commands;\n    /* 0x0004 */ char buf[4092];\n};\n\ntypedef struct SndCommandReturnDef* SndCommandReturnDefPtr;\n\nstruct SndSystemStatus { // 0x40\n    /* 0x00 */ int cd_busy;\n    /* 0x04 */ int pad_0;\n    /* 0x08 */ int pad_1;\n    /* 0x0c */ int pad_2;\n    /* 0x10 */ int cd_error;\n    /* 0x14 */ int pad_3;\n    /* 0x18 */ int pad_4;\n    /* 0x1c */ int pad_5;\n    /* 0x20 */ char pad_big[32];\n};\n\nstruct SndMessageData { // 0x20\n    /* 0x00 */ int data[7];\n    /* 0x1c */ int command;\n};\ntypedef struct SndMessageData* SndMessageDataPtr;\n\nu_int* gCommBusy = 0;\nint gAwaitingInts = 0;\nint gUnkBankLoadError = 0;\nint gStreamingInited = 0;\nvoid (*gCdCallback)(int) = NULL;\nint gSSRead = 0;\nint gSSReadDone = 0;\nint gLoadingFromFS = 0;\n\nextern struct SndCommandBuffer gSndCommandBuffer1;\nextern struct SndCommandBuffer gSndCommandBuffer2;\nstruct SndCommandBuffer* gSndCommandBuffePtr[2] = { &gSndCommandBuffer1, &gSndCommandBuffer2 };\n\nint gCommandBuffeBytesAvail[2] = { 0xffc, 0xffc };\n\nextern struct SndCommandReturnDef gSndCommandReturnDef1[256];\nextern struct SndCommandReturnDef gSndCommandReturnDef2[256];\nstruct SndCommandReturnDef* gSndCommandReturnDefPtr[2] = { gSndCommandReturnDef1, gSndCommandReturnDef2 };\n\nextern unsigned int gActualReturnValues1[272];\nextern unsigned int gActualReturnValues2[272];\nu_int* gReturnValuesPtr[2] = { gActualReturnValues1, gActualReturnValues2 };\n\nint gCommandFillBuffer = 0;\nint gCaching = 0;\nu_int gLoadBusy = 0;\nstruct SndCommandReturnDef gLoadReturnDef = {};\nstatic SndCompleteProc gLoadCB = NULL;\nstatic u_long gLoadUserData = 0;\nu_int gLoadCommand = 0;\nint gLoadAwaits = 0;\n\n// Aligment for DMA transfer buffers\nunsigned int gSyncBuffer[16] __attribute__((aligned(16))) = {};\nchar gSyncSendBuffer[64] __attribute__((aligned(16))) = {};\nchar gSyncStringBuffer[256] __attribute__((aligned(16))) = {};\nstruct SndCommandBuffer gSndCommandBuffer1 __attribute__((aligned(16))) = {};\nstruct SndCommandBuffer gSndCommandBuffer2 __attribute__((aligned(16))) = {};\n\nstruct SndCommandReturnDef gSndCommandReturnDef1[256] = {};\nstruct SndCommandReturnDef gSndCommandReturnDef2[256] = {};\n\n// Not actually sure on their size\nunsigned int gActualReturnValues1[272] __attribute__((aligned(16))) = {};\nunsigned int gActualReturnValues2[272] __attribute__((aligned(16))) = {};\nstruct SndSystemStatus gStats __attribute__((aligned(16))) = {};\nunsigned int gLoadReturnValue[16] __attribute__((aligned(16))) = {};\nint gLoadParams[8] __attribute__((aligned(16))) = {};\n\n// BSS\nextern sceSifClientData gSLClientData;\nextern sceSifClientData gSLClientLoaderData;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/989snd\", snd_StartSoundSystem);\n#ifdef SKIP_ASM\n// Assembler delay slot diff\nvoid snd_StartSoundSystem(void)\n{\n    int i;\n\n    gSndCommandBuffePtr[0] = &gSndCommandBuffer1;\n    gSndCommandBuffePtr[1] = &gSndCommandBuffer2;\n    gReturnValuesPtr[0] = gActualReturnValues1;\n    gReturnValuesPtr[1] = gActualReturnValues2;\n    gSndCommandReturnDefPtr[0] = gSndCommandReturnDef1;\n    gSndCommandReturnDefPtr[1] = gSndCommandReturnDef2;\n    sceSifInitRpc(0);\n\n    while (1) {\n        if (sceSifBindRpc(&gSLClientData, 0x123456, 0) < 0) {\n            printf(\"error: sceSifBindRpc in %s, at line %d\\n\", \"989snd.c\", 0x6e);\n            while (1)\n                ;\n        }\n        i = 10000;\n        while (i--)\n            ;\n        if (gSLClientData.serve != 0) {\n            break;\n        }\n    }\n\n    gLoadBusy = 0;\n    gLoadReturnDef.done = NULL;\n    gLoadReturnDef.u_data = 0;\n    gLoadReturnValue[0] = 0;\n    while (1) {\n        if (sceSifBindRpc(&gSLClientLoaderData, 0x123457, 0) < 0) {\n            printf(\"error: sceSifBindRpc in %s, at line %d\\n\", \"989snd.c\", 0x83);\n            while (1)\n                ;\n        }\n        i = 10000;\n        while (i--)\n            ;\n        if (gSLClientLoaderData.serve != 0) {\n            break;\n        }\n    }\n\n    gStats.cd_busy = 0;\n    gStats.cd_error = 0;\n    gSndCommandBuffer2.num_commands = gSndCommandBuffer1.num_commands = 0;\n    gCommandBuffeBytesAvail[1] = gCommandBuffeBytesAvail[0] = 0xffc;\n\n    i = (int)&gStats;\n    snd_SendIOPCommandAndWait(0, sizeof(i), (char*)&i);\n}\n#endif\n\nint snd_FlushSoundCommands()\n{\n    SndCompleteProc done;\n    u_long u_data;\n    int which, x;\n\n    if (gCommBusy && snd_GotReturns()) {\n        if (gLoadingFromFS) {\n            if (gLoadCB) {\n                gLoadCB(gSyncBuffer[1], gLoadUserData);\n            }\n            gLoadCB = NULL;\n            gLoadingFromFS = 0;\n        } else {\n            which = gCommandFillBuffer != 1;\n            for (x = 0; x < gSndCommandBuffePtr[which]->num_commands; x++) {\n                done = gSndCommandReturnDefPtr[which][x].done;\n                if (gSndCommandReturnDefPtr[which][x].done) {\n                    u_data = gSndCommandReturnDefPtr[which][x].u_data;\n                    done(gReturnValuesPtr[which][x + 1], u_data);\n                }\n            }\n        }\n    }\n\n    if (gLoadBusy) {\n        FlushCache(0);\n        if (gLoadReturnValue[0] != -1) {\n            if (gLoadReturnDef.done) {\n                u_data = gLoadReturnDef.u_data;\n                done = gLoadReturnDef.done;\n                gLoadReturnDef.done = NULL;\n                gLoadReturnDef.u_data = 0;\n                done(gLoadReturnValue[0], u_data);\n            }\n            gLoadBusy = 0;\n            gLoadReturnValue[0] = 0;\n        }\n    }\n\n    if (!gCommBusy && gSndCommandBuffePtr[gCommandFillBuffer]->num_commands && !gCaching) {\n        snd_SendCurrentBatch();\n    }\n\n    if (gSSRead) {\n        snd_StreamSafeCdSync(1);\n        if (gSSReadDone) {\n            gSSRead = 0;\n            gSSReadDone = 0;\n            if (gCdCallback) {\n                gCdCallback(1);\n            }\n        }\n    }\n\n    if (gCommBusy || gLoadBusy) {\n        return 1;\n    }\n\n    return 0;\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/989snd\", snd_GotReturns__Fv);\n#ifdef SKIP_ASM\n// Rodata\nint snd_GotReturns(void)\n{\n    FlushCache(0);\n    if (gCommBusy == NULL) {\n        return 1;\n    }\n\n    if (sceSifCheckStatRpc(&gSLClientData.rpcd)) {\n        return 0;\n    }\n\n    if (*gCommBusy == -1 && (gCommBusy[gAwaitingInts + 1] == -1)) {\n        gCommBusy = NULL;\n        return 1;\n    } else {\n        printf(\"989snd.c: Sif says RPC isn\\'t busy, but we still don\\'t have returns from the  IOP!\\n\");\n        return 0;\n    }\n\n    return 1;\n}\n#endif\n\nvoid snd_PrepareReturnBuffer(u_int* buffer, int num_ints)\n{\n    gAwaitingInts = num_ints;\n    gCommBusy = buffer;\n    buffer[num_ints + 1] = 0;\n    buffer[0] = 0;\n}\n\nJUNK_NOP();\nJUNK_ADDIU(60);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/989snd\", snd_BankLoadByLoc);\n#ifdef SKIP_ASM\nSoundBankPtr snd_BankLoadByLoc(int loc, int offset)\n{\n    gUnkBankLoadError = 0;\n    if (gLoadBusy) {\n        printf(\"snd_BankLoadByLoc: Load already in progress!\\n\");\n        return NULL;\n    }\n\n    if (snd_StreamSafeCdSync(1) == 1) {\n        printf(\"snd_BankLoadByLoc: CD BUSY!\\n\");\n        return NULL;\n    }\n\n    gLoadReturnValue[0] = 0xffffffff;\n    gLoadParams[0] = loc;\n    gLoadParams[1] = offset;\n    while (sceSifCheckStatRpc(&gSLClientLoaderData.rpcd)) {\n        printf(\"989snd.c: RPC collision!\\n\");\n        snd_FlushSoundCommands();\n        FlushCache(0);\n    }\n\n    if (sceSifCallRpc(&gSLClientLoaderData, 3, 1, gLoadParams, 8, gLoadReturnValue, 4, NULL, NULL) < 0) {\n        printf(\"989snd.c: RPC call has failed inside snd_BankLoadByLoc\\n\");\n        gUnkBankLoadError = 0x106;\n        return NULL;\n    }\n\n    while ((SoundBankPtr)gLoadReturnValue[0] == (SoundBankPtr)0xffffffff) {\n        FlushCache(0);\n    }\n\n    return (SoundBankPtr)gLoadReturnValue[0];\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/989snd\", snd_BankLoadByLoc_CB);\n#ifdef SKIP_ASM\nvoid snd_BankLoadByLoc_CB(int loc, int offset, SndCompleteProc cb, u_long u_data)\n{\n    gUnkBankLoadError = 0;\n\n    if (gLoadBusy) {\n        printf(\"snd_BankLoadByLoc: Load already in progress!\\n\");\n        return;\n    }\n\n    if (snd_StreamSafeCdSync(1) == 1) {\n        printf(\"snd_BankLoadByLoc: CD BUSY!\\n\");\n        return;\n    }\n\n    gLoadReturnValue[0] = 0xffffffff;\n    gLoadParams[0] = loc;\n    gLoadParams[1] = offset;\n    gLoadReturnDef.done = cb;\n    gLoadReturnDef.u_data = u_data;\n\n    while (sceSifCheckStatRpc(&gSLClientLoaderData.rpcd)) {\n        printf(\"989snd.c: RPC collision!\\n\");\n        snd_FlushSoundCommands();\n        FlushCache(0);\n    }\n\n    gLoadBusy = 1;\n    sceSifCallRpc(&gSLClientLoaderData, 3, 1, gLoadParams, 8, gLoadReturnValue, 4, NULL, NULL);\n}\n#endif\n\nJUNK_ADDIU(70);\nJUNK_ADDIU(70);\nJUNK_ADDIU(70);\nJUNK_ADDIU(70);\nJUNK_ADDIU(70);\nJUNK_ADDIU(60);\nJUNK_ADDIU(70);\n\nvoid snd_ResolveBankXREFS(void)\n{\n    snd_SendIOPCommandNoWait(8, 0, NULL, NULL, 0);\n}\n\nvoid snd_UnloadBank(SoundBankPtr bank)\n{\n    int data[1];\n\n    data[0] = (int)bank;\n\n    snd_SendIOPCommandNoWait(6, 4, (char*)data, NULL, 0);\n}\n\nvoid snd_SetMasterVolume(int which, int vol)\n{\n    int data[2];\n\n    data[0] = which;\n    data[1] = vol;\n\n    snd_SendIOPCommandNoWait(9, 8, (char*)data, NULL, 0);\n}\n\nint snd_GetMasterVolume(int which)\n{\n    int data[1];\n\n    data[0] = which;\n\n    return snd_SendIOPCommandAndWait(10, 4, (char*)data);\n}\n\nvoid snd_SetPlaybackMode(int mode)\n{\n    int data[1];\n\n    data[0] = mode;\n\n    snd_SendIOPCommandNoWait(0xb, 4, (char*)data, NULL, 0);\n}\n\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\n\nvoid snd_SetMixerMode(int channel_mode, int reverb_mode)\n\n{\n    int data[2];\n\n    data[0] = channel_mode;\n    data[1] = reverb_mode;\n\n    snd_SendIOPCommandNoWait(0xd, 8, (char*)data, NULL, 0);\n}\n\nvoid snd_SetGroupVoiceRange(int group, int min, int max)\n{\n    int data[3];\n\n    data[0] = group;\n    data[1] = min;\n    data[2] = max;\n\n    snd_SendIOPCommandNoWait(0x4e, 0xc, (char*)data, NULL, 0);\n}\n\nu_int snd_PlaySoundVolPanPMPB(SoundBankPtr bank, int sound, int vol, int pan, int pitch_mod, int bend)\n{\n    int data[6];\n\n    data[0] = (int)bank;\n    data[1] = sound;\n    data[2] = vol;\n    data[3] = pan;\n    data[4] = pitch_mod;\n    data[5] = bend;\n\n    return snd_SendIOPCommandAndWait(0x11, 0x18, (char*)data);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(30);\nJUNK_ADDIU(40);\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\n\nvoid snd_StopSound(u_int handle)\n{\n    int data[1];\n\n    data[0] = handle;\n\n    snd_SendIOPCommandNoWait(0x15, 4, (char*)data, NULL, 0);\n}\n\nJUNK_ADDIU(40);\nJUNK_ADDIU(40);\n\nvoid snd_PauseSound(u_int handle)\n{\n    int data[1];\n\n    data[0] = handle;\n\n    snd_SendIOPCommandNoWait(0x13, 4, (char*)data, NULL, 0);\n}\n\nvoid snd_ContinueSound(u_int handle)\n{\n    int data[1];\n\n    data[0] = handle;\n\n    snd_SendIOPCommandNoWait(0x14, 4, (char*)data, NULL, 0);\n}\n\nJUNK_ADDIU(10);\n\nvoid snd_PauseAllSoundsInGroup(u_int groups)\n\n{\n    int data[1];\n\n    data[0] = groups;\n\n    snd_SendIOPCommandNoWait(0x16, 4, (char*)data, NULL, 0);\n}\n\nvoid snd_ContinueAllSoundsInGroup(u_int groups)\n\n{\n    int data[1];\n\n    data[0] = groups;\n\n    snd_SendIOPCommandNoWait(0x17, 4, (char*)data, NULL, 0);\n}\n\nu_int snd_SoundIsStillPlaying(u_int handle)\n{\n    u_int data[1];\n\n    data[0] = handle;\n\n    return snd_SendIOPCommandAndWait(0x19, 4, (char*)data);\n}\n\nvoid snd_SoundIsStillPlaying_CB(u_int handle, SndCompleteProc cb, u_long user_data)\n{\n    int data[1];\n\n    data[0] = handle;\n\n    snd_SendIOPCommandNoWait(0x19, 4, (char*)data, cb, user_data);\n}\n\nint snd_IsSoundALooper(SoundBankPtr bank, u_int sound)\n{\n    int data[2];\n\n    data[0] = (int)bank;\n    data[1] = sound;\n\n    return snd_SendIOPCommandAndWait(0x1a, 8, (char*)data);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\n\nvoid snd_SetSoundVolPan(u_int handle, int vol, int pan)\n{\n    int data[3];\n\n    data[0] = handle;\n    data[1] = vol;\n    data[2] = pan;\n\n    snd_SendIOPCommandNoWait(0x1b, 0xc, (char*)data, NULL, 0);\n}\n\nint snd_GetSoundOriginalPitch(SoundBankPtr bank, int index)\n{\n    int data[2];\n\n    data[0] = (int)bank;\n    data[1] = index;\n\n    return snd_SendIOPCommandAndWait(0x1c, 8, (char*)data);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\n\nvoid snd_SetSoundPitch(u_int handle, int pitch)\n{\n    int data[2];\n\n    data[0] = handle;\n    data[1] = pitch;\n\n    snd_SendIOPCommandNoWait(0x1e, 8, (char*)data, NULL, 0);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\nJUNK_ADDIU(20);\nJUNK_ADDIU(30);\n\nvoid snd_AutoVol(u_int handle, int vol, int delta_time, int delta_from)\n{\n    int data[4];\n\n    data[0] = handle;\n    data[1] = vol;\n    data[2] = delta_time;\n    data[3] = delta_from;\n\n    snd_SendIOPCommandNoWait(0x22, 0x10, (char*)data, NULL, 0);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\nJUNK_ADDIU(20);\n\nvoid snd_SetMIDIRegister(u_int handle, int reg, int value)\n{\n    int data[3];\n\n    data[0] = handle;\n    data[1] = reg;\n    data[2] = value;\n\n    snd_SendIOPCommandNoWait(0x29, 0xc, (char*)data, NULL, 0);\n}\n\nint snd_GetMIDIRegister(u_int handle, int reg)\n{\n    int data[2];\n\n    data[0] = handle;\n    data[1] = reg;\n\n    return snd_SendIOPCommandAndWait(0x28, 8, (char*)data);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\n\nvoid snd_SetGlobalExcite(int value)\n{\n    int data[1];\n\n    data[0] = value;\n\n    snd_SendIOPCommandNoWait(0x27, 4, (char*)data, NULL, 0);\n}\n\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/989snd\", snd_SendIOPCommandAndWait__FiiPc);\n#ifdef SKIP_ASM\nu_int snd_SendIOPCommandAndWait(int command, int data_used, char* in_data)\n{\n    u_int ret_val;\n    int x;\n\n    for (x = 0; x < data_used; x++) {\n        gSyncSendBuffer[x] = in_data[x];\n    }\n\n    while (gCommBusy) {\n        snd_FlushSoundCommands();\n        FlushCache(0);\n    }\n\n    snd_PrepareReturnBuffer(gSyncBuffer, 1);\n    while (sceSifCheckStatRpc(&gSLClientData.rpcd)) {\n        printf(\"989nsd.c: RPC collision!\\n\");\n        snd_FlushSoundCommands();\n        FlushCache(0);\n    }\n\n    if (data_used) {\n        sceSifCallRpc(&gSLClientData, command, 1, gSyncSendBuffer, data_used, gSyncBuffer, 0xc, NULL, NULL);\n    } else {\n        sceSifCallRpc(&gSLClientData, command, 1, NULL, 0, gSyncBuffer, 0xc, NULL, NULL);\n    }\n\n    while (!snd_GotReturns())\n        ;\n\n    ret_val = gSyncBuffer[1];\n\n    if (gSndCommandBuffePtr[gCommandFillBuffer]->num_commands && !gCaching) {\n        snd_SendCurrentBatch();\n    }\n\n    return ret_val;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/989snd\", snd_SendIOPCommandNoWait__FiiPcPFiUl_vUl);\n#ifdef SKIP_ASM\nvoid snd_SendIOPCommandNoWait(int command, int data_used, char* in_data, SndCompleteProc done, u_long u_data)\n{\n    int x, was_caching = 0, y;\n    char* msg;\n    int msg_size;\n\n    if (!gCaching && !gCommBusy && !data_used && !done) {\n        snd_PrepareReturnBuffer(gSyncBuffer, 1);\n\n        while (sceSifCheckStatRpc(&gSLClientData.rpcd)) {\n            printf(\"989snd.c: RPC collision!\\n\");\n            snd_FlushSoundCommands();\n            FlushCache(0);\n        }\n\n        sceSifCallRpc(&gSLClientData, command, 1, NULL, 0, gSyncBuffer, 0xc, NULL, NULL);\n        return;\n    }\n\n    y = 0;\n\n    msg_size = data_used + 4;\n    if (msg_size % 4) {\n        msg_size = ((data_used) - ((msg_size % 4) - 8));\n    }\n\n    while (gSndCommandBuffePtr[gCommandFillBuffer]->num_commands == 256 || gCommandBuffeBytesAvail[gCommandFillBuffer] < msg_size) {\n        if (gCaching != 0) {\n            gCaching = 0;\n            was_caching = 1;\n        }\n        snd_FlushSoundCommands();\n        if (y == 1) {\n            printf(\"snd_SendIOPCommandNoWait: BUFFER %d FULL(%d)! Sound stalled waiting for IOP coma nds to finish!\\n\", gCommandFillBuffer, gSndCommandBuffePtr[gCommandFillBuffer]->num_commands);\n        }\n        y++;\n    }\n\n    if (y) {\n        printf(\"snd_SendIOPCommandNoWait: continueing (%d).\\n\", y);\n    }\n\n    if (was_caching) {\n        gCaching = 1;\n    }\n\n    msg = gSndCommandBuffePtr[gCommandFillBuffer]->buf + 0xffc - gCommandBuffeBytesAvail[gCommandFillBuffer];\n    *((short*)(msg)) = command;\n    msg += 2;\n    *((short*)(msg)) = data_used;\n    msg += 2;\n\n    for (x = 0; x < data_used; x++) {\n        msg[x] = in_data[x];\n    }\n\n    gCommandBuffeBytesAvail[gCommandFillBuffer] -= msg_size;\n    gSndCommandReturnDefPtr[gCommandFillBuffer][gSndCommandBuffePtr[gCommandFillBuffer]->num_commands].done = done;\n    gSndCommandReturnDefPtr[gCommandFillBuffer][gSndCommandBuffePtr[gCommandFillBuffer]->num_commands].u_data = u_data;\n    snd_PostMessage();\n}\n#endif\n\nvoid snd_PostMessage(void)\n{\n    gSndCommandBuffePtr[gCommandFillBuffer]->num_commands = gSndCommandBuffePtr[gCommandFillBuffer]->num_commands + 1;\n    snd_FlushSoundCommands();\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/989snd\", snd_SendCurrentBatch__Fv);\n#ifdef SKIP_ASM\nvoid snd_SendCurrentBatch(void)\n{\n    snd_PrepareReturnBuffer(gReturnValuesPtr[gCommandFillBuffer],\n        gSndCommandBuffePtr[gCommandFillBuffer]->num_commands);\n\n    while (sceSifCheckStatRpc(&gSLClientData.rpcd)) {\n        printf(\"989snd.c: RPC collision!\\n\");\n        FlushCache(0);\n    }\n\n    sceSifCallRpc(&gSLClientData, 0x4d, 1, gSndCommandBuffePtr[gCommandFillBuffer],\n        0x1000 - gCommandBuffeBytesAvail[gCommandFillBuffer],\n        gReturnValuesPtr[gCommandFillBuffer],\n        gSndCommandBuffePtr[gCommandFillBuffer]->num_commands * 4 + 8, NULL, NULL);\n\n    gCommandFillBuffer = gCommandFillBuffer != 1;\n\n    gSndCommandBuffePtr[gCommandFillBuffer]->num_commands = 0;\n    gCommandBuffeBytesAvail[gCommandFillBuffer] = 0xffc;\n}\n#endif\n\nint snd_InitVAGStreamingEx(int num_channels, int buffer_size, unsigned int read_mode, int enable_streamsafe_from_ee)\n{\n    int data[4];\n\n    if (gStreamingInited == 1) {\n        return 0;\n    }\n\n    if (gLoadBusy) {\n        while (snd_FlushSoundCommands())\n            ;\n    }\n\n    snd_StreamSafeCdSync(0);\n    data[0] = num_channels;\n    data[1] = buffer_size;\n    data[2] = read_mode;\n    data[3] = enable_streamsafe_from_ee;\n\n    gStreamingInited = snd_SendIOPCommandAndWait(0x2a, 0x10, (char*)data);\n    return gStreamingInited;\n}\n\nvoid snd_StopAllStreams(void)\n{\n    snd_SendIOPCommandNoWait(0x34, 0, NULL, NULL, 0);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\n\nu_int snd_PlayVAGStreamByLoc(int loc1, int loc2, int offset1, int offset2, int vol, int pan, int vol_group, u_int queue, u_int flags)\n{\n    int data[7];\n\n    data[0] = loc1;\n    data[1] = loc2;\n    data[2] = vol << 0x10 | offset1 & 0xffffU;\n    data[3] = pan << 0x10 | offset2 & 0xffffU;\n    data[4] = vol_group;\n    data[5] = queue;\n    data[6] = flags;\n\n    return snd_SendIOPCommandAndWait(0x2c, 0x1c, (char*)data);\n}\n\nJUNK_ADDIU(30);\n\nvoid snd_ContinueVAGStream(u_int stream)\n{\n    int data[1];\n\n    data[0] = stream;\n\n    snd_SendIOPCommandNoWait(0x2e, 4, (char*)data, NULL, 0);\n}\n\nvoid snd_IsVAGStreamBuffered_CB(u_int stream, SndCompleteProc cb, u_long user_data)\n{\n    u_int data[1];\n\n    data[0] = stream;\n\n    snd_SendIOPCommandNoWait(0x4f, 4, (char*)data, cb, user_data);\n}\n\nint snd_StreamSafeCheckCDIdle(int block_ee_iop)\n{\n    int data[1];\n\n    data[0] = block_ee_iop;\n\n    return snd_SendIOPCommandAndWait(0x36, 4, (char*)data);\n}\n\nint snd_StreamSafeCdRead(u_int lbn, u_int sectors, void* buf, sceCdRMode* mode)\n{\n    int data[3];\n\n    if (gStreamingInited == 0) {\n        return sceCdRead(lbn, sectors, buf, mode);\n    }\n\n    if (snd_StreamSafeCdSync(1) == 1) {\n        return 0;\n    }\n\n    WRITE_ONCE(gStats.cd_busy, 1);\n    WRITE_ONCE(gStats.cd_error, 0);\n\n    data[0] = lbn;\n    data[1] = sectors;\n    data[2] = (int)buf;\n\n    snd_SendIOPCommandNoWait(0x38, 0xc, (char*)data, NULL, 0);\n\n    gSSReadDone = 0;\n    gSSRead = 1;\n\n    return 1;\n}\n\nint snd_StreamSafeCdSync(int mode)\n{\n    if (gStreamingInited == 0) {\n        return sceCdSync(mode);\n    }\n\n    FlushCache(0);\n    gSSReadDone = !READ_ONCE(gStats.cd_busy);\n    if (gSSReadDone != 1) {\n        if (mode == 1) {\n            return 1;\n        }\n\n        while (!gSSReadDone) {\n            snd_FlushSoundCommands();\n            FlushCache(0);\n            gSSReadDone = !READ_ONCE(gStats.cd_busy);\n        }\n    }\n\n    return 0;\n}\n\nint snd_StreamSafeCdBreak(void)\n{\n    if (gStreamingInited == 0) {\n        return sceCdBreak();\n    }\n\n    snd_SendIOPCommandNoWait(0x37, 0, NULL, NULL, 0);\n    return 1;\n}\n\nint snd_StreamSafeCdGetError(void)\n{\n    if (!gStreamingInited) {\n        return sceCdGetError();\n    }\n\n    return ((volatile SndSystemStatus*)&gStats)->cd_error;\n}\n\nvoid snd_SetReverbType(int core, int type)\n{\n    int data[2];\n\n    data[0] = core;\n    data[1] = type;\n\n    snd_SendIOPCommandNoWait(0xe, 8, (char*)data, NULL, 0);\n}\n\nvoid snd_SetReverbDepth(int core, int left, int right)\n{\n    int data[3];\n\n    data[0] = core;\n    data[1] = left;\n    data[2] = right;\n\n    snd_SendIOPCommandNoWait(0xf, 0xc, (char*)data, NULL, 0);\n}\n\nvoid snd_PreAllocReverbWorkArea(int core, int type)\n{\n    int data[2];\n\n    data[0] = core;\n    data[1] = type;\n\n    snd_SendIOPCommandNoWait(0x51, 8, (char*)data, NULL, 0);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\nJUNK_ADDIU(10);\nJUNK_ADDIU(20);\nJUNK_ADDIU(10);\nJUNK_ADDIU(20);\nJUNK_ADDIU(20);\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\n\nint snd_InitMovieSound(int sizeOfIOPBuffer, int volumeLevel, int panCenter, int volumeGroup, int type)\n{\n    int data[5];\n\n    data[0] = sizeOfIOPBuffer;\n    data[1] = volumeLevel;\n    data[2] = panCenter;\n    data[3] = volumeGroup;\n    data[4] = type;\n\n    return snd_SendIOPCommandAndWait(0x3b, 0x14, (char*)data);\n}\n\nvoid snd_ResetMovieSound(void)\n{\n    snd_SendIOPCommandAndWait(0x3d, 0, NULL);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\nJUNK_ADDIU(20);\n\nvoid snd_CloseMovieSound(void)\n{\n    snd_SendIOPCommandAndWait(0x3c, 0, NULL);\n}\n\nvoid snd_StartMovieSound(int iopBuffer, int iopBufferSize, int iopPausePosition, u_int sr, int ch)\n{\n    int data[5];\n\n    data[0] = iopBuffer;\n    data[1] = iopBufferSize;\n    data[2] = iopPausePosition;\n    data[3] = sr;\n    data[4] = ch;\n\n    snd_SendIOPCommandAndWait(0x3e, 0x14, (char*)data);\n}\n\nint snd_GetTransStatus()\n{\n    return snd_SendIOPCommandAndWait(0x40, 0, NULL);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\nJUNK_ADDIU(10);\nJUNK_ADDIU(10);\n\nint snd_GetDopplerPitchMod(int approaching_mph)\n{\n    return (approaching_mph * 0x5f4) / 0x2e5;\n}\n"
  },
  {
    "path": "src/P2/ac.c",
    "content": "#include <ac.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", FindKey__FfiiiPcPfT5PPv);\n\nvoid EvaluateAcp(ACP *pacp, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *ppos, VECTOR *pv)\n{\n    return;\n}\n\nvoid GetAcpTimes(ACP *pacp, int *pct, float **pat)\n{\n    *pct = 0;\n    if (pat)\n    {\n        *pat = NULL;\n    }\n}\n\nvoid EvaluateAcr(ACR *pacr, ALO *palo, float t, float svt, GRFEVAL grfeval, MATRIX3 *pmat, VECTOR *pw)\n{\n    return;\n}\n\nvoid EvaluateAcrEul(ACR *pacr, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *peul, VECTOR *pdeul)\n{\n    return;\n}\n\nvoid GetAcrTimes(ACR *pacr, int *pct, float **pat)\n{\n    *pct = 0;\n    if (pat)\n    {\n        *pat = NULL;\n    }\n}\n\nvoid EvaluateAcs(ACS *pacs, ALO *palo, float t, GRFEVAL grfeval, MATRIX3 *pmat)\n{\n    return;\n}\n\nvoid GetAcsTimes(ACS *pacs, int *pct, float **pat)\n{\n    *pct = 0;\n    if (pat)\n    {\n        *pat = NULL;\n    }\n}\n\nvoid EvaluateAcg(ACG *pacg, ALO *palo, float t, float svt, GRFEVAL grfeval, float *pg, float *pdg)\n{\n    return;\n}\n\nvoid GetAcgTimes(ACG *pacg, int *pct, float **pat)\n{\n    *pct = 0;\n    if (pat)\n    {\n        *pat = NULL;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", LoadAcgbFromBrx__FP4ACGBP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcgb__FP4ACGBP3ALOffiPfT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", GetAcgbTimes__FP4ACGBPiPPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", LoadAcgbwFromBrx__FP5ACGBWP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcgbw__FP5ACGBWP3ALOffiPfT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", GetAcgbwTimes__FP5ACGBWPiPPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcgl__FP4ACGLP3ALOffiPfT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", LoadAcglFromBrx__FP4ACGLP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", GetAcglTimes__FP4ACGLPiPPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateApacg__FPP3ACGP3ALOffiP6VECTORN25);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", LoadApacgFromBrx__FPP3ACGP6VECTORP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", GetApacgTimes__FPP3ACGPiPPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAkvb__FiP3KVBffiP6VECTORT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", LoadAkvbFromBrx__FPiPP3KVBP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", GetAkvbTimes__FiP3KVBPiPPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcpc__FP4ACPCP3ALOffiP6VECTORT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", LoadAcpcFromBrx__FP4ACPCP18CBinaryInputStream);\n\nvoid GetAcpcTimes(ACPC *pacpc, int *pct, float **pat)\n{\n    GetApacgTimes(&STRUCT_OFFSET(pacpc, 0x20, ACG *), pct, pat); // pacpc->apacg\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcpb__FP4ACPBP3ALOffiP6VECTORT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", LoadAcpbFromBrx__FP4ACPBP18CBinaryInputStream);\n\nvoid GetAcpbTimes(ACPB *pacpb, int *pct, float **pat)\n{\n    // pacpb->ckvb, pacpb->akvb\n    GetAkvbTimes(STRUCT_OFFSET(pacpb, 0xc, int), STRUCT_OFFSET(pacpb, 0x10, KVB *), pct, pat);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcrc__FP4ACRCP3ALOffiP7MATRIX3P6VECTOR);\n\nvoid EvaluateAcrcEul(ACRC *pacrc, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *peul, VECTOR *pdeul)\n{\n    // pacrc->apacg, pacrc->eulDefault\n    EvaluateApacg(&STRUCT_OFFSET(pacrc, 0x20, ACG *), palo, t, svt, grfeval, &STRUCT_OFFSET(pacrc, 0x10, VECTOR), peul, pdeul);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", LoadAcrcFromBrx__FP4ACRCP18CBinaryInputStream);\n\nvoid GetAcrcTimes(ACRC *pacrc, int *pct, float **pat)\n{\n    // pacrc->apacg\n    GetApacgTimes(&STRUCT_OFFSET(pacrc, 0x20, ACG *), pct, pat);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcrb__FP4ACRBP3ALOffiP7MATRIX3P6VECTOR);\n\nvoid EvaluateAcrbEul(ACRB *pacrb, ALO *palo, float t, float svt, GRFEVAL grfeval, VECTOR *peul, VECTOR *pdeul)\n{\n    // pacrb->ckvb, pacrb->akvb \n    EvaluateAkvb(STRUCT_OFFSET(pacrb, 0xc, int), STRUCT_OFFSET(pacrb, 0x10, KVB *), t, svt, grfeval, peul, pdeul);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", LoadAcrbFromBrx__FP4ACRBP18CBinaryInputStream);\n\nvoid GetAcrbTimes(ACRB *pacrb, int *pct, float **pat)\n{\n    // pacrb->ckvb, pacrb->akvb\n    GetAkvbTimes(STRUCT_OFFSET(pacrb, 0xc, int), STRUCT_OFFSET(pacrb, 0x10, KVB *), pct, pat);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcsc__FP4ACSCP3ALOfiP7MATRIX3);\n\nvoid LoadAcscFromBrx(ACSC *pacsc, CBinaryInputStream *pbis)\n{\n    // pacsc->apacg, pacsc->vecDefault\n    LoadApacgFromBrx(&STRUCT_OFFSET(pacsc, 0x20, ACG *), &STRUCT_OFFSET(pacsc, 0x10, VECTOR), pbis);\n}\n\nvoid GetAcscTimes(ACSC *pacsc, int *pct, float **pat)\n{\n    // pacsc->apacg\n    GetApacgTimes(&STRUCT_OFFSET(pacsc, 0x20, ACG *), pct, pat);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcsb__FP4ACSBP3ALOfiP7MATRIX3);\n\nvoid LoadAcsbFromBrx(ACSB *pacsb, CBinaryInputStream *pbis)\n{\n    // pacsb->ckvb, pacsb->akvb\n    LoadAkvbFromBrx(&STRUCT_OFFSET(pacsb, 0x08, int), &STRUCT_OFFSET(pacsb, 0x0c, KVB *), pbis);\n}\n\nvoid GetAcsbTimes(ACSB *pacsb, int *pct, float **pat)\n{\n    // pacsb->ckvb, pacsb->akvb \n    GetAkvbTimes(STRUCT_OFFSET(pacsb, 0x08, int), STRUCT_OFFSET(pacsb, 0x0c, KVB *), pct, pat);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcpbl__FP5ACPBLP3ALOffiP6VECTORT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcrbl__FP5ACRBLP3ALOffiP7MATRIX3P6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcgblt__FP6ACGBLTP3ALOffiPfT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", EvaluateAcgblp__FP6ACGBLPP3ALOffiPfT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", PacpNew__F4ACVK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", PacrNew__F4ACVK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", PacsNew__F4ACVK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ac\", PacgNew__F4ACGK);\n"
  },
  {
    "path": "src/P2/act.c",
    "content": "#include <act.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", PactNew__FP2SWP3ALOP5VTACT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", PactNewClone__FP3ACTP2SWP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", CloneAct__FP3ACTT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", InitAct__FP3ACTP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", RetractAct__FP3ACTi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActPositionGoal__FP3ACTfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActRotationGoal__FP3ACTfP7MATRIX3P6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActTwistGoal__FP3ACTPfT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActScale__FP3ACTP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GGetActPoseGoal__FP3ACTi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", CalculateActDefaultAck__FP3ACT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", SnapAct__FP3ACTi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", CalculateAloPositionSpring__FP3ALOfP6VECTORN22);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", ProjectActPosition__FP3ACT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", CalculateAloRotationSpring__FP3ALOfP7MATRIX3P6VECTORT3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", ProjectActRotation__FP3ACT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", ProjectActPose__FP3ACTi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", PredictAloPosition__FP3ALOfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", PredictAloRotation__FP3ALOfP7MATRIX3P6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", AdaptAct__FP3ACT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", InitActval__FP6ACTVALP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActvalPositionGoal__FP6ACTVALfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActvalRotationGoal__FP6ACTVALfP7MATRIX3P6VECTOR);\n\nvoid GetActvalTwistGoal(ACTVAL *pactval, float *pradTwist, float *pdradTwist)\n{\n    *pradTwist = pactval->radTwistGoal;\n    *pdradTwist = pactval->dradTwistGoal;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActvalScale__FP6ACTVALP7MATRIX3);\n\nfloat GGetActvalPoseGoal(ACTVAL *pactval, int ipose)\n{\n    return pactval->agPoses[ipose];\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", InitActref__FP6ACTREFP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActrefPositionGoal__FP6ACTREFfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActrefRotationGoal__FP6ACTREFfP7MATRIX3P6VECTOR);\n\nvoid GetActrefTwistGoal(ACTREF *pactref, float *pradTwist, float *pdradTwist)\n{\n    *pradTwist = *pactref->pradTwistGoal;\n    *pdradTwist = *pactref->pdradTwistGoal;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActrefScale__FP6ACTREFP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GGetActrefPoseGoal__FP6ACTREFi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", InitActadj__FP6ACTADJP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActadjPositionGoal__FP6ACTADJfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActadjRotationGoal__FP6ACTADJfP7MATRIX3P6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActadjTwistGoal__FP6ACTADJPfT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActadjScale__FP6ACTADJP7MATRIX3);\n\nfloat GGetActadjPoseGoal(ACTADJ *pactadj, int ipose)\n{\n    return 0.0f;\n}\n\nvoid InitActbank(ACTBANK *pactbank, ALO *palo)\n{\n    InitAct(pactbank, palo);\n    pactbank->uBank = 1.0f;\n    pactbank->dtPredict = 0.25f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/act\", GetActbankRotationGoal__FP7ACTBANKfP7MATRIX3P6VECTOR);\n"
  },
  {
    "path": "src/P2/actseg.c",
    "content": "#include <actseg.h>\n#include <asega.h>\n\nvoid RetractActseg(ACTSEG *pactseg, GRFRA grfra)\n{\n    ASEGA *pasega = pactseg->pasega;\n    RemoveDlEntry(&pasega->dlActseg, pactseg);\n\n    if (pasega->pactsegError == pactseg)\n    {\n        pasega->pactsegError = NULL;\n    }\n\n    RetractAct(pactseg, grfra);\n}\n\nvoid CloneActseg(ACTSEG *pactseg, ACTSEG *pactsegBase)\n{\n    ASEGA *pasega = pactseg->pasega;\n    DLE dleAsega = pactseg->dleAsega;\n\n    CloneAct(pactseg, pactsegBase);\n\n    pactseg->dleAsega = dleAsega;\n    pactseg->pasega = pasega;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/actseg\", GetActsegPositionGoal__FP6ACTSEGfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/actseg\", GetActsegRotationGoal__FP6ACTSEGfP7MATRIX3P6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/actseg\", GetActsegTwistGoal__FP6ACTSEGPfT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/actseg\", GetActsegScale__FP6ACTSEGP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/actseg\", GGetActsegPoseGoal__FP6ACTSEGi);\n"
  },
  {
    "path": "src/P2/alarm.c",
    "content": "#include <alarm.h>\n#include <chkpnt.h>\n#include <button.h>\n\nvoid BreakAlbrk(ALBRK *palbrk)\n{\n    if (STRUCT_OFFSET(palbrk, 0x680, int) == 0)\n    {\n        DisableAlarmAlbrk(STRUCT_OFFSET(palbrk, 0x6c0, ALARM *)); // palbrk->palarm\n    }\n\n    BreakBrk(palbrk);\n}\n\nvoid SetAlbrkAlarm(ALBRK *palbrk, ALARM *palarm)\n{\n    STRUCT_OFFSET(palbrk, 0x6c0, ALARM *) = palarm; // palbrk->palarm\n}\n\nvoid InitAlarm(ALARM *palarm)\n{\n    InitSo(palarm);\n    STRUCT_OFFSET(palarm, 0x550, ALARMS) = ALARMS_Nil; // palarm->alarms\n    STRUCT_OFFSET(palarm, 0x6b0, int) = IchkAllocChkmgr(&g_chkmgr); // palarm->ichkDisabled\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alarm\", PostAlarmLoad__FP5ALARM);\n\nvoid CloneAlarm(ALARM *palarm, ALARM *palarmBase)\n{\n    int ichkDisabled = STRUCT_OFFSET(palarm, 0x6b0, int); // palarm->ichkDisabled\n    CloneSo(palarm, palarmBase);\n    STRUCT_OFFSET(palarm, 0x6b0, int) = ichkDisabled; // palarm->ichkDisabled\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alarm\", UpdateAlarm__FP5ALARMf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alarm\", PostAlarmLoadCallbackHookup__FP5ALARM5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alarm\", SetAlarmAlarms__FP5ALARM6ALARMS);\n\nvoid TriggerAlarm(ALARM *palarm, ALTK altk)\n{\n    ALARMS alarms;\n\n    switch (altk)\n    {\n        case ALTK_Trigger:\n            alarms = ALARMS_Triggered;\n            break;\n        case ALTK_Untrigger:\n            alarms = ALARMS_Enabled;\n            break;\n        case ALTK_Disable:\n            alarms = ALARMS_Disabled;\n            break;\n        default:\n            return;\n    }\n\n    SetAlarmAlarms(palarm, alarms);\n}\n\nvoid DisableAlarmAlbrk(ALARM *palarm)\n{\n    STRUCT_OFFSET(palarm, 0x61c, int)++; // palarm->calbrksDisabled\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alarm\", EnableAlarmSensors__FP5ALARM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alarm\", DisableAlarmSensors__FP5ALARM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alarm\", NotifyAlarmSensorsOnTrigger__FP5ALARM);\n\nvoid AddAlarmAlbrk(ALARM *palarm, OID oid)\n{\n    uint calbrks = STRUCT_OFFSET(palarm, 0x564, int); // palarm->calbrks\n\n    if (calbrks < 4) // Max 4 breakable alarms\n    {\n        // Add new breakable object ID to the list\n        STRUCT_OFFSET_INDEX(palarm, 0x568, OID, calbrks) = oid; // palarm->aoidAlbrks[calbrks]\n        STRUCT_OFFSET(palarm, 0x564, int) = calbrks + 1;        // palarm->calbrks\n    }\n}\n\nvoid AddAlarmSensor(ALARM *palarm, OID oid)\n{\n    uint coidSensors = STRUCT_OFFSET(palarm, 0x578, int); // palarm->coidSensors\n\n    if (coidSensors < 16) // Max 16 sensors\n    {\n        // Add new sensor object ID to the list\n        STRUCT_OFFSET_INDEX(palarm, 0x57c, OID, coidSensors) = oid; // palarm->aoidSensors[coidSensors]\n        STRUCT_OFFSET(palarm, 0x578, int) = coidSensors + 1; // palarm->coidSensors\n    }\n}\n\nvoid AddAlarmStepguard(ALARM *palarm, OID oid)\n{\n    uint coidStepguards = STRUCT_OFFSET(palarm, 0x600, int); // palarm->coidStepguards\n\n    if (coidStepguards < 6) // Max 6 stepguards\n    {\n        // Add new stepguard object ID to the list\n        STRUCT_OFFSET_INDEX(palarm, 0x604, OID, coidStepguards) = oid; // palarm->aoidStepguards[coidStepguards]\n        STRUCT_OFFSET(palarm, 0x600, int) = coidStepguards + 1; // palarm->coidStepguards\n    }\n}\n\nvoid SetAlarmRsmg(ALARM *palarm, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal)\n{\n    // palarm->arsmg & palarm->crsmg\n    FAddRsmg(&STRUCT_OFFSET(palarm, 0x630, RSMG), 8, &STRUCT_OFFSET(palarm, 0x62c, int), fOnTrigger, oidRoot, oidSM, oidGoal);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alarm\", FGetAlarmSensorList__FP5ALARMPv);\n"
  },
  {
    "path": "src/P2/alo.c",
    "content": "#include <act.h>\n#include <alo.h>\n#include <aseg.h>\n#include <math.h>\n#include <memory.h>\n#include <shadow.h>\n#include <shd.h>\n#include <target.h>\n\nextern VTACT g_vtactseg;\nextern SHADOW s_shadow;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FIsZeroV__FP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FIsZeroW__FP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FIsZeroDv__FP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FIsZeroDw__FP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", InitAlo__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", AddAloHierarchy__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", OnAloAdd__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", RemoveAloHierarchy__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", OnAloRemove__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", UpdateAloOrig__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloParent__FP3ALOT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", ApplyAloProxy__FP3ALOP5PROXY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", BindAlo__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", PostAloLoad__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", PostAloLoadCallback__FP3ALO5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SnipAloObjects__FP3ALOiP4SNIP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", UpdateAloHierarchy__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", UpdateAlo__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", InvalidateAloLighting__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", UpdateAloXfWorld__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", UpdateAloXfWorldHierarchy__FP3ALO);\n\nvoid PresetAloAccel(ALO *palo, float dt)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", ProjectAloTransform__FP3ALOfi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", PredictAloTransform__FP3ALOT0fP6VECTORP7MATRIX3T3T3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", PredictAloTransformAdjust__FP3ALOT0fP6VECTORP7MATRIX3T3T3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", DupAloRo__FP3ALOP2ROT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", RenderFastShadow__FP3ALOP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", RenderAloAll__FP3ALOP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", RenderAloSelf__FP3ALOP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", RenderAloGlobset__FP3ALOP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", RenderAloLine__FP3ALOP2CMP6VECTORT2ff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloOverrideCel__FP3ALOG4RGBA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_00126ab0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", UpdateAloThrob__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloBlotContext__FP3ALOP4BLOT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", EnsureAloFader__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FadeAloIn__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FadeAloOut__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", AdjustAloRtckMat__FP3ALOP2CM4RTCKP6VECTORP7MATRIX4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", CloneAloHierarchy__FP3ALOT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", CloneAlo__FP3ALOT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", HandleAloMessage__FP3ALO5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", TranslateAloToPos__FP3ALOP6VECTOR);\n\nJUNK_ADDIU(20);\nJUNK_ADDIU(20);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", RotateAloToMat__FP3ALOP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloVelocityVec__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloVelocityXYZ__FP3ALOfff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloAngularVelocityVec__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloAngularVelocityXYZ__FP3ALOfff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloVelocityLocal__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloVelocityLocal__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", MatchAloOtherObject__FP3ALOT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", CalculateAloMovement__FP3ALOT0P6VECTORN42);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", CalculateAloTransform__FP3ALOT0iP6VECTORP7MATRIX3T3T3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", CalculateAloTransformAdjust__FP3ALOT0P6VECTORP7MATRIX3T2T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", ConvertAloPos__FP3ALOT0P6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", ConvertAloVec__FP3ALOT0P6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", ConvertAloMat__FP3ALOT0P7MATRIX3T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FDrivenAlo__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", RetractAloDrive__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", ConvertAloMovement__FP3ALOT0P6VECTORN82);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", CalculateAloDrive__FP3ALOP3CLQP2LMffPfN25);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FGetAloChildrenList__FP3ALOPv);\n\nACTSEG *PactsegNewAlo(ALO *palo)\n{\n    return (ACTSEG *)PactNew(palo->psw, palo, &g_vtactseg);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", LoadAloFromBrx__FP3ALOP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", LoadAloAloxFromBrx__FP3ALOP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", BindAloAlox__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", AdjustAloRotation__FP3ALOP7MATRIX3P6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", UnadjustAloRotation__FP3ALOP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloInitialVelocity__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloInitialAngularVelocity__FP3ALOP6VECTOR);\n\nASEGD *PasegdEnsureAlo(ALO *palo)\n{\n    ASEGD *&pasegd = STRUCT_OFFSET(palo, 0x2a0, ASEGD *); // palo->pasegd\n\n    if (!pasegd)\n    {\n        pasegd = (ASEGD *)PvAllocSwClearImpl(sizeof(ASEGD));\n\n        pasegd->oidAseg = OID_Nil;\n        pasegd->iak = IAK_Time;\n        pasegd->tLocal = 0.0f;\n        pasegd->svtLocal = 1.0f;\n    }\n\n    return pasegd;\n}\n\nvoid SetAloFastShadowRadius(ALO *palo, float sRadius)\n{\n    // palo->sFastShadowRadius\n    STRUCT_OFFSET(palo, 0x28c, float) = sRadius * 0.01f;\n}\n\nvoid GetAloFastShadowRadius(ALO *palo, float *psRadius)\n{\n    // palo->sFastShadowRadius\n    *psRadius = STRUCT_OFFSET(palo, 0x28c, float) * 100.0f;\n}\n\nvoid SetAloFastShadowDepth(ALO *palo, float sDepth)\n{\n    // palo->sFastShadowDepth\n    STRUCT_OFFSET(palo, 0x290, float) = sDepth * 0.01f;\n}\n\nvoid GetAloFastShadowDepth(ALO *palo, float *psDepth)\n{\n    // palo->sFastShadowDepth\n    *psDepth = STRUCT_OFFSET(palo, 0x290, float) * 100.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", PshadowAloEnsure__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloCastShadow__FP3ALOi);\n\nvoid SetAloShadowShader(ALO *palo, OID oidShdShadow)\n{\n    SHADOW *pshadow = PshadowAloEnsure(palo);\n    SetShadowShader(pshadow, oidShdShadow);\n}\n\nvoid SetAloShadowNearRadius(ALO *palo, float sNearRadius)\n{\n    SHADOW *pshadow = PshadowAloEnsure(palo);\n    SetShadowNearRadius(pshadow, sNearRadius);\n}\n\nvoid SetAloShadowFarRadius(ALO *palo, float sFarRadius)\n{\n    SHADOW *pshadow = PshadowAloEnsure(palo);\n    SetShadowFarRadius(pshadow, sFarRadius);\n}\n\nvoid SetAloShadowNearCast(ALO *palo, float sNearCast)\n{\n    SHADOW *pshadow = PshadowAloEnsure(palo);\n    SetShadowNearCast(pshadow, sNearCast);\n}\n\nvoid SetAloShadowFarCast(ALO *palo, float sFarCast)\n{\n    SHADOW *pshadow = PshadowAloEnsure(palo);\n    SetShadowFarCast(pshadow, sFarCast);\n}\n\nvoid SetAloShadowConeAngle(ALO *palo, float degConeAngle)\n{\n    SHADOW *pshadow = PshadowAloEnsure(palo);\n    SetShadowConeAngle(pshadow, degConeAngle);\n}\n\nvoid SetAloShadowFrustrumUp(ALO *palo, VECTOR *pvecUp)\n{\n    SHADOW *pshadow = PshadowAloEnsure(palo);\n    SetShadowFrustrumUp(pshadow, pvecUp);\n}\n\nvoid SetAloDynamicShadowObject(ALO *palo, OID oidDysh)\n{\n    SHADOW *pshadow = PshadowAloEnsure(palo);\n    STRUCT_OFFSET(pshadow, 0xb0, OID) = oidDysh; // pshadow->oidDysh\n}\n\nSHADOW *PshadowInferAlo(ALO *palo)\n{\n    // palo->pshadow\n    if (STRUCT_OFFSET(palo, 0x284, SHADOW *))\n    {\n        return STRUCT_OFFSET(palo, 0x284, SHADOW *);\n    }\n\n    InitShadow(&s_shadow);\n    return &s_shadow;\n}\n\nvoid GetAloCastShadow(ALO *palo, int *pfCastShadow)\n{\n    // palo->pshadow\n    *pfCastShadow = (STRUCT_OFFSET(palo, 0x284, SHADOW *) != NULL);\n}\n\nvoid GetAloShadowShader(ALO *palo, OID *poidShdShadow)\n{\n    // palo->pshadow\n    SHADOW *pshadow = STRUCT_OFFSET(palo, 0x284, SHADOW *);\n\n    if (pshadow && pshadow->pshd)\n    {\n        *poidShdShadow = (OID)pshadow->pshd->oid;\n    }\n    else\n    {\n        *poidShdShadow = OID_Nil;\n    }\n}\n\nvoid GetAloShadowNearRadius(ALO *palo, float *psNearRadius)\n{\n    SHADOW *pshadow = PshadowInferAlo(palo);\n    *psNearRadius = pshadow->sNearRadius;\n}\n\nvoid GetAloShadowFarRadius(ALO *palo, float *psFarRadius)\n{\n    SHADOW *pshadow = PshadowInferAlo(palo);\n    *psFarRadius = pshadow->sFarRadius;\n}\n\nvoid GetAloShadowNearCast(ALO *palo, float *psNearCast)\n{\n    SHADOW *pshadow = PshadowInferAlo(palo);\n    *psNearCast = pshadow->sNearCast;\n}\n\nvoid GetAloShadowFarCast(ALO *palo, float *psFarCast)\n{\n    SHADOW *pshadow = PshadowInferAlo(palo);\n    *psFarCast = pshadow->sFarCast;\n}\n\nvoid GetAloShadowConeAngle(ALO *palo, float *pdegConeAngle)\n{\n    const float RAD_TO_DEG = 57.295776f;\n    SHADOW *pshadow = PshadowInferAlo(palo);\n    *pdegConeAngle = atan2f(pshadow->sNearRadius / pshadow->sNearCast, 1.0f) * RAD_TO_DEG * 2.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloShadowFrustrumUp__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloEuler__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloEuler__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", EnsureAloActRestore__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", EnsureAloActla__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", RecacheAloActList__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", InsertAloAct__FP3ALOP3ACT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", ResortAloActList__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", PasegaFindAlo__FP3ALO3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", PsmaFindAlo__FP3ALO3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", PasegaFindAloNearest__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", CreateAloActadj__FP3ALOiPP6ACTADJ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FIsAloStatic__FP3ALO);\n\nvoid ResolveAlo(ALO *palo)\n{\n    if (palo->paloRoot)\n    {\n        STRUCT_OFFSET(palo->paloRoot, 0x228, int) = 0; // palo->paloRoot->cframeStatic\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloPositionSpring__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloPositionSpringDetail__FP3ALOP3CLQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloPositionDamping__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloPositionDampingDetail__FP3ALOP3CLQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRotationSpring__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRotationSpringDetail__FP3ALOP3CLQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRotationDamping__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRotationDampingDetail__FP3ALOP3CLQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloPositionSmooth__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloPositionSmoothMaxAccel__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloPositionSmoothDetail__FP3ALOP4SMPA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRotationSmooth__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRotationSmoothMaxAccel__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRotationSmoothDetail__FP3ALOP4SMPA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloDefaultAckPos__FP3ALO3ACK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloDefaultAckRot__FP3ALO3ACK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRestorePosition__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a3c8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a3e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a418);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRestorePositionAck__FP3ALO3ACK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRestoreRotation__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRestoreRotationAck__FP3ALO3ACK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a4e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloLookAt__FP3ALO3ACK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloLookAtIgnore__FP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloLookAtIgnore__FP3ALOPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloLookAtPanFunction__FP3ALOP3CLQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloLookAtPanFunction__FP3ALOP3CLQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloLookAtPanLimits__FP3ALOP2LM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloLookAtPanLimits__FP3ALOP2LM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloLookAtTiltFunction__FP3ALOP3CLQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloLookAtTiltFunction__FP3ALOP3CLQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloLookAtTiltLimits__FP3ALOP2LM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloLookAtTiltLimits__FP3ALOP2LM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloLookAtEnabledPriority__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloLookAtEnabledPriority__FP3ALOPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloLookAtDisabledPriority__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloLookAtDisabledPriority__FP3ALOPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a810);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a848);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a860);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a888);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a8b8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012a8c8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRotationMatchesVelocity__FP3ALOff3ACK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", PtargetEnsureAlo__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloTargetAttacks__FP3ALOi);\n\nvoid SetAloTargetRadius(ALO *palo, float sRadiusTarget)\n{\n    TARGET *ptarget = PtargetEnsureAlo(palo);\n    STRUCT_OFFSET(ptarget, 0x8c, float) = sRadiusTarget; // ptarget->sRadiusTarget\n}\n\nvoid SetAloTargetHitTest(ALO *palo, int fHitTest)\n{\n    TARGET *ptarget = PtargetEnsureAlo(palo);\n    STRUCT_OFFSET(ptarget, 0x90, int) = fHitTest; // ptarget->fHitTest\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloScrollingMasterSpeeds__FP3ALOff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloEyesClosed__FP3ALOf);\n\nvoid EnsureAloSfx(ALO *palo)\n{\n    // palo->psfx\n    if (!STRUCT_OFFSET(palo, 0x2ac, SFX *))\n    {\n        NewSfx(&STRUCT_OFFSET(palo, 0x2ac, SFX *));\n    }\n}\n\nvoid SetAloSfxid(ALO *palo, SFXID sfxid)\n{\n    EnsureAloSfx(palo);\n    STRUCT_OFFSET(palo, 0x2ac, SFX *)->sfxid = sfxid; // palo->psfx\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloSfxidSpl__FP3ALO5SFXID);\n\nvoid GetAloSfxid(ALO *palo, SFXID *psfxid)\n{\n    SFXID sfxid = SFXID_Nil;\n    if (STRUCT_OFFSET(palo, 0x2ac, SFX *)) // palo->psfx\n    {\n        sfxid = STRUCT_OFFSET(palo, 0x2ac, SFX *)->sfxid;\n    }\n\n    *psfxid = sfxid;\n}\n\nvoid SetAloSStart(ALO *palo, float sStart)\n{\n    EnsureAloSfx(palo);\n    STRUCT_OFFSET(palo, 0x2ac, SFX *)->sStart = sStart; // palo->psfx\n}\n\nvoid GetAloSStart(ALO *palo, float *psStart)\n{\n    float sStart = 3000.0f;\n    if (STRUCT_OFFSET(palo, 0x2ac, SFX *)) // palo->psfx\n    {\n        sStart = STRUCT_OFFSET(palo, 0x2ac, SFX *)->sStart;\n    }\n\n    *psStart = sStart;\n}\n\nvoid SetAloSFull(ALO *palo, float sFull)\n{\n    EnsureAloSfx(palo);\n    STRUCT_OFFSET(palo, 0x2ac, SFX *)->sFull = sFull; // palo->psfx\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloSndRepeat__FP3ALOP2LM);\n\nvoid GetAloSFull(ALO *palo, float *psFull)\n{\n    float sFull = 300.0f;\n    if (STRUCT_OFFSET(palo, 0x2ac, SFX *)) // palo->psfx\n    {\n        sFull = STRUCT_OFFSET(palo, 0x2ac, SFX *)->sFull;\n    }\n\n    *psFull = sFull;\n}\n\nvoid SetAloUVolume(ALO *palo, float uVol)\n{\n    EnsureAloSfx(palo);\n    STRUCT_OFFSET(palo, 0x2ac, SFX *)->uVol = uVol; // palo->psfx\n}\n\nvoid SetAloUDoppler(ALO *palo, float uDoppler)\n{\n    EnsureAloSfx(palo);\n    STRUCT_OFFSET(palo, 0x2ac, SFX *)->uDoppler = uDoppler; // palo->psfx\n}\n\nvoid GetAloUDoppler(ALO *palo, float *puDoppler)\n{\n    float uDoppler = 0.0f;\n    if (STRUCT_OFFSET(palo, 0x2ac, SFX *)) // palo->psfx\n    {\n        uDoppler = STRUCT_OFFSET(palo, 0x2ac, SFX *)->uDoppler;\n    }\n\n    *puDoppler = uDoppler;\n}\n\nvoid SetAloUVolumeSpl(ALO *palo, float uVol)\n{\n    // palo->psfx\n    if (STRUCT_OFFSET(palo, 0x2ac, SFX *) && STRUCT_OFFSET(palo, 0x2ac, SFX *)->pamb)\n    {\n        SetPambVol(STRUCT_OFFSET(palo, 0x2ac, SFX *)->pamb, uVol);\n    }\n}\n\nvoid GetAloUVolume(ALO *palo, float *puVol)\n{\n    float uVol = 1.0f;\n    if (STRUCT_OFFSET(palo, 0x2ac, SFX *)) // palo->psfx\n    {\n        uVol = STRUCT_OFFSET(palo, 0x2ac, SFX *)->uVol;\n    }\n\n    *puVol = uVol;\n}\n\nvoid SetAloUPitch(ALO *palo, float uPitch)\n{\n    EnsureAloSfx(palo);\n    STRUCT_OFFSET(palo, 0x2ac, SFX *)->uPitch = uPitch; // palo->psfx\n}\n\nvoid SetAloUPitchSpl(ALO *palo, float uPitch)\n{\n    // palo->psfx\n    if (STRUCT_OFFSET(palo, 0x2ac, SFX *) && STRUCT_OFFSET(palo, 0x2ac, SFX *)->pamb)\n    {\n        SetPambFrq(STRUCT_OFFSET(palo, 0x2ac, SFX *)->pamb, uPitch);\n    }\n}\n\nvoid GetAloUPitch(ALO *palo, float *puPitch)\n{\n    float uPitch = 0.0f;\n    if (STRUCT_OFFSET(palo, 0x2ac, SFX *)) // palo->psfx\n    {\n        uPitch = STRUCT_OFFSET(palo, 0x2ac, SFX *)->uPitch;\n    }\n\n    *puPitch = uPitch;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloSndRepeat__FP3ALOP2LM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", StartAloSound__FP3ALO5SFXIDfffP2LM);\n\nvoid StopAloSound(ALO *palo)\n{\n    // palo->psfx\n    if (STRUCT_OFFSET(palo, 0x2ac, SFX *))\n    {\n        StopSound(STRUCT_OFFSET(palo, 0x2ac, SFX *)->pamb, 0);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", EnsureAloThrob__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloThrobKind__FP3ALO6THROBK);\n\nvoid GetAloThrobKind(ALO *palo, THROBK *pthrobk)\n{\n    THROBK throbk = THROBK_Nil;\n    if (STRUCT_OFFSET(palo, 0x288, THROB *)) // palo->throb\n    {\n        throbk = STRUCT_OFFSET(palo, 0x288, THROB *)->throbk;\n    }\n\n    *pthrobk = throbk;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloThrobInColor__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloThrobInColor__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloThrobOutColor__FP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloThrobOutColor__FP3ALOP6VECTOR);\n\nvoid SetAloThrobDtInOut(ALO *palo, float dtInOut)\n{\n    EnsureAloThrob(palo);\n    STRUCT_OFFSET(palo, 0x288, THROB *)->dtInOut = dtInOut;\n}\n\nvoid GetAloThrobDtInOut(ALO *palo, float *pdtInOut)\n{\n    float dtInOut = 0.0f;\n    if (STRUCT_OFFSET(palo, 0x288, THROB *)) // palo->throb\n    {\n        dtInOut = STRUCT_OFFSET(palo, 0x288, THROB *)->dtInOut;\n    }\n\n    *pdtInOut = dtInOut;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloInteractCane__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloInteractCane__FP3ALOPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloInteractCaneSweep__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloInteractCaneSweep__FP3ALOPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloInteractCaneRush__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloInteractCaneRush__FP3ALOPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloInteractCaneSmash__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloInteractCaneSmash__FP3ALOPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloInteractBomb__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloInteractBomb__FP3ALOPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloInteractShock__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", GetAloInteractShock__FP3ALOPi);\n\nint FAbsorbAloWkr(ALO *palo, WKR *pwkr)\n{\n    return (pwkr->grfic != 0);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloPoseCombo__FP3ALO3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloForceCameraFade__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", SetAloRealClock__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012b550);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012b590);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012b5b8);\n\nJUNK_ADDIU(10);\nJUNK_WORD(0x7c450000);\nJUNK_WORD(0x48220800);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", FUN_0012b6b8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/alo\", anticrack_itm_firewall);\n"
  },
  {
    "path": "src/P2/aseg.c",
    "content": "#include <aseg.h>\n#include <asega.h>\n\nvoid StartupAseg()\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", InitAseg__FP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", LoadAsegFromBrx__FP4ASEGP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", LoadAsegEventsFromBrx__FP4ASEGP18CBinaryInputStreamiPiPP2EA);\n\nvoid CloneAseg(ASEG *paseg, LO *ploBase)\n{\n    CloneLo(paseg, ploBase);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", PostAsegLoad__FP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", PostAsegLoadCallback__FP4ASEG5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", ApplyAsegOvr__FP4ASEGP3ALOiP3OVRffiPP5ASEGA);\n\nvoid ApplyAseg(ASEG *paseg, ALO *paloAsegRoot, float tLocal, float svtLocal, GRFAPL grfapl, ASEGA **ppasega)\n{\n    ApplyAsegOvr(paseg, paloAsegRoot, 0, NULL, tLocal, svtLocal, grfapl, ppasega);\n}\n\nASEGA *PasegaApplyAseg(ASEG *paseg, ALO *paloAsegRoot, float tLocal, float svtLocal, GRFAPL grfapl)\n{\n    ASEGA *pasega;\n    ApplyAsegOvr(paseg, paloAsegRoot, 0, NULL, tLocal, svtLocal, grfapl, &pasega);\n    return pasega;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", PasegaFindAseg__FP4ASEGP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", EnsureAseg__FP4ASEGP3ALO4SEEKffiPP5ASEGA);\n\nASEGA *PasegaEnsureAseg(ASEG *paseg, ALO *paloRoot, SEEK seek, float t, float svt, GRFAPL grfapl)\n{\n    ASEGA *pasega;\n    EnsureAseg(paseg, paloRoot, seek, t, svt, grfapl, &pasega);\n    return pasega;\n}\n\nvoid ApplyAsegCur(ASEG *paseg, ALO *paloRoot, float t, float svt, GRFAPL grfapl, ASEGA **ppasega)\n{\n    if (*ppasega)\n    {\n        RetractAsega(*ppasega);\n        *ppasega = NULL;\n    }\n    if (paseg)\n    {\n        ApplyAseg(paseg, paloRoot, t, svt, grfapl, ppasega);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", FWipingAseg__FP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", FindAsegClosestPoint__FP4ASEGP3ALOP6VECTORfPfT2T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", PeaFindAsegLabel__FP4ASEG3OID);\n\nfloat TFindAsegLabel(ASEG *paseg, OID oidLabel)\n{\n    EA *pea = PeaFindAsegLabel(paseg, oidLabel);\n    if (pea)\n    {\n        return pea->tLocal;\n    }\n\n    return 0.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", PchnFindAseg__FP4ASEGP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", PredictAsegEffect__FP4ASEGffP3ALOT3iP6VECTORP7MATRIX3T6T6);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", GetAsegWaypoints__FP4ASEGP3ALOPiPPP8WAYPOINT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/aseg\", StripAsegChn__FP4ASEGP3CHN);\n\nvoid StripAsegAlo(ASEG *aseg, ALO *alo)\n{\n    if (aseg->pchnStrip)\n    {\n        return;\n    }\n\n    CHN *chn = PchnFindAseg(aseg, alo);\n    if (chn)\n    {\n        StripAsegChn(aseg, chn);\n    }\n}\n\nvoid LoadAsegblFromBrx(ASEGBL *pasegbl, CBinaryInputStream *pbis)\n{\n    return;\n}\n\nvoid PostAsegblLoad(ASEGBL *pasegbl)\n{\n    return;\n}\n\nvoid CloneAsegbl(ASEGBL *pasegbl, LO *ploBase)\n{\n    return;\n}\n"
  },
  {
    "path": "src/P2/asega.c",
    "content": "#include <asega.h>\n#include <sw.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", PasegaNew__FP2SW);\n\nvoid SetAsegaHandsOff(ASEGA *pasega, int fHandsOff)\n{\n    if (fHandsOff == pasega->fHandsOff)\n        return;\n\n    if (fHandsOff)\n    {\n        IncrementSwHandsOff(g_psw);\n    }\n    else\n    {\n        DecrementSwHandsOff(g_psw);\n    }\n\n    pasega->fHandsOff = fHandsOff;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", UpdateAsegaIeaCur__FP5ASEGA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", PactsegFindAsega__FP5ASEGA3OID);\n\nJUNK_ADDIU(10);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", HandleAsegaEvent__FP5ASEGAP2EAPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", HandleAsegaEventsFF__FP5ASEGAP4ASEGPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", HandleAsegaEvents__FP5ASEGAP4ASEGPi);\n\nvoid RemoveAsega(ASEGA *pasega)\n{\n    RemoveDlEntry(&g_psw->dlAsegaPending, pasega);\n    FreeSlotheapPv(&g_psw->slotheapAsega, pasega);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", RetractAsega__FP5ASEGA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", FUN_0012e928);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", UFromEaErrorFunc__FP2EAf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", FWrapAsegaTime__FP5ASEGAPfT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", UpdateAsega__FP5ASEGAf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", SeekAsega__FP5ASEGA4SEEKff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", SnapAsega__FP5ASEGAi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", AdaptAsega__FP5ASEGA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", FindChnClosestPointLocal__FP3CHNP3ALOP6VECTORfffPfT2T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", SetAsegaSpeed__FP5ASEGAf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", SetAsegaMasterSpeed__FP5ASEGAf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", SetAsegaPriority__FP5ASEGAi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", SendAsegaMessage__FP5ASEGA5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", SubscribeAsegaStruct__FP5ASEGAPFPv5MSGIDPv_vPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/asega\", SubscribeAsegaObject__FP5ASEGAP2LO);\n"
  },
  {
    "path": "src/P2/barrier.c",
    "content": "#include <barrier.h>\n#include <bbmark.h>\n\nvoid InitBarrier(BARRIER *pbarrier)\n{\n    InitSo(pbarrier);\n    SetSoConstraints(pbarrier, CT_Locked, NULL, CT_Locked, NULL);\n    STRUCT_OFFSET(pbarrier, 0x590, OID) = OID_Nil; // pbarrier->barwarp.oidWarp\n}\n\nvoid CloneBarrier(BARRIER *pbarrier, BARRIER *pbarrierBase)\n{\n    CloneSo(pbarrier, pbarrierBase);\n    if (!pbarrier->paloParent)\n    {\n        RecalcSwOxfFilterForObject(pbarrier->psw, pbarrier);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/barrier\", PostBarrierLoad__FP7BARRIER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/barrier\", UpdateBarrier__FP7BARRIERf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/barrier\", FIgnoreBarrierIntersection__FP7BARRIERP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/barrier\", NotifyBarrierImpact__FP7BARRIERP2XPi);\n\nvoid AddBarrierObject(BARRIER *pbarrier, OID oid)\n{\n    int coid = STRUCT_OFFSET(pbarrier, 0x554, int); // pbarrier->coid\n    OID *aoid = &STRUCT_OFFSET(pbarrier, 0x558, OID); // pbarrier->aoid\n    aoid[coid] = oid;\n    STRUCT_OFFSET(pbarrier, 0x554, int) = coid + 1; // pbarrier->coid\n}\n\nvoid AddBarrierClass(BARRIER *pbarrier, CID cid)\n{\n    int ccid = STRUCT_OFFSET(pbarrier, 0x568, int); // pbarrier->ccid\n    CID *acid = &STRUCT_OFFSET(pbarrier, 0x56c, CID); // pbarrier->acid\n    acid[ccid] = cid;\n    STRUCT_OFFSET(pbarrier, 0x568, int) = ccid + 1; // pbarrier->ccid\n}\n"
  },
  {
    "path": "src/P2/bas.c",
    "content": "#include <bas.h>\n#include <cd.h>\n#include <sdk/libcdvd.h>\n#include <lib/libkernl/filestub.h>\n\nCBinaryAsyncStream::CBinaryAsyncStream(void *pvSpool)\n{\n    m_isector = 0;\n    m_abSpool = (byte *)(((int)pvSpool + 0x3f) & ~0x3f);\n    m_fd = -1;\n    m_pbSpooling = NULL;\n    m_pb = NULL;\n    m_cbFile = 0;\n    m_cbUnspooled = 0;\n    m_cbSpooling = 0;\n    m_ibCur = 0;\n    m_cb = 0;\n}\n\nCBinaryAsyncStream::~CBinaryAsyncStream()\n{\n    Close();\n}\n\nbool CBinaryAsyncStream::FOpenFile(CFileLocation *pfl)\n{\n    return FOpenSector(pfl->m_fcl.isector, pfl->m_fcl.cb);\n}\n\nJUNK_ADDIU(30);\n\nbool CBinaryAsyncStream::FOpenSector(uint isector, uint cb)\n{\n    m_isector = isector;\n    m_cbFile = cb;\n    m_cbUnspooled = cb;\n    m_bask = BASK_Cd;\n    m_cb = 0;\n    m_pb = m_abSpool;\n    m_ibCur = 0;\n    StartSpooling();\n    return true;\n}\n\nvoid CBinaryAsyncStream::Close()\n{\n    switch (m_bask)\n    {\n        case BASK_Host:\n        {\n            if (m_fd > -1)\n            {\n                sceClose(m_fd);\n            }\n            m_fd = -1;\n            break;\n        }\n        case BASK_Cd:\n        {\n            if (FSpooling())\n            {\n                sceCdSync(0);\n                FinishSpooling();\n            }\n            m_isector = 0;\n            break;\n        }\n    }\n\n    m_bask = BASK_Nil;\n}\n\nvoid CBinaryAsyncStream::StartSpooling()\n{\n    if (FSpooling() || m_cbUnspooled == 0)\n        return;\n\n    int cb = 0x4000;\n    if (m_cbUnspooled < cb)\n    {\n        cb = m_cbUnspooled;\n    }\n\n    byte *pv = m_abSpool;\n    if (m_pb == pv)\n    {\n        pv += 0x4000;\n    }\n\n    m_pbSpooling = pv;\n    m_cbSpooling = cb;\n\n    switch (m_bask)\n    {\n        case BASK_Host:\n        {\n            sceRead(m_fd, pv, cb);\n            break;\n        }\n        case BASK_Cd:\n        {\n            ReadCdDirect(m_isector, (m_cbSpooling + 0x7ffu) >> 0x0b, pv);\n            break;\n        }\n    }\n}\n\nbool CBinaryAsyncStream::FSpooling()\n{\n    return m_cbSpooling != 0;\n}\n\nbool CBinaryAsyncStream::FSpoolingComplete()\n{\n    int status = 0;\n    bool fComplete = false;\n\n    if (m_cb == m_ibCur && FSpooling())\n    {\n        switch (m_bask)\n        {\n            case BASK_Host:\n            {\n                int fExecuting;\n                status = sceIoctl(m_fd, 1, &fExecuting);\n                fComplete = (fExecuting == 0);\n                break;\n            }\n            case BASK_Cd:\n            {\n                fComplete = (sceCdSync(1) == 0);\n                if (fComplete)\n                {\n                    status = sceCdGetError();\n                }\n                break;\n            }\n        }\n    }\n\n    if (status)\n    {\n        m_cbSpooling = 0;\n        m_pbSpooling = 0;\n        fComplete = false;\n    }\n\n    return fComplete;\n}\n\nvoid CBinaryAsyncStream::FinishSpooling()\n{\n    if (!FSpoolingComplete())\n        return;\n\n    if (m_bask == BASK_Cd)\n    {\n        int n;\n        if (m_cbSpooling <= -1)\n        {\n            n = m_cbSpooling + 0x7ffu;\n        }\n        else\n        {\n            n = m_cbSpooling;\n        }\n\n        m_isector += n >> 0x0b;\n    }\n\n    m_cbUnspooled -= m_cbSpooling;\n    m_pb = m_pbSpooling;\n    m_cb = m_cbSpooling;\n\n    m_cbSpooling = 0;\n    m_pbSpooling = 0;\n    m_ibCur = 0;\n}\n\nvoid CBinaryAsyncStream::Spool()\n{\n    switch (m_bask)\n    {\n        case BASK_Host:\n        {\n            StartSpooling();\n            FinishSpooling();\n            break;\n        }\n        case BASK_Cd:\n        {\n            FinishSpooling();\n            StartSpooling();\n            break;\n        }\n    }\n}\n\nvoid CBinaryAsyncStream::Skip(int cb)\n{\n    m_ibCur += cb;\n}\n"
  },
  {
    "path": "src/P2/basic.c",
    "content": "#include <basic.h>\n#include <splice/gc.h>\n#include <splice/sidebag.h>\n\nextern CGc g_gc;\n\nint FIsBasicDerivedFrom(BASIC *pbasic, CID cid)\n{\n    VT *vt = (VT *)pbasic->pvtbasic;\n    while (vt)\n    {\n        if (vt->cid == cid) return 1;\n        vt = vt->pvtSuper;\n    }\n\n    return 0;\n}\n\nvoid EnsureBasicSidebag(BASIC *pbasic)\n{\n    if (!pbasic->psidebag)\n    {\n        CSidebag *psidebag = PsidebagNew();\n        pbasic->psidebag = psidebag;\n        g_gc.AddRootSidebag(psidebag);\n    }\n}\n\nvoid GetBasicCid(BASIC *pbasic, CID* pcid)\n{\n    *pcid = pbasic->pvtbasic->cid;\n}\n"
  },
  {
    "path": "src/P2/bbmark.c",
    "content": "#include <bbmark.h>\n#include <slotheap.h>\n#include <sw.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bbmark\", UpdateSwPox__FP2SWP3OXAT1UcUc);\n\nOX *PoxAddSw(SW *psw, OXA *poxa, OXA *poxaOther)\n{\n    OX *pox = (OX *)PvAllocSlotheapImpl(&psw->slotheapOx);\n    pox->pxp = NULL;\n    pox->psoOther = poxaOther->pso;\n    pox->poxNext = poxa->pox;\n    poxa->pox = pox;\n    return pox;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bbmark\", PoxRemoveSw__FP2SWP3OXAT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bbmark\", PoxFromSoSo__FP2SOT0);\n\nXP *PxpFirstFromSoSo(SO *pso, SO *psoOther)\n{\n    OX *pox = PoxFromSoSo(pso, psoOther);\n    return pox ? pox->pxp : NULL;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bbmark\", AddSwAaobrObject__FP2SWP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bbmark\", RemoveSwAaobrObject__FP2SWP2SO);\n\nvoid InvalidateSwAaox(SW *psw)\n{\n    psw->fAaoxValid = 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bbmark\", UpdateSwAaox__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bbmark\", InvalidateSwXpForObject__FP2SWP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bbmark\", RecalcSwXpAll__FP2SWi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bbmark\", RecalcSwOxfFilterForObject__FP2SWP2SO);\n"
  },
  {
    "path": "src/P2/bez.c",
    "content": "#include <bez.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bez\", EvaluateBezierWeightedFloat__FfffffffffPfN29);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bez\", EvaluateBezierFloat__FfffffffPfN27);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bez\", EvaluateBezierPos__FfffP6VECTORN63);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bez\", EvaluateBezierMat__FfffP7MATRIX3P6VECTORT3T4T3T4T4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bez\", TesselateBezier__FfffP6VECTORN33iT3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bez\", SBezierPosLength__FffP6VECTORN32);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bez\", LimitBezierMulti__Fie);\n"
  },
  {
    "path": "src/P2/binoc.c",
    "content": "#include <binoc.h>\n#include <alo.h>\n#include <clock.h>\n#include <font.h>\n\nvoid InitBei(BEI *pbei, CLQ *pclq, float duWidth, float dgHeight, int cseg)\n{\n    // Copy CLQ\n    *(qword *)&pbei->clq = *(qword *)pclq;\n\n    pbei->cseg = cseg;\n\n    // Calculate segment count of half the notch\n    float duSegWidth = 1.0f / cseg;\n    float csegNotchWidth = duWidth / duSegWidth;\n    int csegNotchHalf = (int)csegNotchWidth >> 1; // Simplifies to duWidth * cseg / 2\n\n    pbei->csegNotchHalf = csegNotchHalf;\n\n    // Calculate notch segment indices\n    pbei->isegNotchMid = cseg / 2;\n    pbei->isegNotchFirst = pbei->isegNotchMid - csegNotchHalf;\n    pbei->isegNotchLast = pbei->isegNotchMid + csegNotchHalf;\n\n    // Evaluate curve at notch edges and center\n    pbei->gNotchEdge = GEvaluateClq(pclq, pbei->isegNotchFirst / pbei->cseg);\n    pbei->gNotchCenter = GEvaluateClq(pclq, 0.5f) + dgHeight;\n}\n\nfloat GEvaluateBei(BEI *pbei, int iseg)\n{\n    // A more idiomatic structure would check if inside the notch first\n    // and use the CLQ evaluation as the default return value.\n\n    // Outside notch region\n    if (iseg < pbei->isegNotchFirst || iseg > pbei->isegNotchLast)\n    {\n        // Evaluate quadratic curve\n        float t = iseg / pbei->cseg;\n        return GEvaluateClq(&pbei->clq, t);\n    }\n\n    // Notch edges\n    if (iseg == pbei->isegNotchFirst || iseg == pbei->isegNotchLast)\n    {\n        // Return edge height\n        return pbei->gNotchEdge;\n    }\n\n    // Left side of notch\n    if (iseg < pbei->isegNotchMid)\n    {\n        // Interpolate between edge and center\n        float t = (iseg - pbei->isegNotchFirst) / pbei->csegNotchHalf;\n        return GLerp(pbei->gNotchEdge, pbei->gNotchCenter, t);\n    }\n\n    // Right side of notch\n    if (iseg > pbei->isegNotchMid)\n    {\n        // Interpolate between center and edge\n        float t = (iseg - pbei->isegNotchMid) / pbei->csegNotchHalf;\n        return GLerp(pbei->gNotchCenter, pbei->gNotchEdge, t);\n    }\n\n    return pbei->gNotchCenter;\n}\n\nvoid InitBinoc(BINOC *binoc, BLOTK blotk)\n{\n    binoc->width = 640.0f;\n    binoc->height = 492.80001f;\n    binoc->unk0 = 15.0f;\n    binoc->unk1 = 0x80ffffff;\n    InitBlot(binoc, blotk);\n}\n\nvoid ResetBinoc(BINOC *binoc)\n{\n    binoc->pvtbinoc->pfnSetBinocAchzDraw(binoc, 0);\n    SetBinocLookat(binoc, NULL);\n    binoc->dxReticle = 0.0f;\n    binoc->dyReticle = 0.0f;\n    binoc->uCompassBarOffset = 0.4f;\n    binoc->zoom = 0.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", PostBinocLoad__FP5BINOC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", DrawBinocCompass);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", DrawBinocZoom);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", DrawBinocReticle);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", DrawBinocOutline);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00134aa0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00134b48);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", DrawBinocFilter);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00135550);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", open_close_binoc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_001357f0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00135858);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_001358d0);\n\nJUNK_ADDIU(30);\nJUNK_WORD(0xE4C00000);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00135E30);\n\nJUNK_ADDIU(A0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00135E48);\n\nJUNK_ADDIU(10);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", SetBinocBfk);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00135f48);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00136040);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00136238);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_001363d0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", SetBinocAchzDraw);\n\nbool FDoneBinocAchz(BINOC *pbinoc)\n{\n    if (pbinoc->achzDraw[0] == '\\0')\n    {\n        return true;\n    }\n\n    CRichText rt(pbinoc->achzDraw, pbinoc->pfont);\n    int cchTotal = rt.Cch();\n\n    float tAchzDraw = g_clock.t - STRUCT_OFFSET(pbinoc, 0x268, float); // pbinoc->tAchzSet\n    int cchDrawn = (int)(tAchzDraw * STRUCT_OFFSET(pbinoc, 0x2F0, float)); // pbinoc->svch\n\n    return cchDrawn >= cchTotal;\n}\n\nvoid SetBinocLookat(BINOC *binoc, ALO *paloLookat)\n{\n    binoc->paloLookat = paloLookat;\n}\n\nvoid SetBinocZoom(BINOC *binoc, float zoom)\n{\n    float cappedZoom = zoom * 0.01f;\n    float one = 1.0f;\n    float zero = 0.0f;\n    if (cappedZoom < zero)\n    {\n        cappedZoom = zero;\n    }\n    else if (cappedZoom > one)\n    {\n        cappedZoom = one;\n    }\n    binoc->zoom = cappedZoom;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_001365f0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00136648);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", DrawBinoc);\n\nvoid GetBinocReticleFocus(BINOC *binoc, float *dxReticle, float *dyReticle)\n{\n    *dxReticle = binoc->dxReticle + 320.0f;\n    *dyReticle = binoc->dyReticle + 180.40001f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00136ef8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", FUN_00136fa8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", binoc__static_initialization_and_destruction_0);\n\nvoid CTextBox::SetPos(float x, float y)\n{\n    m_x = x;\n    m_y = y;\n}\n\nvoid CTextBox::SetSize(float dx, float dy)\n{\n    m_dx = dx;\n    m_dy = dy;\n}\n\nvoid CTextBox::SetTextColor(RGBA *rgba)\n{\n    this->m_rgba = *rgba;\n}\n\nvoid CTextBox::SetHorizontalJust(JH jh)\n{\n    m_jh = jh;\n}\n\nvoid CTextBox::SetVerticalJust(JV jv)\n{\n    m_jv = jv;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/binoc\", _GLOBAL_$I$InitBei__FP3BEIP3CLQffi);\n"
  },
  {
    "path": "src/P2/bis.c",
    "content": "#include <bis.h>\n#include <memory.h>\n#include <989snd.h>\n#include <sdk/libcdvd.h>\n#include <lib/libkernl/filestub.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bis\", __18CBinaryInputStreamPvii);\n#ifdef SKIP_ASM\n/**\n * @todo 92.85% match. Class fields might be incorrect,\n * but they seem to be used correctly elsewhere?\n * https://decomp.me/scratch/CpeOx\n */\nCBinaryInputStream::CBinaryInputStream(void *pvSpool, int cbSpool, GRFBIS grfbis)\n{\n    int aligned = (cbSpool + 0x3f) & ~0x3f;\n    int padding = (aligned - cbSpool);\n\n    m_bisk = BISK_Nil;\n    m_grfbis = grfbis;\n\n    m_abSpool = (byte *)pvSpool - padding;\n    m_cbSpool = aligned;\n\n    // m_pbRaw = 0;\n    m_pb = 0;\n    m_cbRaw = 0;\n    m_cb = 0;\n    m_pprog = 0;\n    m_grfDecomp = 0;\n    m_cbSpillOver = 0;\n    m_cbFile = 0;\n}\n#endif\n\nCBinaryInputStream::~CBinaryInputStream()\n{\n    Close();\n}\n\nint CBinaryInputStream::FOpenSector(uint isector, uint cb)\n{\n    m_bisk = BISK_Cd;\n    m_cbAsyncRequest = isector;\n    m_cbFile = cb;\n    m_cbRemaining = cb;\n    m_fd = cb;\n    m_pbRaw = m_abSpool;\n    *(uint *)&m_tickWait = 0;\n    m_cbAsyncComplete = 0;\n    *(uint *)((int)&m_tickWait + 4) = 0;\n\n    int cbSpool = m_cbSpool;\n    if (cbSpool < 0)\n    {\n        cbSpool += 0xfffff;\n    }\n\n    m_cbPartialRead = 0;\n\n    int cbAsyncRemaining = 2;\n    int shr = 20;\n    if ((cbSpool >> shr) > cbAsyncRemaining)\n    {\n        cbAsyncRemaining = cbSpool >> shr;\n    }\n\n    m_isector = 0;\n    m_cbAsyncRemaining = cbAsyncRemaining;\n    m_cbuf = cbAsyncRemaining - 1;\n\n    return 1;\n}\n\nvoid CBinaryInputStream::OpenMemory(int cb, void *pv)\n{\n    m_bisk = BISK_Mem;\n    m_pb = (byte *)pv;\n    m_cb = cb;\n}\n\nint CBinaryInputStream::FOpenFile(CFileLocation *pfl)\n{\n    return FOpenSector(pfl->m_fcl.isector, pfl->m_fcl.cb);\n}\n\nvoid CBinaryInputStream::Close()\n{\n    switch (m_bisk)\n    {\n        case BISK_Host:\n        {\n            // NOTE: This is m_fd if m_tickWait is removed.\n            if (*(int *)((uchar *)&m_tickWait - 0x4) >= 0)\n                sceClose(*(int *)((uchar *)&m_tickWait - 0x4));\n            break;\n        }\n        case BISK_Cd:\n        {\n            // NOTE: This is m_cbAsyncComplete if m_tickWait is removed.\n            if (STRUCT_OFFSET(this, 0x3c, int))\n            {\n                if (m_grfbis & 0x2)\n                {\n                    sceCdBreak();\n                }\n                else\n                {\n                    snd_StreamSafeCdBreak();\n                }\n            }\n            break;\n        }\n    }\n\n    m_bisk = BISK_Nil;\n    m_pbRaw = 0;\n    m_pb = 0;\n    m_cbRaw = 0;\n    m_cb = 0;\n    m_grfDecomp = 0;\n    m_cbSpillOver = 0;\n}\n\nvoid CBinaryInputStream::DecrementCdReadLimit(int cb)\n{\n    m_fd -= cb;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bis\", PumpCd__18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bis\", PumpHost__18CBinaryInputStream);\n\nvoid CBinaryInputStream::Pump()\n{\n    switch (m_bisk)\n    {\n        case BISK_Host:\n            PumpHost();\n            break;\n        case BISK_Cd:\n            PumpCd();\n            break;\n        default:\n            break;\n    }\n\n    // TODO: This code matches perfectly, but it could look much better.\n    int iVar1 = m_cbRemaining - STRUCT_OFFSET(this, 0x24, int);\n    int zero = 0;\n    int remain = (iVar1 > zero) ? iVar1 : 0;\n\n    m_cbRemaining = remain;\n\n    if (m_pprog)\n    {\n        m_pprog->SetRemain(remain);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bis\", Decompress__18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bis\", Read__18CBinaryInputStreamiPv);\n#ifdef SKIP_ASM\n/**\n * @brief Reads a certain number of bytes from the stream.\n *\n * @param cb Count of bytes to read.\n * @param pv Pointer to the memory destination.\n *\n * @todo  74.27% matched\n */\nvoid CBinaryInputStream::Read(int cb, void *pv)\n{\n    uint uVar1;\n    uint cb_00;\n\n    if ((-1 < m_cb) && (0 < cb)) {\n        for (int i = 0; i < cb; i++)\n        {\n            uVar1 = m_cb;\n            if (uVar1 == 0) {\n                if ((m_grfbis & 4U) == 0) {\n                    Decompress();\n                    Pump();\n                    m_cb = m_cbRaw;\n                    m_pb = m_pbRaw;\n                    m_pbRaw = m_pbRaw + m_cbRaw;\n                    m_cbRaw = 0;\n                    uVar1 = m_cb;\n                }\n                else {\n                    uVar1 = m_cb;\n                }\n                if (uVar1 == 0) {\n                    m_cb = -1;\n                    return;\n                }\n            }\n            cb_00 = cb;\n            if ((int)uVar1 <= cb) {\n                cb_00 = uVar1;\n            }\n            if (pv != NULL) {\n                byte* pb = reinterpret_cast<byte*>(pv);\n                CopyAb(pb, m_pb, cb_00);\n                pv = reinterpret_cast<void*>(pb + cb_00);\n            }\n\n            m_pb = m_pb + cb_00;\n            m_cb = m_cb - cb_00;\n        }\n    }\n}\n#endif\n\nvoid CBinaryInputStream::Align(int n)\n{\n    int pbAligned = ((int)m_pb + (n - 1)) & -n;\n    m_cb -= (pbAligned - (int)m_pb);\n    m_pb = (byte *)pbAligned;\n}\n\nuchar CBinaryInputStream::U8Read()\n{\n    if (m_cb >= 1)\n    {\n        uchar b = *m_pb;\n        m_pb++;\n        m_cb--;\n        return b;\n    }\n\n    uchar b;\n    Read(sizeof(uchar), &b);\n    return b;\n}\n\nushort CBinaryInputStream::U16Read()\n{\n    if (m_cb >= 2)\n    {\n        ushort u = m_pb[0];\n        ushort v = m_pb[1];\n        m_pb += 2;\n        m_cb -= 2;\n        return (v << 8) | u;\n    }\n\n    ushort v;\n    Read(sizeof(ushort), &v);\n    return v;\n}\n\nuint CBinaryInputStream::U32Read()\n{\n    if (m_cb >= 4)\n    {\n        uint u = m_pb[0];\n        uint v = m_pb[1];\n        uint w = m_pb[2];\n        uint x = m_pb[3];\n        m_pb += 4;\n        m_cb -= 4;\n        return u + (v * 0x100) + (w * 0x10000) + (x * 0x1000000);\n    }\n\n    uint v;\n    Read(sizeof(uint), &v);\n    return v;\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\n\nchar CBinaryInputStream::S8Read()\n{\n    if (m_cb >= 1)\n    {\n        char b = *m_pb;\n        m_pb += 1;\n        m_cb -= 1;\n        return b;\n    }\n\n    char b;\n    Read(sizeof(char), &b);\n    return b;\n}\n\nshort CBinaryInputStream::S16Read()\n{\n    if (m_cb >= 2)\n    {\n        short v = m_pb[1] << 8;\n        v |= m_pb[0];\n        m_pb += 2;\n        m_cb -= 2;\n        return v;\n    }\n\n    short v;\n    Read(sizeof(short), &v);\n    return v;\n}\n\nint CBinaryInputStream::S32Read()\n{\n    if (m_cb >= 4)\n    {\n        int u = m_pb[0];\n        int v = m_pb[1];\n        int w = m_pb[2];\n        char x = m_pb[3];\n        m_pb += 4;\n        m_cb -= 4;\n        return u + (v << 8) + (w << 16) + (x << 24);\n    }\n\n    int v;\n    Read(sizeof(int), &v);\n    return v;\n}\n\nJUNK_NOP();\nJUNK_ADDIU(20);\n\nfloat CBinaryInputStream::F32Read()\n{\n    if (m_cb >= 4)\n    {\n        int g = (m_pb[0] + (m_pb[1] << 8) + (m_pb[2] << 16) + (m_pb[3] << 24));\n        m_pb += 4;\n        m_cb -= 4;\n        return *(float *)&g;\n    }\n\n    float g;\n    Read(sizeof(float), &g);\n    return g;\n}\n\nvoid CBinaryInputStream::ReadVector(VECTOR *pvec)\n{\n    Read(sizeof(VECTOR), pvec);\n}\n\nvoid CBinaryInputStream::ReadVector4(VECTOR4 *pvec)\n{\n    Read(sizeof(VECTOR4), pvec);\n}\n\nvoid CBinaryInputStream::ReadMatrix(MATRIX3 *pmat)\n{\n    int size = sizeof(pmat->mat[0]);\n    Read(size, &pmat->mat[0]);\n    Read(size, &pmat->mat[1][1]);\n    Read(size, &pmat->mat[2][2]);\n}\n\nvoid CBinaryInputStream::ReadMatrix4(MATRIX4 *pmat)\n{\n    // TODO: This might be possible to clean up, but I wasn't able to.\n    // The compiler seems to insist that must we have pointer to each row. -545u\n    float *row0 = &pmat->mat[0][0];\n    float *row1 = &pmat->mat[1][0];\n    float *row2 = &pmat->mat[2][0];\n    float *row3 = &pmat->mat[3][0];\n\n    const int cbRow = sizeof(float) * 3;\n    Read(cbRow, row0);\n    Read(cbRow, row1);\n    Read(cbRow, row2);\n    Read(cbRow, row3);\n\n    row0[3] = 0.0f;\n    row1[3] = 0.0f;\n    row2[3] = 0.0f;\n    row3[3] = 1.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bis\", ReadGeom__18CBinaryInputStreamP4GEOM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bis\", ReadBspc__18CBinaryInputStreamP4GEOMP4BSPC);\n\nvoid CBinaryInputStream::ReadVbsp(int *pcvbsp, VBSP **pavbsp)\n{\n    *pcvbsp = U16Read();\n    *pavbsp = (VBSP *)PvAllocSwClearImpl(*pcvbsp * sizeof(VBSP));\n\n    for (int i = 0; i < *pcvbsp; i++)\n    {\n        VBSP *pvbsp = *pavbsp + i;\n\n        ReadVector(&pvbsp->normal);\n        pvbsp->gDot = F32Read();\n\n        uint negIndex = U32Read();\n        if (negIndex & 0x80000000)\n        {\n            pvbsp->pvbspNeg = (VBSP *)negIndex;\n        }\n        else\n        {\n            pvbsp->pvbspNeg = *pavbsp + negIndex;\n        }\n\n        uint posIndex = U32Read();\n        if (posIndex & 0x80000000)\n        {\n            pvbsp->pvbspPos = (VBSP *)posIndex;\n        }\n        else\n        {\n            pvbsp->pvbspPos = *pavbsp + posIndex;\n        }\n    }\n}\n\nvoid CBinaryInputStream::ReadStringSw(char **pachz)\n{\n    ushort length = U16Read();\n    char *buffer = (char *)PvAllocSwImpl((int)length + 1);\n    Read((int)length, buffer);\n    buffer[length] = 0;\n    *pachz = buffer;\n}\n\nJUNK_NOP();\nJUNK_ADDIU(50);\n\nvoid CBinaryInputStream::Unknown1()\n{\n    ushort size = U16Read();\n    Read(size, NULL);\n}\n\nvoid CBinaryInputStream::Unknown2(void **ppv)\n{\n    uint data[8];\n    Read(0x20, &data);\n\n    if (data[1] != data[7])\n    {\n        *ppv = PvAllocSwCopyImpl(0x20, data);\n        return;\n    }\n\n    *ppv = NULL;\n}\n"
  },
  {
    "path": "src/P2/blend.c",
    "content": "#include <aseg.h>\n#include <blend.h>\n\n// 96% Match\nINCLUDE_ASM(\"asm/nonmatchings/P2/blend\", VerifyAeaEquivalence__FiP2EAiT1);\n#ifdef SKIP_ASM\nvoid VerifyAeaEquivalence(int cea0, EA *aea0, int cea1, EA *aea1)\n{\n    int fLess = (cea0 < cea1);\n    int ceaMin = cea0;\n\n    if (cea0 >= cea1)\n    {\n        ceaMin = cea1;\n    }\n\n    int i;\n\n    if (0 < ceaMin)\n    {\n        if (fLess)\n        {\n            i = cea0;\n        }\n        else\n        {\n            i = cea1;\n        }\n\n        do\n        {\n            i--;\n        } while (i != 0);\n    }\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blend\", EnsureAsegBlendDynamic__FP3ALOiiPviPiT5PP6ASEGBL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blend\", FillBlAmrsg__FiiPviiP3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blend\", CalculateBlendAmrsg__FiiPviiP4MRSGPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blend\", ImrsgLookUp__FffiP4MRSGPf);\n\nJUNK_ADDIU(90);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blend\", ReblendAsegbl__FP6ASEGBLiiPv);\n\nvoid SetAsegblSlerp(ASEGBL *pasegbl, ALO *palo)\n{\n    CHN *pchn = PchnFindAseg(pasegbl, palo);\n    if (!pchn)\n        return;\n    if (!STRUCT_OFFSET(pchn, 0x8, void *))\n        return;\n    STRUCT_OFFSET(STRUCT_OFFSET(pchn, 0x8, void *), 0x18, int) = 1;\n}\n"
  },
  {
    "path": "src/P2/blip.c",
    "content": "#include <blip.h>\n\nextern QW *g_aqwBlipeGifsNormal;\nextern QW *g_aqwBlipeGifsClampedAdd;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", BuildBlipAqwGifs__FiPP2QW);\n\nvoid StartupBlips()\n{\n    BuildBlipAqwGifs(1, &g_aqwBlipeGifsNormal);\n    BuildBlipAqwGifs(2, &g_aqwBlipeGifsClampedAdd);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", PblipNew__FP5BLIPG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", RemoveBlip__FP4BLIP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", PblipgNew__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", InitBlipg__FP5BLIPG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", OnBlipgAdd__FP5BLIPG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", OnBlipgRemove__FP5BLIPG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", SetBlipgShader__FP5BLIPG3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", PropagateBlipgShader__FP5BLIPG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", SetBlipgEmitb__FP5BLIPGP5EMITB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", UpdateBlipg__FP5BLIPGf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", SubscribeBlipgObject__FP5BLIPGP2LO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", CblipeProjectBlipTransformAccel__FP7MATRIX4G8VU_FLOATP5BLIPPP5BLIPVP5BLIPXi6BLIPOKP6VECTORT7);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", ProjectBlipgTransformAccel__FP5BLIPGf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", ProjectBlipgTransform__FP5BLIPGfi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", RenderBlipgSelf__FP5BLIPGP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", DrawBlipg__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/blip\", PropagateBlipgShaders__Fi);\n"
  },
  {
    "path": "src/P2/bomb.c",
    "content": "#include <bomb.h>\n#include <memory.h>\n#include <emitter.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", InitBomb__FP4BOMB);\n\nvoid LoadBombFromBrx(BOMB *pbomb, CBinaryInputStream *pbis)\n{\n    LoadSoFromBrx(pbomb, pbis);\n    // pbomb->pexpl\n    InferExpl(&STRUCT_OFFSET(pbomb, 0x5bc, EXPL *), pbomb);\n}\n\nvoid CloneBomb(BOMB *pbomb, BOMB *pbombBase)\n{\n    CloneSo(pbomb, pbombBase);\n\n    // pbombBase->psfxDet\n    if (STRUCT_OFFSET(pbombBase, 0x680, SFX *))\n    {\n        // pbomb->psfxDet & pbombBase->psfxDet\n        STRUCT_OFFSET(pbomb, 0x680, SFX *) = (SFX *)PvAllocSwCopyImpl(0x24, STRUCT_OFFSET(pbombBase, 0x680, SFX *));\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", PostBombLoad__FP4BOMB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", HandleBombMessage__FP4BOMB5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", UpdateBomb__FP4BOMBf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", FUN_0013b828);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", FUN_0013b9d8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", FUN_0013ba70);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", FAbsorbBombWkr__FP4BOMBP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", FUN_0013bc80);\n\nvoid PrimeBomb(BOMB *pbomb, float dt)\n{\n    // pbomb->tDetonate\n    STRUCT_OFFSET(pbomb, 0x554, float) = g_clock.t + dt;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", ApplyBombThrow__FP4BOMBP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", DetonateBomb__FP4BOMB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bomb\", PsfxEnsureBomb__FP4BOMB4ENSK);\n"
  },
  {
    "path": "src/P2/bq.c",
    "content": "#include <bq.h>\n\nvoid CByteQueue::Init(int cb, void *pv)\n{\n    m_cb = cb;\n    m_ab = (byte *)pv;\n    Reset();\n}\n\nvoid CByteQueue::Reset()\n{\n    m_cbFree = m_cb;\n    m_cbDrain = 0;\n    m_cbAlloc = 0;\n    m_ibAlloc = 0;\n    m_ibFree = 0;\n    m_cbTotal = 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bq\", CbFill__10CByteQueueiP11CQueueInput);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bq\", CbDrain__10CByteQueueiP12CQueueOutput);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bq\", CbFill__10CByteQueueiPUc);\n\nvoid CByteQueue::FreeDrain(int cb)\n{\n    if (cb == 0)\n    {\n        cb = m_cbDrain;\n        if (cb == 0)\n        {\n            return;\n        }\n    }\n\n    m_cbFree += cb;\n    m_cbDrain -= cb;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bq\", CbRead__17CQueueInputMemoryiPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bq\", CbRead__15CQueueInputFileiPv);\n\nJUNK_WORD(0xAC80000C);\n"
  },
  {
    "path": "src/P2/break.c",
    "content": "#include <break.h>\n#include <chkpnt.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", InitBrk__FP3BRK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", LoadBrkFromBrx__FP3BRKP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", CloneBrk__FP3BRKT0);\n\nvoid PostBrkLoad(BRK *pbrk)\n{\n    PostAloLoad((ALO *)pbrk);\n    PostSwCallback(pbrk->psw, PostBrkLoadCallbackHookup, pbrk, MSGID_callback, NULL);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", PostBrkLoadCallbackHookup__FP3BRK5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", UpdateBrk__FP3BRKf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", FAbsorbBrkWkr__FP3BRKP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", BreakBrk__FP3BRK);\n\nvoid SetBrkBroken(BRK *pbrk, int fBroken)\n{\n    STRUCT_OFFSET(pbrk, 0x680, int) = fBroken; // pbrk->fBroken\n\n    if (fBroken)\n    {\n        SetChkmgrIchk(&g_chkmgr, STRUCT_OFFSET(pbrk, 0x688, int)); // pbrk->ichkBroken\n    }\n    else\n    {\n        ClearChkmgrIchk(&g_chkmgr, STRUCT_OFFSET(pbrk, 0x688, int)); // pbrk->ichkBroken\n    }\n}\n\nvoid SetBrkExclude(BRK *pbrk, OID oid)\n{\n    if (STRUCT_OFFSET(pbrk, 0x550, uint) >= 0x10)\n        return;\n\n    (&STRUCT_OFFSET(pbrk, 0x554, BRP))[STRUCT_OFFSET(pbrk, 0x550, uint)].oid = oid;\n    (&STRUCT_OFFSET(pbrk, 0x554, BRP))[STRUCT_OFFSET(pbrk, 0x550, uint)].brpt = BRPT_Disappear;\n    STRUCT_OFFSET(pbrk, 0x550, uint)++;\n}\n\nvoid SetBrkRemain(BRK *pbrk, OID oid)\n{\n    if (STRUCT_OFFSET(pbrk, 0x550, uint) >= 0x10)\n        return;\n\n    (&STRUCT_OFFSET(pbrk, 0x554, BRP))[STRUCT_OFFSET(pbrk, 0x550, uint)].oid = oid;\n    (&STRUCT_OFFSET(pbrk, 0x554, BRP))[STRUCT_OFFSET(pbrk, 0x550, uint)].brpt = BRPT_Remain;\n    STRUCT_OFFSET(pbrk, 0x550, uint)++;\n}\n\nvoid SetBrkFixed(BRK *pbrk, OID oid)\n{\n    if (STRUCT_OFFSET(pbrk, 0x550, uint) >= 0x10)\n        return;\n\n    (&STRUCT_OFFSET(pbrk, 0x554, BRP))[STRUCT_OFFSET(pbrk, 0x550, uint)].oid = oid;\n    (&STRUCT_OFFSET(pbrk, 0x554, BRP))[STRUCT_OFFSET(pbrk, 0x550, uint)].brpt = BRPT_Fixed;\n    STRUCT_OFFSET(pbrk, 0x550, uint)++;\n}\n\nvoid SetBrkRemainFixed(BRK *pbrk, OID oid)\n{\n    if (STRUCT_OFFSET(pbrk, 0x550, uint) >= 0x10)\n        return;\n\n    (&STRUCT_OFFSET(pbrk, 0x554, BRP))[STRUCT_OFFSET(pbrk, 0x550, uint)].oid = oid;\n    (&STRUCT_OFFSET(pbrk, 0x554, BRP))[STRUCT_OFFSET(pbrk, 0x550, uint)].brpt = BRPT_RemainFixed;\n    STRUCT_OFFSET(pbrk, 0x550, uint)++;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", SetBrkOnPlayer__FP3BRKi);\n\nvoid GetBrkOnPlayer(BRK *pbrk, int *pfBreakOnPlayer)\n{\n    // pbrk->grfbrk\n    *pfBreakOnPlayer = STRUCT_OFFSET(pbrk, 0x63c, int) & 1;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", SetBrkOnBomb__FP3BRKi);\n\nvoid GetBrkOnBomb(BRK *pbrk, int *pfBreakOnBomb)\n{\n    // pbrk->grfbrk\n    *pfBreakOnBomb = (STRUCT_OFFSET(pbrk, 0x63c, int) >> 2) & 1;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", AddBrkTouchObject__FP3BRK3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", AddBrkTouchClass__FP3BRK3CID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", FUN_0013DAB8);\n\nSFX *PsfxEnsureBrk(BRK *pbrk, ENSK ensk)\n{\n    // pbrk->psfxBreak\n    if (!STRUCT_OFFSET(pbrk, 0x6b4, SFX *))\n    {\n        NewSfx(&STRUCT_OFFSET(pbrk, 0x6b4, SFX *));\n    }\n    \n    return STRUCT_OFFSET(pbrk, 0x6b4, SFX *);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", FCheckBrkTouchObject__FP3BRKP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", UpdateBrkp__FP4BRKPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", HandleBrkpMessage__FP4BRKP5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", FIgnoreBrkpIntersection__FP4BRKPP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", SetBrkpBrkps__FP4BRKP5BRKPS);\n\nvoid InitBreak(BREAK *pbreak)\n{\n    InitBrk(pbreak);\n    STRUCT_OFFSET(pbreak, 0x63c, int) = 5;\n    STRUCT_OFFSET(pbreak, 0x698, int) = -1;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", InitFragile__FP7FRAGILE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", AdjustFragileNewXp__FP7FRAGILEP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", AdjustZapbreakNewXp__FP8ZAPBREAKP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/break\", UpdateZapbreak__FP8ZAPBREAKf);\n"
  },
  {
    "path": "src/P2/brx.c",
    "content": "#include <brx.h>\n#include <bis.h>\n\nextern EOPID g_aeopid[];\n\nvoid StartupBrx()\n{\n    BuildEopids();\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/brx\", PloNew__F3CIDP2SWP3ALO3OIDi);\n#ifdef SKIP_ASM\n/**\n * @todo 2.19% matched.\n */\nLO *PloNew(CID cid, SW *psw, ALO *paloParent, OID oid, int isplice)\n{\n    return psw;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/brx\", LoadOptionFromBrx__FPvP5EOPIDP18CBinaryInputStream);\n\nvoid LoadOptionsFromBrx(void *pvStruct, CBinaryInputStream *pbis)\n{\n    while (true)\n    {\n        short eopid = pbis->S16Read();\n        if (eopid < 0)\n        {\n            break;\n        }\n        LoadOptionFromBrx(pvStruct, &g_aeopid[eopid], pbis);\n    }\n}\n\nuint IploFromStockOid(int oid)\n{\n    int iplo;\n\n    // Ensure oid is a stock object (OID between 12 and 42)\n    if (oid >= 12 && oid <= 42)\n    {\n        iplo = oid - 12;\n    }\n    else\n    {\n        iplo = -1;\n    }\n\n    return iplo;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/brx\", LoadSwObjectsFromBrx__FP2SWP3ALOP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/brx\", SetLoDefaults__FP2LO);\n"
  },
  {
    "path": "src/P2/bsp.c",
    "content": "#include <bsp.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bsp\", ClsgClipEdgeToBsp__FP3BSPP6VECTORT1PiiP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bsp\", PruneBsp__FP3BSPP6VECTORfPP3BSP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bsp\", PbspPointInBspQuick__FP6VECTORP3BSP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/bsp\", CloneBspc__FP4GEOMP4BSPCT0T1);\n"
  },
  {
    "path": "src/P2/button.c",
    "content": "#include <button.h>\n#include <chkpnt.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", PostAshLoad__FP2SWP3ASHP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", FFoundAshAseg__FP3ASHP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", FAddAshAseg__FP3ASHP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", FAddAshOid__FP3ASH3OID);\n\nvoid InitBtn(BTN *pbtn)\n{\n    STRUCT_OFFSET(pbtn, 0x120, int) = IchkAllocChkmgr(&g_chkmgr); // pbtn->ichkPushed\n    STRUCT_OFFSET(pbtn, 0x140, OID) = OID_Nil; // pbtn->oidDialog\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", LoadBtn__FP3BTNP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", PostBtnLoad__FP3BTN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", RestoreBtnFromCheckpointCallback__FP3BTN5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", SetBtnRsmg__FP3BTNi3OIDN22);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", SetBtnButtons__FP3BTN7BUTTONS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", FAddRsmg__FP4RSMGiPii3OIDN24);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", TriggerRsmg__FP2SWiP4RSMGP2LOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", RunBtnAsegs__FP3BTN4IASHii);\n\nvoid TriggerBtn(BTN *pbtn, int fSeekToEnd, int fChkTrigger)\n{\n    if (fChkTrigger)\n        HandleLoSpliceEvent(pbtn->paloOwner, 0x16, 0, NULL);\n    else\n        HandleLoSpliceEvent(pbtn->paloOwner, 2, 0, NULL);\n\n    if (!STRUCT_OFFSET(pbtn, 0x134, int) && !fChkTrigger) // pbtn->fSilent\n    {\n        float sStart = 3000.0f;\n        float sFull = 300.0f;\n        float uVolAtSource = 1.0f;\n        StartSound(SFXID_Click1, NULL, pbtn->paloOwner, NULL, sStart, sFull, uVolAtSource, 0.0f,\n                   0.0f, NULL, NULL);\n    }\n\n    RunBtnAsegs(pbtn, IASH_On, fSeekToEnd, fChkTrigger);\n\n    if (!STRUCT_OFFSET(pbtn, 0x13C, int)) // pbtn->fManualReset\n        SetBtnButtons(pbtn, BUTTONS_Pushed);\n\n    if (STRUCT_OFFSET(pbtn, 0x11C, int))                           // pbtn->fCheckpointed\n        SetChkmgrIchk(&g_chkmgr, STRUCT_OFFSET(pbtn, 0x120, int)); // pbtn->ichkPushed\n\n    pbtn->paloOwner->pvtlo->pfnSendLoMessage(pbtn->paloOwner, MSGID_button_trigger, pbtn);\n}\n\nvoid UntriggerBtn(BTN *pbtn, int fSeekToEnd)\n{\n    HandleLoSpliceEvent(pbtn->paloOwner, 3, 0, NULL); // untrigger event\n    RunBtnAsegs(pbtn, IASH_Off, fSeekToEnd, 0);\n    pbtn->paloOwner->pvtlo->pfnSendLoMessage(pbtn->paloOwner, MSGID_button_untrigger, pbtn);\n}\n\nvoid InitButton(BUTTON *pbutton)\n{\n    InitSo(pbutton);\n    InitBtn(&STRUCT_OFFSET(pbutton, 0x554, BTN)); // pbutton->btn\n}\n\nvoid LoadButtonFromBrx(BUTTON *pbutton, CBinaryInputStream *pbis)\n{\n    LoadSoFromBrx(pbutton, pbis);\n    LoadBtn(&STRUCT_OFFSET(pbutton, 0x554, BTN), pbutton); // pbutton->btn\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", InsertButtonPos__FP6BUTTONP3PNTP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", InsertButtonMat__FP6BUTTONP3XFMP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", PostButtonLoad__FP6BUTTON);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", CloneButton__FP6BUTTONT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", SetButtonButtons__FP6BUTTON7BUTTONS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", FCheckButtonObject__FP6BUTTONP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", IposFindButtonClosest__FP6BUTTONPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", ImatFindButtonClosest__FP6BUTTONPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", PresetButtonAccel__FP6BUTTONf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", UpdateButtonInternalXps__FP6BUTTON);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", UpdateButton__FP6BUTTONf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", FAbsorbButtonWkr__FP6BUTTONP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", InitVolbtn__FP6VOLBTN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", LoadVolbtnFromBrx__FP6VOLBTNP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", PostVolbtnLoad__FP6VOLBTN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", CloneVolbtn__FP6VOLBTNT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", SetVolbtnButtons__FP6VOLBTN7BUTTONS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", UpdateVolbtn__FP6VOLBTNf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", FGetVolbtnPushObjectsWithinList__FP6VOLBTNPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddBtnAseg__FP3BTNP3ALO3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddButtonAseg__FP6BUTTON3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddVolbtnAseg__FP6VOLBTN3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddBtnOffAseg__FP3BTNP3ALO3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddButtonOffAseg__FP6BUTTON3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddVolbtnOffAseg__FP6VOLBTN3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddButtonPushObject__FP6BUTTON3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddButtonNoPushObject__FP6BUTTON3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddButtonPushClass__FP6BUTTON3CID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/button\", AddButtonNoPushClass__FP6BUTTON3CID);\n\nvoid AddVolbtnPushObject(VOLBTN *pvolbtn, OID oid)\n{\n    int coidPush = STRUCT_OFFSET(pvolbtn, 0x550, int);        // pvolbtn->coidPush\n    STRUCT_OFFSET_INDEX(pvolbtn, 0x554, OID, coidPush) = oid; // pvolbtn->aoidPush[coidPush]\n    STRUCT_OFFSET(pvolbtn, 0x550, int) = coidPush + 1;        // pvolbtn->coidPush\n}\n\nvoid SetButtonRsmg(BUTTON *pbutton, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal)\n{\n    SetBtnRsmg(&STRUCT_OFFSET(pbutton, 0x554, BTN), fOnTrigger, oidRoot, oidSM, oidGoal); // pbutton->btn\n}\n\nvoid SetVolbtnRsmg(VOLBTN *pvolbtn, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal)\n{\n    SetBtnRsmg(&STRUCT_OFFSET(pvolbtn, 0x5c0, BTN), fOnTrigger, oidRoot, oidSM, oidGoal); // pvolbtn->btn\n}\n"
  },
  {
    "path": "src/P2/cat.c",
    "content": "#include <cat.h>\n#include <cd.h>\n\nextern CDS g_cds;\n\nvoid StartupCatalog()\n{\n    g_cds = CDS_Ready;\n}\n\nint FUN_001407A0(uint *pui)\n{\n    return pui[1];\n}\n"
  },
  {
    "path": "src/P2/cd.c",
    "content": "#include <cd.h>\n#include <989snd.h>\n#include <sdk/libcdvd.h>\n\nextern int g_scecd;\nextern int s_retCdRead;\nextern int s_retCdError;\nextern sceCdRMode s_cdmode;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cd\", CpchzTokenizePath__FPc);\n\nbool FValidCdMmode()\n{\n    // TODO: This is the only way I managed to get the code to match.\n    // This might be possible to clean up, but I wasn't able to. - 545u\n    int type = sceCdGetDiskType();\n    if (g_scecd == type)\n    {\n        type = g_scecd;\n    }\n    else\n    {\n        g_scecd = type;\n    }\n\n    return g_scecd == SCECdPS2DVD;\n}\n\nvoid SetCdMmode()\n{\n    if (g_scecd == SCECdPS2DVD)\n    {\n        sceCdMmode(2);\n    }\n}\n\nvoid StartupCd()\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cd\", UpdateCd__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cd\", CdPath__FPcT0i);\n\nvoid ReadCd(uint isector, uint csector, void *pv)\n{\n    do\n    {\n        s_retCdRead = snd_StreamSafeCdRead(isector, csector, pv, &s_cdmode);\n        if (s_retCdRead == 1)\n        {\n            break;\n        }\n\n        snd_StreamSafeCdSync(0);\n        s_retCdError = snd_StreamSafeCdGetError();\n    } while (true);\n}\n\nvoid ReadCdDirect(uint isector, uint csector, void *pv)\n{\n    do\n    {\n        s_retCdRead = sceCdRead(isector, csector, pv, &s_cdmode);\n        if (s_retCdRead == 1)\n        {\n            break;\n        }\n\n        sceCdSync(0);\n        s_retCdError = sceCdGetError();\n    } while (true);\n}\n\nbool FCdCompleted(int fBlock)\n{\n    return !snd_StreamSafeCdSync(!fBlock);\n}\n\nJUNK_ADDIU(10);\n"
  },
  {
    "path": "src/P2/chkpnt.c",
    "content": "#include <chkpnt.h>\n#include <sce/memset.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", ResetChkmgrCheckpoints__FP6CHKMGR);\n#ifdef SKIP_ASM\n/**\n * @brief Resets the checkpoints on the checkpoint manager.\n *\n * @param pchkmgr Pointer to the checkpoint manager.\n *\n * @todo 67.19% matched.\n */\nvoid ResetChkmgrCheckpoints(CHKMGR *pchkmgr)\n{\n\tpchkmgr->cbitChk = 0;\n\tpchkmgr->unk_0x8 = 0;\n\n\tmemset(STRUCT_OFFSET(pchkmgr, 0xc, void *), 0, 0x200);\n\tpchkmgr->fChkDirty = 0;\n\n\tfloat temp_should_be_global_var = 0.0f;\n\tpchkmgr->posVolChkpnt.x = temp_should_be_global_var;\n\tpchkmgr->posVolChkpnt.z = temp_should_be_global_var;\n\tpchkmgr->posVolChkpnt.x = temp_should_be_global_var;\n\tpchkmgr->posVolChkpnt.x = (float)((int)temp_should_be_global_var >> 0x1f);\n\n\tmemset(pchkmgr->csSaved, 0, 0x20c);\n\tpchkmgr->fCheckpoint = 0;\n\n\tpchkmgr->unk_oid_0x424 = (OID)0xFFFFFFFF;\n\tpchkmgr->unk_oid_0x428 = (OID)0xFFFFFFFF;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", SaveChkmgrCheckpoint__FP6CHKMGR3OIDT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", ReturnChkmgrToCheckpoint__FP6CHKMGR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", RestoreChkmgrFromCheckpoint__FP6CHKMGR);\n\nint IchkAllocChkmgr(CHKMGR *pchkmgr)\n{\n    return ++pchkmgr->cbitChk;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", FGetChkmgrIchk__FP6CHKMGRi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", SetChkmgrIchk__FP6CHKMGRi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", ClearChkmgrIchk__FP6CHKMGRi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", LoadVolFromBrx__FP3VOLP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", FCheckVolPoint__FP3VOLP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", InitChkpnt__FP6CHKPNT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", LoadChkpntFromBrx__FP6CHKPNTP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", BindChkpnt__FP6CHKPNT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", PostChkpntLoad__FP6CHKPNT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", CloneChkpnt__FP6CHKPNTT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", UpdateChkpnt__FP6CHKPNTf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", FUN_001417f0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", TriggerChkpnt__FP6CHKPNT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", FUN_001419A0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", FUN_001419C0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/chkpnt\", FUN_001419E0);\n"
  },
  {
    "path": "src/P2/clip.c",
    "content": "#include <clip.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", PsoHitTestLineObjects__FiP6VECTORT1iPP2SOP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", FUN_00141b48);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", ClsgClipEdgeToObject__FP2SOP6VECTORT1iP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", ClsgClipEdgeToObjectPruned__FP2SOP3BSPP6VECTORT2iP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", ClsgClipCylinderToObject__FP2SOP6VECTORT1fiP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", ClsgClipLineToSphere__FP6VECTORfT0T0iP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", ClsgClipEdgeToSphere__FP6VECTORfT0T0iP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", ClsgClipCylinderToSphere__FP6VECTORfT0T0fiP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", ClsgClipEdgeToCylinder__FP6VECTORT0fT0T0iP3LSG);\n\nJUNK_WORD(0x27BD01C0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", SgnCompareMaa__FP3MAAT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", ClsgMergeAlsg__FiP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/clip\", ClsgClipCylinderToBsp__FP4BSPCP4GEOMP6VECTORT2fiP3LSG);\n\nJUNK_WORD(0x27BD0120);\n"
  },
  {
    "path": "src/P2/clock.c",
    "content": "#include <clock.h>\n#include <intrinsics.h>\n\n// constants\nstatic const int CLOCK_FRAMERATE = 60; // 60 FPS\nstatic const float CLOCK_FRAMETIME = 1.f / CLOCK_FRAMERATE; // 1/60th of a second\n\nstatic const int CLOCK_EE_TICK_RATE = 294912000; // 294.912 MHz\nstatic const float CLOCK_EE_TICK_DURATION = 1.f / CLOCK_EE_TICK_RATE; // 1/294.912 MHz\n\n// data\nfloat g_rtClock = 1.0f;\nfloat g_rtClockPowerUp = 1.0f;\nCLOCK g_clock = { 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0 };\nTICK s_tickLastRaw; // Should be static?\n\nvoid SetClockRate(float rt)\n{\n    g_rtClock = rt;\n    SetClockEnabled(&g_clock, rt > 0.0f);\n}\n\nvoid MarkClockTick(CLOCK *pclock)\n{\n    const TICK currentTick = TickNow();\n    const TICK deltaTick = currentTick - pclock->tickFrame;\n    float dt = deltaTick * CLOCK_EE_TICK_DURATION;\n\n    // Clamp delta time between one and two frames\n    float dtMin = CLOCK_FRAMETIME;\n    float dtMax = CLOCK_FRAMETIME * 2;\n\n    if (dt < dtMin)\n    {\n        dt = dtMin;\n    }\n    else if (dt > dtMax)\n    {\n        dt = dtMax;\n    }\n\n    // Store unscaled real delta time\n    pclock->dtReal = dt;\n    float dtScaled = pclock->fEnabled ? dt : 0.0f;\n    dtScaled *= g_rtClockPowerUp * g_rtClock;\n\n    // If scaled delta time is at least one frame, store the scaled value\n    if (dtScaled >= CLOCK_FRAMETIME)\n    {\n        pclock->dtReal = dtScaled;\n    }\n\n    // Update clock state\n    pclock->t += dtScaled;\n    pclock->dtPrev = pclock->dt;\n    pclock->dt = dtScaled;\n    pclock->tReal += pclock->dtReal;\n    pclock->tickFrame = currentTick;\n}\n\nvoid MarkClockTickRealOnly(CLOCK *pclock)\n{\n    const TICK currentTick = TickNow();\n    const TICK deltaTick = currentTick - pclock->tickFrame;\n    float dt = deltaTick * CLOCK_EE_TICK_DURATION;\n\n    pclock->dtReal = dt;\n    pclock->tReal += pclock->dtReal;\n    pclock->tickFrame = currentTick;\n}\n\nvoid ResetClock(CLOCK *pclock, float t)\n{ \n    pclock->t = t;\n}\n\nvoid SetClockEnabled(CLOCK *pclock, int fEnabled)\n{\n    pclock->fEnabled = fEnabled;\n}\n\nvoid StartupClock() \n{\n    ulong cTick = READ_CP0_COUNT();\n\n    s_tickLastRaw = (TICK)cTick;\n    g_clock.tickFrame = TickNow();\n}\n\n/**\n * @todo Correct cWrapAround once the bss section of the TU is migrated.\n */\nconst TICK TickNow()\n{\n    // Read 32-bit CP0 Count register\n    ulong cTick = READ_CP0_COUNT();\n\n    // Mask count to ensure clean 32-bit value (likely not necessary)\n    ulong ulMask = 0xFFFFFFFF;\n    cTick = cTick & ulMask;\n\n    // Detect wraparound: if count < previous count, the register overflowed\n    if (cTick < s_tickLastRaw)\n    {\n        cWrapAround++;\n    }\n\n    // Store current count for next wraparound detection\n    s_tickLastRaw = cTick;\n\n    // Combine wraparound count (upper 32 bits) with current count (lower 32 bits)\n    return (cWrapAround << 32) | cTick;\n}\n"
  },
  {
    "path": "src/P2/cm.c",
    "content": "/**\n * @todo Mangle all function names in INCLUDE_ASM macros.\n */\n#include <cm.h>\n#include <util.h>\n#include <binoc.h>\n#include <cplcy.h>\n\n// todo fix data and rodata\n// VECTOR4 g_posEyeDefault = { 0.0f, -2000.0f, 500.0f, 0.0f };\n// VECTOR4 g_posCenterDefault = { 0.0f, 0.0f, 0.0f, 0.0f };\n\n// float g_sNearFog = 500.0f;\n// float g_sFarFog = 20000.0f;\n// float g_uFogMax = 0.5f;\n// RGBA g_rgbaFog = { 0, 0, 0, 0 };\n\n// VECTOR4 D_002618B8 = { 0.5f, 0.0f, 0.1f, 10.0f }; // unknown\n\n// float DT_CmJoltMax = 0.5f;\n// float SW_CmJolt = 50.0f;\n// CLQ s_clqUToUJolt = { 1.0f, -2.0f, 1.0f, 0.0f };\n// VECTOR4 s_dposJolt = { 0.0f, 0.0f, 0.0f, 0.0f };\n// VECTOR4 s_rotJolt = { 0.05f, 0.0f, 0.0f, 0.0f };\n\n// VECTOR4 s_vecRange = { 0.0f, 0.0f, 0.0f, 0.0f };\n// VECTOR4 s_vecOffset = { 0.0f, 0.0f, 0.0f, 0.0f };\n\n// float R_SetCmSpring = 15.0f;\n// float R_SetCmDamping = -8.0f;\n\n// float D_00261928[] = { 1.0f, 5.0f, 10.0f, 12.0f, 15.0f, 12.0f, 10.0f, 5.0f, 1.0f }; // array of 9 floats\n// float D_0026194C = 250.0f;\n// float D_00261950 = 1500.0f;\n\n// SMP s_smpSquishEye = { 2500.0f, 0.0f, 0.25f };\n// SMP unk_padding = { 0.0f, 0.0f, 0.0f }; // needed to align next variables\n\n// float D_00261970 = -250.0f;\n// float D_00261974 = 250.0f;\n// float D_00261978 = 250.0f;\n// float D_0026197C = 0.0f;\n// float D_00261980 = 250.0f;\n// float D_00261984 = 250.0f;\n// float D_00261988 = 250.0f;\n// float D_0026198C = 0.0f;\n\n// CM* g_pcm = NULL;\n\nvoid StartupCm()\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", CalcCmAdjust__FP2CMP2SOP6CPDEFIP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", SpringCm__FfffP2CMP6VECTORP6VECTORP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", AdjustCmCpdefi__FP2CMP2SOfP6CPDEFI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", ResetCmAdjust__FP2CMP2SOP6CPDEFI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", GetCmCpdefi__FP2CMP2SOfP6CPDEFI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", BuildCmFgfn__FP2CMfP4FGFN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", RecalcCmFrustrum__FP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", InitCm__FP2CM);\n\nvoid SetSwCameraFov(float fov)\n{\n    SetCmFov(g_pcm, fov);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_001437e8);\n\nvoid SetSwCameraFarClip(float sFarClip)\n{\n    SetCmFarClip(g_pcm, sFarClip);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00143838);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00143860);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00143888);\n\nvoid SetSwCameraRgbaFog(SW *psw, RGBA *prgbaFog)\n{\n    SetCmRgbaFog(g_pcm, prgbaFog);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_001438d8);\n\nvoid SetCmPos(CM *pcm, VECTOR *ppos)\n{\n    SetCmPosMat(pcm, ppos, NULL);\n}\n\nvoid SetCmMat(CM *pcm, MATRIX3 *pmat)\n{\n    SetCmPosMat(pcm, NULL, pmat);\n}\n\nvoid SetCmFov(CM *pcm, float fov)\n{\n    STRUCT_OFFSET(pcm, 0x1c4, float) = fov;\n    STRUCT_OFFSET(pcm, 0x1c8, float) = fov;\n    STRUCT_OFFSET(pcm, 0x1cc, int) = 0;\n    RecalcCmFrustrum(pcm);\n}\n\nvoid SetCmNearClip(CM *pcm, float sNearClip)\n{\n    pcm->sNearClip = sNearClip;\n    RecalcCmFrustrum(pcm);\n}\n\nvoid SetCmFarClip(CM *pcm, float sFarClip)\n{\n    pcm->sFarClip = sFarClip;\n    RecalcCmFrustrum(pcm);\n}\n\nvoid SetCmSProgress(CM *pcm, float uSProgress)\n{\n    pcm->uSProgress = uSProgress;\n    RecalcCmFrustrum(pcm);\n}\n\nvoid FUN_001439c8(CM *pcm, float param_2)\n{\n    pcm->field35_0x1fc = param_2;\n    RecalcCmFrustrum(pcm);\n}\n\nvoid FUN_001439e8(CM *pcm, float param_2)\n{\n    pcm->field36_0x200 = param_2;\n    RecalcCmFrustrum(pcm);\n}\n\nvoid SetCmRgbaFog(CM *pcm, RGBA *prgbaFog)\n{\n    STRUCT_OFFSET(pcm, 0x204, RGBA) = *prgbaFog; // pcm->rgbaFog = *prgbaFog;\n    RecalcCmFrustrum(pcm);\n}\n\nvoid SetCmMrdRatio(CM *pcm, float ratio)\n{\n    STRUCT_OFFSET(pcm, 0x1c0, float) = ratio;\n    RecalcCmFrustrum(g_pcm);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", ResetCm);\n\nvoid ClearCmFadeObjects(CM *pcm)\n{\n    pcm->field67_0x340 = 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", AddCmFadeObject);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", RemoveCmFadeObject);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00143BA8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", UpdateCmFade);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", UpdateCmLast);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", SetupCmRotateToCam);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", ConvertCmScreenToWorld);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", ConvertCmWorldToScreen);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", SetupCm__FP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", CombineEyeLookAtProj);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", BuildFrustrum);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", UpdateCmMat4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", DrawCm__FP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", SetCmPosMat__FP2CMP6VECTORP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", SetCmLookAt);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", ConvertWorldToCylindVelocity);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", ConvertCylindToWorldVelocity);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", ResetCmLookAtSmooth);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", SetCmLookAtSmooth);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", AdjustCmJoy__FP2CMP3JOY5JOYIDPf);\n\nJUNK_WORD(0x0000102D);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", SetCmPolicy__FP2CM3CPPP5CPLCYP2SOPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", RevokeCmPolicy__FP2CMi3CPPP5CPLCYP2SOPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FInsideCmMrd);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", DecomposeCylind);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", DecomposeSphere);\n\nvoid SetCmCut(CM *pcm, float *pradCut)\n{\n    pcm->field41_0x224 = 1; // Likely pcm->fCut\n    if (pradCut)\n    {\n        pcm->field42_0x228 = 1; // Likely pcm->fRadCut\n        pcm->field43_0x22c = pradCut[0]; // Likely pcm->radCut\n    }\n}\n\nvoid SetResetFlag(CM *pcm)\n{\n    pcm->reset_flag = true;\n}\n\nvoid ClearCmCut(CM *pcm)\n{\n    SetCmCut(pcm, 0);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", AdaptCm);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", SetCm);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", PsoEnemyStepguard);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00145950);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00145b68);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00145DD8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00145de8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00145e68);\n\nvoid PushLookkCm(CM *pcm, LOOKK lookk)\n{\n    PushCplookLookk(&pcm->cplook, lookk);\n}\n\nLOOKK LookkPopCm(CM *pcm)\n{\n    return LookkPopCplook(&pcm->cplook);\n}\n\nLOOKK LookkCurCm(CM *pcm)\n{\n    return LookkCurCplook(&pcm->cplook);\n}\n\nvoid SetCmSniperFocus(CM *pcm, PNT *ppntAnchor, float sRadiusSniper, float rScreenSniper)\n{\n    pcm->cplook.ppntAnchor = ppntAnchor;\n    pcm->cplook.sRadiusSniper = sRadiusSniper;\n    pcm->cplook.rScreenSniper = rScreenSniper;\n}\n\nvoid FUN_00146028(CM *pcm)\n{\n    pcm->vCenter.z = g_clock.t;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", FUN_00146038);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cm\", cm__static_initialization_and_destruction_0__Fii);\n\nvoid _GLOBAL_$I$StartupCm()\n{\n    cm__static_initialization_and_destruction_0(1, 0xffff);\n}\n"
  },
  {
    "path": "src/P2/cnvo.c",
    "content": "#include <cnvo.h>\n#include <bbmark.h>\n\nvoid InitCnvo(CNVO *pcnvo)\n{\n    InitSo(pcnvo);\n    STRUCT_OFFSET(pcnvo, 0x550, float) = 100.0f; // pcnvo->svBelt\n}\n\nvoid LoadCnvoFromBrx(CNVO *pcnvo, CBinaryInputStream *pbis)\n{\n    LoadSoFromBrx(pcnvo, pbis);\n    STRUCT_OFFSET(pcnvo, 0x554, float) = pbis->F32Read(); // pcnvo->svuAvg\n    STRUCT_OFFSET(pcnvo, 0x558, float) = pbis->F32Read(); // pcnvo->svvAvg\n}\n\nvoid PostCnvoLoad(CNVO *pcnvo)\n{\n    PostAloLoad(pcnvo);\n    MatchCnvoScrollerToBeltSpeed(pcnvo);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cnvo\", AdjustCnvoXpVelocity__FP4CNVOP2XPi);\n\nvoid SetCnvoBeltSpeed(CNVO *pcnvo, float svBelt)\n{\n    if (svBelt == STRUCT_OFFSET(pcnvo, 0x550, float)) // pcnvo->svBelt\n        return;\n\n    STRUCT_OFFSET(pcnvo, 0x550, float) = svBelt; // pcnvo->svBelt\n    InvalidateSwXpForObject(pcnvo->psw, pcnvo, 7);\n    MatchCnvoScrollerToBeltSpeed(pcnvo);\n    ResolveAlo(pcnvo);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cnvo\", MatchCnvoScrollerToBeltSpeed__FP4CNVO);\n"
  },
  {
    "path": "src/P2/coin.c",
    "content": "#include <coin.h>\n#include <chkpnt.h>\n#include <bis.h>\n#include <sw.h>\n\nvoid InitDprize(DPRIZE *pdprize)\n{\n    pdprize->dprizesInit = DPRIZES_Normal;\n    pdprize->dprizes = DPRIZES_Nil;\n    pdprize->svcAttract = 30.0f;\n    pdprize->oidInitialState = OID_Nil;\n    InitAlo(pdprize);\n    AppendDlEntry(&pdprize->psw->dlDprize, pdprize);\n    pdprize->ichkCollected = IchkAllocChkmgr(&g_chkmgr);\n    pdprize->ficg.grficSmash = '\\x10';\n    pdprize->ficg.grficRush = '\\x10';\n    pdprize->ficg.grficSweep = '\\x10';\n    pdprize->ficg.grficBomb = '\\x10';\n    pdprize->fLastBounce = 1;\n}\n\nvoid LoadDprizeFromBrx(DPRIZE *pdprize, CBinaryInputStream *pbis)\n{\n    SetAloTargetHitTest(pdprize, 1);\n    LoadAloFromBrx(pdprize, pbis);\n    SnipAloObjects(pdprize, 5, s_asnipDprize);\n}\n\nvoid CloneDprize(DPRIZE *pdprize, DPRIZE *pdprizeBase)\n{\n    int ichkCollected = pdprize->ichkCollected;\n    DLE dle = pdprize->dle;\n    CloneAlo(pdprize, pdprizeBase);\n    pdprize->dle = dle;\n    pdprize->ichkCollected = ichkCollected;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", PostDprizeLoad__FP6DPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", ProjectDprizeTransform__FP6DPRIZEfi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FFilterDprizeObjects__FP6DPRIZEP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", CheckDprizeBounce__FP6DPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", CheckDprizeCollect__FP6DPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FAbsorbDprizeWkr__FP6DPRIZEP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", UpdateDprize__FP6DPRIZEf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", RenderDprizeAll__FP6DPRIZEP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", SetDprizeDprizes__FP6DPRIZE7DPRIZES);\n\nvoid InitCoin(COIN *pcoin)\n{\n    InitDprize(pcoin);\n    pcoin->sRadiusBounce = 45.0f;\n    pcoin->svLastBounceMax = 250.0f;\n    pcoin->sRadiusCollect = 50.0f;\n    pcoin->svLastBounce = 50.0f;\n    pcoin->rxyBounce = 0.6f;\n    pcoin->rzBounce = 0.75f;\n    pcoin->uGlintChance = 0.25f;\n    pcoin->lmDtMaxLifetime.gMin = 8.0f;\n    pcoin->lmDtMaxLifetime.gMax = 10.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00147ed0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00147ef8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", UpdateCoin__FP4COINf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", CreateSwCharm__FP2SW);\n\nvoid AddLife(void *ptr)\n{\n    int new_clife = g_pgsCur->clife + 1;\n    int capped_clife = 99;\n    if (new_clife < 99)\n    {\n        capped_clife = new_clife;\n    }\n    g_pgsCur->clife = capped_clife;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", OnCoinSmack__FP4COIN);\n#ifdef SKIP_ASM\n/**\n * @todo 91.21% matched.\n */\nvoid OnCoinSmack(COIN *pcoin)\n{\n    g_pgsCur->ccoin++;\n\n    if (g_pgsCur->ccoin < 100)\n        return;\n\n    if (g_pgsCur->ccharm < CcharmMost())\n    {\n        // Give the player a charm and reset the coin count\n        g_pgsCur->ccoin = 0;\n        g_coinctr.dgDisplayMax = 250.0f;\n        g_coinctr.pfnsmack = CreateSwCharm;\n        g_coinctr.pv = pcoin->psw;\n    }\n    else\n    {\n        if (g_pgsCur->clife < 99)\n        {\n            // Give the player a life and reset the coin count\n            g_pgsCur->ccoin = 0;\n            g_coinctr.dgDisplayMax = 250.0f;\n            g_coinctr.pv = NULL;\n            g_coinctr.pfnsmack = AddLife;\n            g_lifectr.pvtblot->pfnShowBlot(&g_lifectr);\n        }\n        else\n        {\n            // Clamp coin count to 99\n            g_pgsCur->ccoin = 99;\n        }\n    }\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", SetCoinDprizes__FP4COIN7DPRIZES);\n\nvoid InitCharm(CHARM *pcharm)\n{\n    InitDprize(pcharm);\n    pcharm->sRadiusBounce = 60.0f;\n    pcharm->sRadiusCollect = 60.0f;\n    pcharm->svLastBounceMax = 300.0f;\n    pcharm->svLastBounce = 0.0f;\n    pcharm->rxyBounce = 0.75f;\n    pcharm->rzBounce = 0.5f;\n    pcharm->uGlintChance = 0.35f;\n}\n\nvoid SetCharmDprizes(CHARM *pcharm, DPRIZES dprizes)\n{\n    // if (pcharm->dprizes == dprizes)\n    if (STRUCT_OFFSET(pcharm, 0x2d0, DPRIZES) == dprizes)\n        return;\n\n    if (dprizes == DPRIZES_Collect)\n    {\n        dprizes = DPRIZES_Swirl;\n        StartSound(SFXID_Collect_Charm, NULL, pcharm, NULL, 1500.0f, 0.0f, 1, 0.0f, 0.0f, NULL,\n                   NULL);\n        HandleLoSpliceEvent(pcharm, 2, 0, NULL);\n    }\n\n    SetDprizeDprizes(pcharm, dprizes);\n}\n\nvoid InitKey(KEY *pkey)\n{\n    InitDprize(pkey);\n    pkey->sRadiusBounce = 35.0f;\n    pkey->sRadiusCollect = 35.0f;\n    pkey->svLastBounceMax = 500.0f;\n    pkey->svLastBounce = 250.0f;\n    pkey->rxyBounce = 0.6f;\n    pkey->rzBounce = 0.6f;\n    pkey->uGlintChance = 0.75f;\n\n    if (g_plsCur->fls & FLS_KeyCollected)\n    {\n        pkey->dprizesInit = DPRIZES_Removed;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", SetKeyDprizes__FP3KEY7DPRIZES);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148698);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148718);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148748);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148770);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148828);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148888);\n\nint FUN_00148910(float *pf0, float *pf1)\n{\n    return (*pf0 < *pf1) ? 1 : -1;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148938);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", CpdprizeAttractSwDprizes__FP2SW3CIDP6VECTORiPP6DPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", RemoveSwExtraneousCharms__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148d90);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148e18);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148e40);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00148ef8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", increment_and_show_life_count);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", CollectLifetkn__FP7LIFETKN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", FUN_00149168);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/coin\", break_bottle);\n"
  },
  {
    "path": "src/P2/cplcy.c",
    "content": "/**\n * @todo Mangle all function names in INCLUDE_ASM macros.\n */\n#include <cplcy.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", InitCplcy);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", FActiveCplcy);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", SetCpmanCpmt);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", FUN_001493c0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", PosCplookAnchor);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", FUN_00149458);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", plays_binoc_sfx);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", PushCplookLookk__FP6CPLOOK5LOOKK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", LookkPopCplook__FP6CPLOOK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", LookkCurCplook__FP6CPLOOK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", InitCplook);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", FUN_001496c0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", UpdateCplook);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", FUN_0014a7b8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", InitCpalign);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", FUN_0014a8d0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", UpdateCpalign);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", FUN_0014aa90);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", FUN_0014aa98);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/cplcy\", UpdateCpaseg);\n"
  },
  {
    "path": "src/P2/credit.c",
    "content": "#include <credit.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/credit\", InitCredit__FP6CREDIT5BLOTK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/credit\", PostCreditLoad__FP6CREDIT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/credit\", SetCreditClock__FP6CREDITPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/credit\", UpdateCredit__FP6CREDIT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/credit\", DrawCredit__FP6CREDIT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/credit\", PlaceCredit__FP6CREDITffi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/credit\", VacateCredit__FP6CREDIT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/credit\", SetCreditLine__FP6CREDITiPcf);\n"
  },
  {
    "path": "src/P2/crout.c",
    "content": "#include <crout.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crout\", CroutDecomp__FiPfT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crout\", CroutSolve__FiPfN21);\n"
  },
  {
    "path": "src/P2/crusher.c",
    "content": "#include <crusher.h>\n\n/**\n * @todo Rename.\n */\nextern int DAT_0027c008;\n\nvoid OnCrfodAdd(CRFOD *pcrfod)\n{\n    OnStepguardAdd(pcrfod);\n    AppendDlEntry(&pcrfod->psw->dlCrfod, pcrfod);\n}\n\nvoid OnCrfodRemove(CRFOD *pcrfod)\n{\n    OnStepguardRemove(pcrfod);\n    RemoveDlEntry(&pcrfod->psw->dlCrfod, pcrfod);\n}\n\nvoid CloneCrfod(CRFOD *pcrfod, CRFOD *pcrfodBase)\n{\n    DLE dleCrfod = STRUCT_OFFSET(pcrfod, 0xc10, DLE);\n    CloneStepguard(pcrfod, pcrfodBase);\n    STRUCT_OFFSET(pcrfod, 0xc10, DLE) = dleCrfod;\n}\n\nvoid InitCrfodb(CRFODB *pcrfodb)\n{\n    InitStepguard(pcrfodb);\n    STRUCT_OFFSET(pcrfodb, 0xc24, int) = 1;\n    DAT_0027c008 = 0;\n}\n\nvoid PostCrfodbLoad(CRFODB *pcrfodb)\n{\n    PostStepguardLoad(pcrfodb);\n    STRUCT_OFFSET(pcrfodb, 0xc2c, int) = DAT_0027c008++;\n}\n\nvoid CalcHeadingVector(float rad, VECTOR *pvector)\n{\n    CalculateSinCos(rad, &pvector->y, (float *)pvector);\n    pvector->z = 0.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", UpdateCrfodbGoal__FP6CRFODBi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FDetectCrfodb__FP6CRFODB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FAbsorbCrfodbWkr__FP6CRFODBP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014bd38);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", SgsNextCrfodkAI__FP6CRFODK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FDetectCrfodk__FP6CRFODK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FAbsorbCrfodkWkr__FP6CRFODKP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014bf88);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", InitCrbrain__FP7CRBRAIN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", post_load_crbrain);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014c2f0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014c5e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014c668);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", update_crbrain);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014c788);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014c820);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014c838);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014c858);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014cba8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014cd70);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", FUN_0014cdc8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crusher\", handle_crbrain_message);\n"
  },
  {
    "path": "src/P2/crv.c",
    "content": "#include <crv.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", SMeasureApos__FiP6VECTORPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", GWrapApos__FfiPfi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", IposFindAposG__FfiPfiT2T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", EvaluateAposG__FfiP6VECTORPfiT2T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FindAposClosestPointAll__FP6VECTORP6CONSTRiT0N20PiPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FindAposClosestPointSegment__FP6VECTORP6CONSTRiT0iiT0T0PiPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", ConvertApos__FiP6VECTORP7MATRIX4T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", PcrvNew__F4CRVK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", SFromCrvU__FP3CRVf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", UFromCrvS__FP3CRVf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", IcvFindCrvU__FP3CRVfPfT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", IcvFindCrvS__FP3CRVfPfT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", GMeasureCrvU__FP5CRVMCf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", UMaxCrv__FP3CRV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", SMaxCrv__FP3CRV);\n\nJUNK_ADDIU(A0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", SMeasureCrvSegmentU__FP5CRVMSf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FindCrvClosestPointOnLineSegmentFromU__FP3CRVP6VECTORT1fT1T1PfT6);\n\nJUNK_ADDIU(A0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", DuGetCrvSearchIncrement__FP3CRV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", LoadCrvlFromBrx__FP4CRVLP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", EvaluateCrvlFromU__FP4CRVLfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", EvaluateCrvlFromS__FP4CRVLfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", RenderCrvlSegment__FP4CRVLiP7MATRIX4P2CMG4RGBAi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", ConvertCrvl__FP4CRVLP7MATRIX4T1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", SFromCrvlU__FP4CRVLf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", UFromCrvlS__FP4CRVLf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", MeasureCrvl__FP4CRVL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FindCrvlClosestPointAll__FP4CRVLP6VECTORP6CONSTRT1T1PfT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FindCrvlClosestPointFromU__FP4CRVLP6VECTORfP6CONSTRT1T1PfT6);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FindCrvlClosestPointFromS__FP4CRVLP6VECTORfP6CONSTRT1T1PfT6);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", LoadCrvcFromBrx__FP4CRVCP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", InvalidateCrvcCache__FP4CRVC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FillCrvcCache__FP4CRVCi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", EvaluateCrvcFromU__FP4CRVCfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", EvaluateCrvcFromS__FP4CRVCfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", RenderCrvcSegment__FP4CRVCiP7MATRIX4P2CMG4RGBAi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", ConvertCrvc__FP4CRVCP7MATRIX4T1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", SFromCrvcU__FP4CRVCf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", UFromCrvcS__FP4CRVCf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", MeasureCrvc__FP4CRVC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FindCrvcClosestPointAll__FP4CRVCP6VECTORP6CONSTRT1T1PfT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FindCrvcClosestPointFromU__FP4CRVCP6VECTORfP6CONSTRT1T1PfT6);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/crv\", FindCrvcClosestPointFromS__FP4CRVCP6VECTORfP6CONSTRT1T1PfT6);\n"
  },
  {
    "path": "src/P2/dart.c",
    "content": "#include <dart.h>\n#include <emitter.h>\n#include <jt.h>\n\nextern SNIP s_asnipDart[];\n\nvoid InitDart(DART *pdart)\n{\n    InitSo(pdart);\n    SetDartDarts(pdart, DARTS_Nil);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dart\", OnDartAdd__FP4DART);\n\nvoid RemoveDart(DART *pdart)\n{\n    RemoveLo(pdart);\n    AppendDlEntry(&pdart->psw->dlDartFree, pdart);\n    SetDartDarts(pdart, DARTS_AvailToFire);\n}\n\nvoid CloneDart(DART *pdart, DART *pdartBase)\n{\n    DLE dleDartFree = STRUCT_OFFSET(pdart, 0x56c, DLE); // pdart->dleDartFree\n    CloneSo(pdart, pdartBase);\n    STRUCT_OFFSET(pdart, 0x56c, DLE) = dleDartFree; // pdart->dleDartFree\n}\n\nvoid LoadDartFromBrx(DART *pdart, CBinaryInputStream *pbis)\n{\n    LoadSoFromBrx(pdart, pbis);\n    InferExpl(&STRUCT_OFFSET(pdart, 0x58c, EXPL *), pdart); // pdart->pexpl\n}\n\nvoid HandleDartMessage(DART *pdart, MSGID msgid, void *pv)\n{\n    HandleAloMessage(pdart, msgid, pv);\n    // pdart->pasegaSticking\n    if (msgid == MSGID_asega_retracted && (ASEGA *)pv == STRUCT_OFFSET(pdart, 0x578, ASEGA *))\n    {\n        STRUCT_OFFSET(pdart, 0x578, ASEGA *) = NULL;\n        SetDartDarts(pdart, DARTS_Stuck);\n    }\n}\n\nvoid PostDartLoad(DART *pdart)\n{\n    PostAloLoad(pdart);\n    SnipAloObjects(pdart, 1, s_asnipDart);\n}\n\nvoid UpdateDart(DART *pdart, float dt)\n{\n    UpdateSo(pdart, dt);\n\n    switch (STRUCT_OFFSET(pdart, 0x550, DARTS))\n    {\n        case DARTS_AvailToFire:\n        case DARTS_ReadyToFire:\n        case DARTS_Sticking:\n        case DARTS_Fading:\n        default:\n        {\n            break;\n        }\n        case DARTS_Airborne:\n        {\n            UpdateDartAirborne(pdart, dt);\n            break;\n        }\n        case DARTS_Stuck:\n        {\n            // pdart->dtMaxStuck, pdart->tDarts, g_pjt->phbsk\n            if (STRUCT_OFFSET(pdart, 0x568, float) < g_clock.t - STRUCT_OFFSET(pdart, 0x554, float) &&\n               (!g_pjt || (HBSK *)pdart->paloParent != STRUCT_OFFSET(g_pjt, 0x23b0, HBSK *)))\n            {\n                SetDartDarts(pdart, DARTS_Fading);\n            }\n            break;\n        }\n    }\n}\n\nvoid SetDartDarts(DART *pdart, DARTS darts)\n{\n    // pdart->darts\n    if (STRUCT_OFFSET(pdart, 0x550, DARTS) == darts)\n    {\n        return;\n    }\n\n    if (STRUCT_OFFSET(pdart, 0x550, DARTS) == DARTS_Airborne)\n    {\n        STRUCT_OFFSET(pdart, 0x57c, ALO *) = NULL; // pdart->paloTarget\n        STRUCT_OFFSET(pdart, 0x580, float) = 0.0f; // pdart->dtLaunchToTarget\n        STRUCT_OFFSET(pdart, 0x584, float) = 0.0f; // pdart->dzTarget\n        STRUCT_OFFSET(pdart, 0x588, DARTGUN *) = NULL; // pdart->pdartgunFiredFrom\n    }\n\n    STRUCT_OFFSET(pdart, 0x550, DARTS) = darts; // pdart->darts\n    STRUCT_OFFSET(pdart, 0x554, float) = g_clock.t; // pdart->tDarts\n\n    if (darts == DARTS_Fading)\n    {\n        FadeAloOut(pdart, STRUCT_OFFSET(pdart, 0x564, float)); // pdart->dtFade\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dart\", ApplyDartThrow__FP4DARTP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dart\", UpdateDartAirborne__FP4DARTf);\n"
  },
  {
    "path": "src/P2/dartgun.c",
    "content": "#include <dartgun.h>\n\nvoid InitDartgun(DARTGUN *pdartgun)\n{\n    InitBreak((BREAK *)pdartgun);\n    STRUCT_OFFSET(pdartgun, 0x6c0, OID) = OID_Nil; // pdartgun->oidDart\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", HandleDartgunMessage__FP7DARTGUN5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", BindDartgun__FP7DARTGUN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", FUN_0014f900);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", PostDartgunLoad__FP7DARTGUN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", UpdateDartgun__FP7DARTGUNf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", FIgnoreDartgunIntersection__FP7DARTGUNP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", BreakDartgun__FP7DARTGUN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", SetDartgunGoalState__FP7DARTGUN3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", TrackDartgun__FP7DARTGUNP3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", FPrepareDartgunToFire__FP7DARTGUN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", FireDartgun__FP7DARTGUN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", AgeDartgunStuckDart__FP7DARTGUN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", PratGetDartgunRatTarget__FP7DARTGUN);\n\n/**\n * @todo Cleanup once struct is implemented.\n */\nvoid AddDartgunRatTarget(DARTGUN *pdartgun, OID oid)\n{\n    if (STRUCT_OFFSET(pdartgun, 0x744, uint) >= 8)\n    {\n        return;\n    }\n\n    // pdartgun->aoidRatTarget[pdartgun->coidRatTarget++] = oid;\n    OID *aoidRatTarget = &STRUCT_OFFSET(pdartgun, 0x748, OID);\n    aoidRatTarget[STRUCT_OFFSET(pdartgun, 0x744, uint)++] = oid;\n}\n\nvoid StartDartgunTargetAreaChange(DARTGUN *pdartgun)\n{\n    STRUCT_OFFSET(pdartgun, 0x78c, int) = 0; // pdartgun->cpratInTargetArea\n    STRUCT_OFFSET(pdartgun, 0x7b0, int) = 0; // pdartgun->fJtInTargetArea\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dartgun\", AddDartgunTargetAreaTarget__FP7DARTGUNP3ALO);\n"
  },
  {
    "path": "src/P2/dialog.c",
    "content": "#include <dialog.h>\n#include <asega.h>\n#include <screen.h>\n#include <wipe.h>\n#include <sound.h>\n#include <ui.h>\n\nextern BLOT g_binoc;\n\nvoid InitDialog(DIALOG *pdialog)\n{\n    InitAlo(pdialog);\n    STRUCT_OFFSET(pdialog, 0x2c8, ulong) = STRUCT_OFFSET(pdialog, 0x2c8, ulong) | 0x100000000;\n    STRUCT_OFFSET(pdialog, 0x300, OID) = OID_Nil;\n    STRUCT_OFFSET(pdialog, 0x30c, OID) = OID_Nil;\n}\n\nvoid LoadDialogFromBrx(DIALOG *pdialog, CBinaryInputStream *pbis)\n{\n    LoadAloFromBrx(pdialog, pbis);\n    // pdialog->cde & pdialog->ade\n    LoadDialogEventsFromBrx(pdialog, pbis, &STRUCT_OFFSET(pdialog, 0x2dc, int), &STRUCT_OFFSET(pdialog, 0x2e0, DE *));\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dialog\", LoadDialogEventsFromBrx__FP6DIALOGP18CBinaryInputStreamPiPP2DE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dialog\", PostDialogLoad__FP6DIALOG);\n\nvoid SetDialogInstruct(DIALOG *pdialog)\n{\n    // pdialog->dialogk\n    STRUCT_OFFSET(pdialog, 0x2d0, DIALOGK) = DIALOGK_Instruct;\n}\n\nvoid SetDialogConfront(DIALOG *pdialog)\n{\n    // pdialog->dialogk\n    STRUCT_OFFSET(pdialog, 0x2d0, DIALOGK) = DIALOGK_Confront;\n}\n\nvoid GetDialogPlayed(DIALOG *pdialog, int *pfPlayed)\n{\n    // pdialog->pfPlayed\n    *pfPlayed = *STRUCT_OFFSET(pdialog, 0x304, int *);\n}\n\nvoid SetDialogPlayed(DIALOG *pdialog, int fPlayed)\n{\n    // pdialog->pfPlayed\n    *STRUCT_OFFSET(pdialog, 0x304, int *) = fPlayed;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dialog\", SetDialogDialogs__FP6DIALOG7DIALOGS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dialog\", UpdateDialog__FP6DIALOGf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dialog\", HandleDialogEvent__FP6DIALOGP2DE);\n\nvoid HandleDialogMessage(DIALOG *pdialog, MSGID msgid, void *pv)\n{\n    HandleAloMessage(pdialog, msgid, pv);\n    // pdialog->dp\n    if (msgid == MSGID_asega_retracted && (ASEGA *)pv == STRUCT_OFFSET(pdialog, 0x2e8, DP).pasegaLipsync)\n    {\n        STRUCT_OFFSET(pdialog, 0x2e8, DP).pasegaLipsync = NULL;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dialog\", FPauseDialog__FP6DIALOG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dialog\", FUN_001516c0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dialog\", HandleDialogEvents__FP6DIALOG);\n\nvoid FUN_00151860(DIALOG *pdialog, BLOT *pblot)\n{\n    if (pblot)\n    {\n        ((void (*)(BLOT *, DIALOG *))STRUCT_OFFSET(pblot->pvtblot, 0x158, void *))(pblot, pdialog);\n    }\n    else\n    {\n        BLOT *pbinoc = &g_binoc;\n        STRUCT_OFFSET(pbinoc, 0x324, DIALOG *) = pdialog;\n        PushUiActiveBlot(&g_ui, pbinoc);\n    }\n}\n\nvoid TriggerDialog(DIALOG *pdialog)\n{\n    NOTE *pnote = &g_note;\n\n    if (STRUCT_OFFSET(pnote, 0x260, int) >= 2)\n        return;\n\n    if (STRUCT_OFFSET(pnote, 0x26c, int) != 0)\n        return;\n\n    if (SetVagUnpaused())\n        return;\n\n    if (g_wipe.wipes == WIPES_WipingOut)\n        return;\n\n    if (pdialog == g_pdialogPlaying)\n        return;\n\n    DIALOGS dialogs = DIALOGS_Triggered;\n\n    if (*STRUCT_OFFSET(pdialog, 0x304, int *) != 0) // pdialog->pfPlayed\n    {\n        if (STRUCT_OFFSET(pdialog, 0x2d0, DIALOGK) != DIALOGK_Confront) // pdialog->dialogk\n        {\n            dialogs = DIALOGS_UnableToCall;\n        }\n        else\n        {\n            dialogs = STRUCT_OFFSET(pdialog, 0x2d4, DIALOGS); // pdialog->dialogs\n        }\n    }\n    else\n    {\n        int cpfEquivalence = STRUCT_OFFSET(pdialog, 0x310, int); // pdialog->cpfEquivalence\n\n        if (cpfEquivalence > 0)\n        {\n            for (int i = 0; i < cpfEquivalence; i++)\n            {\n                if (*STRUCT_OFFSET_INDEX(pdialog, 0x314, int *, i) != 0)\n                // pdialog->cpfEquivalenceArray[i]\n                {\n                    dialogs = DIALOGS_UnableToCall;\n                    break;\n                }\n            }\n        }\n    }\n\n    SetDialogDialogs(pdialog, dialogs);\n}\n\nvoid UntriggerDialog(DIALOG *pdialog)\n{\n    // pdialog->dialogs\n    if (STRUCT_OFFSET(pdialog, 0x2d4, DIALOGS) != DIALOGS_Triggered && STRUCT_OFFSET(pdialog, 0x2d4, DIALOGS) != DIALOGS_Playing)\n    {\n        SetDialogDialogs(pdialog, DIALOGS_Enabled);\n    }\n}\n\n"
  },
  {
    "path": "src/P2/difficulty.c",
    "content": "#include <difficulty.h>\n#include <transition.h>\n#include <sce/memset.h>\n#include <game.h>\n#include <coin.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/difficulty\", PdifficultyEnsureSw);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/difficulty\", FUN_00151A58);\n\nvoid OnDifficultyGameLoad(DIFFICULTY *pdifficulty)\n{\n    memset(pdifficulty, 0, sizeof(DIFFICULTY)); // note: DIFFICULTY should be 0x24 bytes\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/difficulty\", OnDifficultyWorldPreLoad);\n#ifdef SKIP_ASM\n/**\n * @todo 16.92% matched.\n */\nvoid OnDifficultyWorldPreLoad(DIFFICULTY *pdifficulty)\n{\n\tconst GS* gsCur = g_pgsCur;\n\tconst LS* lsCur = g_plsCur;\n\tconst int gameworld = (int)(gsCur->gameworldCur);\n\tconst int worldlevel = (int)(gsCur->worldlevelCur);\n\n\tDIFFICULTYLEVEL *difficultyProps;\n\n\tpdifficulty->ccoinRichMin = 4;\n\tpdifficulty->ccoinRichMax = 6;\n\tpdifficulty->ccoinPoorMax = 3;\n\tpdifficulty->ccoinPoorMin = 1;\n\n\tif (((gameworld == (int)GAMEWORLD_Intro) || (gameworld == (int)GAMEWORLD_Clockwerk)) || (worldlevel == (int)WORLDLEVEL_Hub))\n\t{ // Case: Current world is 0 or 5, or current level is a hub\n\t\tdifficultyProps = &g_difficultyEasy; // Set easy difficulty\n\t}\n\telse if (((int)lsCur->fls & (int)FLS_KeyCollected) == 0)\n\t{ // Case: Key NOT collected on current level\n\t\tdifficultyProps = &g_difficultyMedium; // set medium difficulty\n\t}\n\telse\n\t{ // Case: Key collected on current level\n\t\tdifficultyProps = &g_difficultyHard; // set hard difficulty\n\t}\n\n\tpdifficulty->pDifficultyLevel = difficultyProps;\n\n\tChangeSuck(lsCur->uSuck, pdifficulty);\n\tdifficultyProps = pdifficulty->pDifficultyLevel; // redundant?\n\n\t// todo: finish function\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/difficulty\", OnDifficultyWorldPostLoad);\n#ifdef SKIP_ASM\n/**\n * @todo 30.85% matched.\n */\nvoid OnDifficultyWorldPostLoad(DIFFICULTY *pdifficulty)\n{\n\tDIFFICULTYLEVEL *difficultyProps;\n\tint csuckCharms;\n\n\t// Case: The transition is a quit-game reload\n\tif ((g_transition.grftrans & 8) == 0)\n\t{\n\t\tconst float newSuck = GLimitLm((LM*)&pdifficulty->pDifficultyLevel->unk_lm_0x8, g_plsCur->uSuck);\n\t\tChangeSuck(newSuck, pdifficulty);\n\t}\n\t// Case: The ransition is not a quit-game reload\n\telse {\n\t\tdifficultyProps = pdifficulty->pDifficultyLevel;\n\n\t\t// Case: Suck value is BELOW charmLow or ABOVE charmHigh\n\t\tif ((g_plsCur->uSuck < difficultyProps->uSuckCharmLow) ||\n\t\t\t(difficultyProps->uSuckCharmHigh <= g_plsCur->uSuck))\n\t\t{\n\t\t\t// Suck value is lower than both thresholds\n\t\t\tif (g_plsCur->uSuck < difficultyProps->uSuckCharmHigh)\n\t\t\t{\n\t\t\t\tRemoveSwExtraneousCharms(g_psw);\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Suck value is not below the charmLow, so it must be above charmHigh\n\t\t\tcsuckCharms = difficultyProps->ccharmHigh;\n\t\t}\n\t\t// Case: Suck value is ABOVE charmLow but BELOW charmHigh\n\t\telse\n\t\t{\n\t\t\tcsuckCharms = difficultyProps->ccharmLow;\n\t\t}\n\n\t\tif (g_pgsCur->ccharm < csuckCharms)\n\t\t{\n\t\t\tSetCcharm(csuckCharms);\n\t\t\tpdifficulty->dps = DPS_GivenCharms;\n\t\t}\n\t}\n}\n#endif\n\nvoid OnDifficultyInitialTeleport(DIFFICULTY *pdifficulty)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/difficulty\", OnDifficultyPlayerDeath);\n#ifdef SKIP_ASM\n/**\n * @todo 88.43% matched.\n */\nvoid OnDifficultyPlayerDeath(float scalar, DIFFICULTY* pdifficulty)\n{\n\tDIFFICULTYLEVEL* pdifflevel = pdifficulty->pDifficultyLevel;\n\n\t// Get suck values for current level\n\tfloat uSuckCur = g_plsCur->uSuck;\n\tfloat duSuckDeath = pdifflevel->duSuckDeath;\n\n\t// Increase suck value\n\tChangeSuck(uSuckCur + scalar * duSuckDeath, pdifficulty);\n\n\t// Update suckunknown_0x10\n\tfloat result;\n\tif (g_pgsCur->clife < 0)\n\t{\n\t\t// itgame over\n\t\tresult = pdifficulty->pDifficultyLevel->field18_0x40;\n\t}\n\telse\n\t{\n\t\t// not game over\n\t\tresult = pdifflevel->field17_0x3c;\n\t\tif (g_pgsCur->clife <= pdifflevel->field21_0x4c)\n\t\t{\n\t\t\tresult = result + pdifflevel->field22_0x50;\n\t\t}\n\t}\n\tresult = GLimitLm(&g_lmZeroOne, g_plsCur->unk_suck_0x10 + scalar * result);\n\tg_plsCur->unk_suck_0x10 = result;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/difficulty\", OnDifficultyTriggerCheckpoint__FP10DIFFICULTYP6CHKPNT);\n#ifdef SKIP_ASM\n/**\n * @todo 3.33% matched.\n */\nvoid OnDifficultyTriggerCheckpoint(DIFFICULTY *pdifficulty, CHKPNT *pchkpnt)\n{\n\tDIFFICULTYLEVEL *pdifflevel;\n\n\tif (!pchkpnt)\n\t{\n\t\tpdifflevel = pdifficulty->pDifficultyLevel;\n\t}\n\n\t// todo: implement CHKPNT struct and finish this function\n\t// ...\n}\n#endif\n\nvoid OnDifficultyCollectKey(DIFFICULTY *pdifficulty)\n{\n\tChangeSuck(0.0f, pdifficulty);\n\n\tg_plsCur->unk_suck_0x10 = 0.0f;\n\tg_plsCur->unk_field_0x70 = 0;\n\n\tmemset(&g_plsCur->unk_field_0x74, 0, 1);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/difficulty\", OnDifficultyBreak);\n\nvoid ChangeSuck(float nParam, DIFFICULTY *pdifficulty)\n{\n    g_plsCur->uSuck = GLimitLm(&pdifficulty->pDifficultyLevel->suck_lm, nParam);\n}\n"
  },
  {
    "path": "src/P2/dl.c",
    "content": "#include <dl.h>\n\nextern DLI *s_pdliFirst; // Global iterator list.\n\nvoid InitDl(DL *pdl, int ibDle)\n{\n    pdl->ibDle = ibDle;\n}\n\nvoid ClearDl(DL *pdl)\n{\n    pdl->tail = NULL;\n    pdl->head = NULL;\n}\n\nvoid ClearDle(DLE *pdle)\n{\n    pdle->prev = NULL;\n    pdle->next = NULL;\n}\n\nDLE *PdleFromDlEntry(DL *pdl, void *pv)\n{\n    return (DLE *)((uchar *)pv + pdl->ibDle);\n}\n\nvoid AppendDlEntry(DL *pdl, void *pv)\n{\n    DLE *newEntry = PdleFromDlEntry(pdl, pv);\n    if (!pdl->tail)\n    {\n        pdl->head = pv;\n    }\n    else\n    {\n        DLE *currentTail = PdleFromDlEntry(pdl, pdl->tail);\n        newEntry->prev = pdl->tail;\n        currentTail->next = pv;\n    }\n    pdl->tail = pv;\n}\n\nvoid PrependDlEntry(DL *pdl, void *pv)\n{\n    DLE *newEntry = PdleFromDlEntry(pdl, pv);\n    if (!pdl->head)\n    {\n        pdl->tail = pv;\n        pdl->head = pv;\n    }\n    else\n    {\n        DLE *currentHead = PdleFromDlEntry(pdl, pdl->head);\n        newEntry->next = pdl->head;\n        currentHead->prev = pv;\n        pdl->head = pv;\n    }\n}\n\nvoid InsertDlEntryBefore(DL *pdl, void *pvNext, void *pv)\n{\n    if (!pvNext)\n    {\n        AppendDlEntry(pdl, pv);\n    }\n    else if (pvNext == pdl->head)\n    {\n        PrependDlEntry(pdl, pv);\n    }\n    else\n    {\n        DLE *newEntry = PdleFromDlEntry(pdl, pv);\n        DLE *nextEntry = PdleFromDlEntry(pdl, pvNext);\n        void *prevEntryPointer = nextEntry->prev;\n        DLE *prevEntry = PdleFromDlEntry(pdl, prevEntryPointer);\n        newEntry->next = pvNext;\n        newEntry->prev = prevEntryPointer;\n        nextEntry->prev = pv;\n        prevEntry->next = pv;\n    }\n}\n\nJUNK_NOP();\nJUNK_ADDIU(60);\n\nvoid RemoveDlEntry(DL *pdl, void *pv)\n{\n    DLE *pentry = PdleFromDlEntry(pdl, pv);\n    DLI *pcurrent = s_pdliFirst;\n\n    // Loop through global iterator list to find DLI that houses the DLE we're looking for.\n    while (pcurrent)\n    {\n        if ((DLE *)pcurrent->m_ppv == pentry)\n        {\n            // If the DLE is the current index of the DLI, replace the with prev.\n            void *pprev = pentry->prev;\n            if (pprev)\n            {\n                (DLE *)pcurrent->m_ppv = PdleFromDlEntry(pdl, pprev);\n            }\n            else\n            {\n                (DLE *)pcurrent->m_ppv = pdl;\n            }\n        }\n\n        pcurrent = pcurrent->m_pdliNext;\n    }\n\n    // Adjust head\n    void *pprev = pentry->prev;\n    if (pprev)\n    {\n        DLE *pdle = PdleFromDlEntry(pdl, pprev);\n        pdle->next = pentry->next;\n    }\n    else\n    {\n        pdl->head = pentry->next;\n    }\n\n    // Adjust tail\n    pprev = pentry->next;\n    if (pprev)\n    {\n        DLE *pdle = PdleFromDlEntry(pdl, pprev);\n        pdle->prev = pentry->prev;\n    }\n    else\n    {\n        pdl->tail = pentry->prev;\n    }\n\n    // Clear links\n    pentry->next = NULL;\n    pentry->prev = NULL;\n}\n\nbool FFindDlEntry(DL *pdl, void *pv)\n{\n    DLE *pdle = PdleFromDlEntry(pdl, pv);\n    return (pdle->next) || (pdl->tail == pv);\n}\n\nbool FIsDlEmpty(DL *pdl)\n{\n    return !pdl->head;\n}\n\nvoid MergeDl(DL *pdlDst, DL *pdlSrc)\n{\n    if (!pdlSrc->head)\n        return;\n\n    if (!pdlDst->head)\n    {\n        memcpy(pdlDst, pdlSrc, 12);\n        ClearDl(pdlSrc);\n        return;\n    }\n\n    DLE *pdstTail = PdleFromDlEntry(pdlDst, pdlDst->tail);\n    DLE *psrcHead = PdleFromDlEntry(pdlSrc, pdlSrc->head);\n\n    pdstTail->next = pdlSrc->head;\n    psrcHead->prev = pdlDst->tail;\n\n    pdlDst->tail = pdlSrc->tail;\n    ClearDl(pdlSrc);\n}\n\nint CPvDl(DL *pdl)\n{\n    void *pCurItem = pdl->head;\n    int iCount = 0;\n\n    while (pCurItem)\n    {\n        DLE *pDle = (DLE *)((uchar *)pCurItem + pdl->ibDle);\n        pCurItem = pDle->next;\n        iCount++;\n    }\n\n    return iCount;\n}\n"
  },
  {
    "path": "src/P2/dmas.c",
    "content": "#include <dmas.h>\n#include <sce/libdma.h>\n#include <sdk/ee/eestruct.h>\n\nextern sceDmaChan *g_pdcVif0;\nextern sceDmaChan *g_pdcVif1;\nextern sceDmaChan *g_pdcGif;\nextern sceDmaChan *g_pdcFromSpr;\nextern sceDmaChan *g_pdcToSpr;\n\nvoid StartupDma()\n{\n    sceDmaReset(1);\n    sceGsResetPath();\n    g_pdcVif0 = sceDmaGetChan(0);\n    g_pdcVif1 = sceDmaGetChan(1);\n    g_pdcGif = sceDmaGetChan(2);\n    g_pdcFromSpr = sceDmaGetChan(8);\n    g_pdcToSpr = sceDmaGetChan(9);\n}\n\nDMAS::DMAS()\n{\n    m_fPad = 0;\n    m_fEndPrim = 0;\n    Clear();\n}\n\nvoid DMAS::Clear()\n{\n    m_pbMax = NULL;\n    m_ab = NULL;\n    m_pqwCnt = NULL;\n    m_pb = NULL;\n}\n\nvoid DMAS::Reset()\n{\n    m_pqwCnt = NULL;\n    m_pb = m_ab;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AllocGlobal__4DMASi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AllocSw__4DMASii);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AllocStack__4DMASi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AllocStatic__4DMASiP2QW);\n\nvoid DMAS::Detach(int *pcqw, QW **paqw)\n{\n    EndDmaCnt();\n    if (pcqw)\n    {\n        *pcqw = (uint)(m_pb - m_ab) >> 4;\n    }\n    if (paqw)\n    {\n        *paqw = (QW *)m_ab;\n    }\n    Clear();\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", DetachCopySw__4DMASPiPP2QWT2i);\n\nvoid DMAS::Send(sceDmaChan *chan)\n{\n    EndDmaCnt();\n    FlushCache(WRITEBACK_DCACHE);\n    sceDmaSend(chan, m_ab);\n    m_pb = m_ab;\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AddDmaCnt__4DMAS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AddDmaRefs__4DMASiP2QW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AddDmaCall__4DMASP2QW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AddDmaRet__4DMAS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AddDmaBulk__4DMASiP2QW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", AddDmaEnd__4DMAS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dmas\", EndDmaCnt__4DMAS);\n\nvoid DMAS::EndPrim()\n{\n    return;\n}\n\nJUNK_WORD(0x00021102);\n"
  },
  {
    "path": "src/P2/dysh.c",
    "content": "#include <dysh.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dysh\", InitDysh__FP4DYSH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dysh\", SetDyshShadow__FP4DYSHP6SHADOW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dysh\", RenderDyshSelf__FP4DYSHP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dysh\", DrawDysh__FP3RPL);\n"
  },
  {
    "path": "src/P2/dzg.c",
    "content": "#include <dzg.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dzg\", InitDzg__FP3DZGi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dzg\", ClearDzgSolution__FP3DZG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dzg\", AppendDzgDz__FP3DZGP2DZ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dzg\", FillDzgDz__FP3DZGiP2DZiPP2XPPiPPP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dzg\", EnforceDzgDz__FP3DZGP2DZ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dzg\", SolveDzg__FP3DZGiiPP2XPPiPPP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dzg\", SolveDzgFric__FP3DZGiiPP2XPPiPPP2SOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dzg\", ApplyDzg__FP3DZGiPiPPP2SOff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/dzg\", SolveInequalities__FiPfN21);\n"
  },
  {
    "path": "src/P2/emitter.c",
    "content": "#include <emitter.h>\n\nextern float DAT_0024a124;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", InitEmitb__FP5EMITB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", InitEmitter__FP7EMITTER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", LoadEmitmeshFromBrx__FP8EMITMESHP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", LoadEmitblipColorsFromBrx__FP8EMITBLIPiP2LOP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", LoadEmitterFromBrx__FP7EMITTERP18CBinaryInputStream);\n\nvoid CloneEmitter(EMITTER *pemitter, EMITTER *pemitterBase)\n{\n    CloneAlo(pemitter, pemitterBase);\n    STRUCT_OFFSET(pemitter, 0x2d0, EMITB *)->cref++;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", BindEmitterCallback__FP7EMITTER5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", BindEmitter__FP7EMITTER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", PostEmitterLoad__FP7EMITTER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", HandleEmitterMessage__FP7EMITTER5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", PemitbCopyOnWrite__FP5EMITB);\n\nEMITB *PemitbEnsureEmitter(EMITTER *pemitter, ENSK ensk)\n{\n    if (ensk == ENSK_Set)\n    {\n        STRUCT_OFFSET(pemitter, 0x34c, int) = 1; // pemitter->fValuesChanged\n        STRUCT_OFFSET(pemitter, 0x2d0, EMITB *) = PemitbCopyOnWrite(STRUCT_OFFSET(pemitter, 0x2d0, EMITB *));\n    }\n\n    return STRUCT_OFFSET(pemitter, 0x2d0, EMITB *); // pemitter->pemitb\n}\n\nEMITTER *PemitterEnsureEmitter(EMITTER *pemitter, ENSK ensk)\n{\n    if (ensk == ENSK_Set)\n    {\n        STRUCT_OFFSET(pemitter, 0x34c, int) = 1; // pemitter->fValuesChanged\n    }\n\n    return pemitter;\n}\n\nvoid AddEmitterSkeleton(EMITTER *pemitter, OID oid, OID oidOther, float sRadius, float gDensity, float sRadiusOther, float gDensityOther)\n{\n    EMITB *pemitb = PemitbEnsureEmitter(pemitter, ENSK_Set);\n    AddEmitoSkeleton(&pemitb->emito, oid, oidOther, sRadius, gDensity, sRadiusOther, gDensityOther, pemitter);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", ModifyEmitterParticles__FP7EMITTER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", UpdateEmitter__FP7EMITTERf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", FUN_00155f28);\n\nvoid PauseEmitter(EMITTER *pemitter, float dtPause)\n{\n    STRUCT_OFFSET(pemitter, 0x340, float) = g_clock.t + dtPause; // pemitter->tUnpause\n}\n\nvoid PauseEmitterIndefinite(EMITTER *pemitter)\n{\n    STRUCT_OFFSET(pemitter, 0x340, float) = DAT_0024a124; // pemitter->tUnpause\n}\n\nvoid UnpauseEmitter(EMITTER *pemitter)\n{\n    STRUCT_OFFSET(pemitter, 0x340, float) = -1.0f; // pemitter->tUnpause\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", FPausedEmitter__FP7EMITTER);\n\nvoid SetEmitterEnabled(EMITTER *pemitter, int fEnabled)\n{\n    if (fEnabled)\n    {\n        UnpauseEmitter(pemitter);\n        return;\n    }\n\n    PauseEmitterIndefinite(pemitter);\n}\n\nvoid GetEmitterEnabled(EMITTER *pemitter, int *pfEnabled)\n{\n    *pfEnabled = !FPausedEmitter(pemitter);\n}\n\nvoid GetEmitterPaused(EMITTER *pemitter, int *pfPaused)\n{\n    *pfPaused = FPausedEmitter(pemitter);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", OnEmitterValuesChanged__FP7EMITTER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", SetEmitterParticleCount__FP7EMITTERi);\n\nvoid SetEmitterAutoPause(EMITTER *pemitter, int fAutoPause)\n{\n    STRUCT_OFFSET(pemitter, 0x308, int) = fAutoPause; // pemitter->fAutoPause\n    STRUCT_OFFSET(pemitter, 0x34c, int) = 1; // pemitter->fValuesChanged\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", SetEmitbRipt__FP5EMITB4RIPT);\n\nvoid SetEmitterRipt(EMITTER *pemitter, RIPT ript)\n{\n    EMITB *pemitb = PemitbEnsureEmitter(pemitter, ENSK_Set);\n    SetEmitbRipt(pemitb, ript);\n}\n\nvoid SetExploRipt(EXPLO *pexplo, RIPT ript)\n{\n    EMITB *pemitb = PemitbEnsureExplo(pexplo, ENSK_Set);\n    SetEmitbRipt(pemitb, ript);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", WakeSoWater__FP2SOP5WATERfP6VECTORT3ff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", StandardSmokeCloud__FP6VECTORf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", ChooseEmitoPos__FP5EMITOiiP6VECTORT3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", ConvertEmitoPosVec__FP5EMITOP6VECTORT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", CalculateEmitvx__FiP2LMiP6EMITVX);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", ChooseEmitVelocity__FP6EMITVXffP2LMP6VECTORiT4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", ChooseEmitvVelocityAge__FP5EMITVP6EMITVXP5EMITOiP6VECTORN24PfT7);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", EmitRips__FP5EMITBP5EMITGiP6VECTORT3PfT5);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", EmitBlips__FP5EMITBP5EMITGiP6VECTORT3PfT5T3T3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", OriginateParticles__FiP5EMITBP7EMITGEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", OriginateSplineSinkParticles__FiP5EMITBR7EMITGENT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", EmitParticles__FiP5EMITBP5EMITG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", EmitRipsSphere__FP6VECTORT0iP7EMITRIPP5EMITVPP4RIPGP2LO);\n\nJUNK_WORD(0x27bd0290); // junk_00157FF0\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", StockSplashBig__FP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", StockSplashSmall__FP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", AddEmitoSkeleton__FP5EMITO3OIDT1ffffP2LO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", BindEmitb__FP5EMITBP2LO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", SetEmitdvEmitb__FP6EMITDVP5EMITB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", CalculateEmitdvMatrix__FP6EMITDVfP7MATRIX4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", PostExplLoad__FP4EXPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", CalculateExplTransform__FP4EXPLP6VECTORP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", ExplodeExpl__FP4EXPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", ExplodeExplParams__FP4EXPLUiP3ALOP6VECTORT3ff);\n\nvoid ExplodeExplExplso(EXPL *pexpl, EXPLSO *pexplso)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", LoadExplgFromBrx__FP5EXPLGP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", CloneExplg__FP5EXPLGT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", BindExplg__FP5EXPLG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", ExplodeExplgExplso__FP5EXPLGP6EXPLSO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", InitExplo__FP5EXPLO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", LoadExploFromBrx__FP5EXPLOP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", CloneExplo__FP5EXPLOT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", BindExplo__FP5EXPLO);\n\nvoid ExplodeExploExplso(EXPLO *pexplo, EXPLSO *pexplso)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", AddExploSkeleton__FP5EXPLO3OIDT1ffff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", PemitbEnsureExplo__FP5EXPLO4ENSK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", InitExpls__FP5EXPLS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", BindExpls__FP5EXPLS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", HandleExplsMessage__FP5EXPLS5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", ExplodeExplsExplso__FP5EXPLSP6EXPLSO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", PsfxEnsureExpls__FP5EXPLS4ENSK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", FireExplsExplso__FP5EXPLSP6EXPLSO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", InferExpl__FPP4EXPLP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/emitter\", FireSwTimedExplodeStyles__FP2SW);\n\n// junk_00159668\nJUNK_ADDIU(10);\nJUNK_WORD(0x7c450000);\nJUNK_WORD(0x48220800);\n"
  },
  {
    "path": "src/P2/eyes.c",
    "content": "#include <eyes.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/eyes\", InitEyes__FP4EYESP4SAAF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/eyes\", PostEyesLoad__FP4EYES);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/eyes\", SetEyesEyess__FP4EYES5EYESS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/eyes\", UpdateEyes__FP4EYESf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/eyes\", SetEyesClosed__FP4EYESf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/eyes\", PsaiFromEyesShd__FP4EYESP3SHD);\n"
  },
  {
    "path": "src/P2/fader.c",
    "content": "#include <fader.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fader\", UpdateFader__FP5FADERf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fader\", PfaderNew__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fader\", RemoveFader__FP5FADER);\n"
  },
  {
    "path": "src/P2/find.c",
    "content": "#include <find.h>\n\nDL *PdlFromSwOid(SW *psw, OID oid)\n{\n    return &psw->adlHash[(oid * 0x95675) & 0x1ff];\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/find\", MatchSwObject__FP2LOiiiT0iPiPP2LOT6);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/find\", CploFindSwObjects__FP2SWi3OIDP2LOiPP2LO);\n\nLO *PloFindSwObject(SW *psw, GRFFSO grffso, OID oid, LO *ploContext)\n{\n    LO *aplo = NULL;\n    CploFindSwObjects(psw, grffso | FSO_ReturnActualCount, oid, ploContext, 1, &aplo);\n    return aplo;\n}\n\nLO *PloFindSwNearest(SW *psw, OID oid, LO *ploContext)\n{\n    LO *aplo = NULL;\n    CploFindSwObjects(psw, FSO_ReturnActualCount | FSO_FindNearest, oid, ploContext, 1, &aplo);\n    return aplo;\n}\n\nLO *PloFindSwChild(SW *psw, OID oid, ALO *paloAncestor)\n{\n    LO *aplo = NULL;\n    CploFindSwObjects(psw, FSO_ReturnActualCount | FSO_FindChild, oid, paloAncestor, 1, &aplo);\n    return aplo;\n}\n\nint FIsCidDerivedFrom(CID cid, CID cidAncestor)\n{\n    void **ppv = (&g_mpcidpvt)[cid];\n    while (ppv)\n    {\n        if (ppv[1] == (void *)cidAncestor)\n        {\n            return 1;\n        }\n\n        ppv = (void **)*ppv;\n    }\n\n    return 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/find\", CploFindSwObjectsByClass__FP2SWi3CIDP2LOiPP2LO);\n\nLO *PloFindSwObjectByClass(SW *psw, GRFFSO grffso, CID cid, LO *ploContext)\n{\n    LO *aplo = NULL;\n    CploFindSwObjectsByClass(psw, grffso | FSO_ReturnActualCount, cid, ploContext, 1, &aplo);\n    return aplo;\n}\n\nALO *PaloFindLoCommonParent(LO *plo, LO *ploOther)\n{\n    while (plo)\n    {\n        ALO *current = (ALO *)ploOther;\n        while (current)\n        {\n            if (plo == current)\n            {\n                return (ALO *)plo;\n            }\n\n            current = (ALO *)current->paloParent;\n        }\n\n        plo = (LO *)plo->paloParent;\n    }\n\n    return NULL;\n}\n"
  },
  {
    "path": "src/P2/flash.c",
    "content": "#include <flash.h>\n#include <clock.h>\n#include <tn.h>\n\n// NOTE: Could also belong to P2/find.c.\nJUNK_ADDIU(60);\n\nvoid InitFlash(FLASH *pflash)\n{\n    InitAlo(pflash);\n\n    pflash->gScaleTarget = 1.0f;\n    pflash->gScaleCur = 1.0f;\n\n    SMP *psmpScale = &pflash->smpScale;\n    psmpScale->svFast = 1.0f;\n    psmpScale->svSlow = 0.2f;\n    psmpScale->dtFast = 0.1f;\n}\n\nvoid LoadFlashFromBrx(FLASH *pflash, CBinaryInputStream *pbis)\n{\n    LoadAloFromBrx(pflash, pbis);\n    LoadTbspFromBrx(pbis, &pflash->ctsurf, &pflash->atsurf, &pflash->ctbsp, &pflash->atbsp);\n}\n\nvoid UpdateFlash(FLASH *pflash, float dt)\n{\n    UpdateAlo(pflash, dt);\n    pflash->gScaleCur = GSmooth(pflash->gScaleCur, pflash->gScaleTarget, g_clock.dt, &pflash->smpScale, 0);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/flash\", RenderFlashSelf__FP5FLASHP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/flash\", FPosFlashWithin__FP5FLASHP6VECTOR);\n"
  },
  {
    "path": "src/P2/fly.c",
    "content": "#include <fly.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", InitFly__FP3FLY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", LoadFlyFromBrx__FP3FLYP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", CloneFly__FP3FLYT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", FreezeFly__FP3FLYi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", PostFlyLoad__FP3FLY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", PresetFlyAccel__FP3FLYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", UpdateFly__FP3FLYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", RenderFlySelf__FP3FLYP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", FAbsorbFlyWkr__FP3FLYP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", SetFlyFlys__FP3FLY4FLYS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", EmitFlyDroppings__FP3FLY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", FFindFlyClosestLandingPos__FP3FLYP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", FlysAttemptedFlyLanding__FP3FLY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", FShouldFlyFlee__FP3FLY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", FFilterFly__FPvP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/fly\", FCheckFlyOpenSpaceBelow__FP3FLY);\n"
  },
  {
    "path": "src/P2/font.c",
    "content": "#include <font.h>\n#include <memory.h>\n\nvoid StartupFont()\n{\n    g_pfont = NULL;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", FUN_0015c188);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", FUN_0015c1c0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", FUN_0015c200);\n\nvoid CFont::CopyTo(CFont *pfontDest)\n{\n    pfontDest->m_dxCharUnscaled = this->m_dxCharUnscaled;\n    pfontDest->m_dxSpaceUnscaled = this->m_dxSpaceUnscaled;\n    pfontDest->m_dyUnscaled = this->m_dyUnscaled;\n    pfontDest->m_rxScale = this->m_rxScale;\n    pfontDest->m_ryScale = this->m_ryScale;\n    pfontDest->m_csfr = this->m_csfr;\n    CopyAb(&pfontDest->m_asfr, &this->m_asfr, this->m_csfr * 8);\n    pfontDest->m_fGstest = this->m_fGstest;\n    pfontDest->m_gstest = this->m_gstest;\n    pfontDest->m_z = this->m_z;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", SetupDraw__5CFontP8CTextBoxP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", CleanupDraw__5CFontP8CTextBoxP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", DxFromPchz__5CFontPc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", DyWrapPchz__5CFontPcf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", ClineWrapPchz__5CFontPcf);\n\nJUNK_ADDIU(50);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", DrawPchz__5CFontPcP8CTextBoxT2P4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", PushScaling__5CFontff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", PopScaling__5CFont);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", PfontClone__8CFontBrxff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", CopyTo__8CFontBrxP8CFontBrx);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", FValid__8CFontBrxc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", DxFromCh__8CFontBrxc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", FEnsureLoaded__8CFontBrxP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", SetupDraw__8CFontBrxP8CTextBoxP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", SwitchTex0__8CFontBrxP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", DxDrawCh__8CFontBrxcffUiP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", FUN_0015cf70);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", DrawPart__8CFontBrxffffffffUiP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", EdgeRect__8CFontBrxP9CTextEdgeP8CTextBoxP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", LoadFromBrx__8CFontBrxP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", PostLoad__8CFontBrxP3GSB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", PglyffFromCh__8CFontBrxc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", __9CRichTextPcP5CFont);\n\nvoid CRichText::Reset()\n{\n    this->m_pchCur = this->m_achz;\n    this->m_pfontCur = this->m_pfontBase;\n    this->m_rgbaSet = this->m_rgbaBase;\n    this->m_rgbaCur = this->m_rgbaSet;\n    this->m_unknown = 0;\n}\n\nvoid CRichText::SetBaseColor(RGBA *rgba)\n{\n    this->m_rgbaBase = *rgba;\n    this->m_rgbaCur = this->m_rgbaBase;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", ChNext__9CRichText);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", Cch__9CRichText);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", Trim__9CRichTexti);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", Dx__9CRichText);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", ClineWrap__9CRichTextf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", FUN_0015e1b0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", DxMaxLine__9CRichText);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", GetExtents__9CRichTextPfT1f);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", Draw__9CRichTextP8CTextBoxT1P4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/font\", PostFontsLoad__Fv);\n\nJUNK_WORD(0x46000802);\nJUNK_WORD(0x46000802);\nJUNK_WORD(0x46000802);\nJUNK_ADDIU(10);\nJUNK_WORD(0x0002102A);\nJUNK_WORD(0xAC850030);\n"
  },
  {
    "path": "src/P2/freeze.c",
    "content": "#include <freeze.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", RemergeSwObject__FP2SWP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", MergeSwFreezeGroups__FP2SWP3ALOT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", SplinterSwFreezeGroup__FP2SWP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", MergeSwGroup__FP2SWP3MRG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", AddSwMergeGroup__FP2SWP3MRG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", RemoveFromArray__FPiPPvPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", RemoveSwMergeGroup__FP2SWP3MRG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", RemergeSwObjects__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", FreezeAloHierarchy__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", GetAloFrozen__FP3ALOPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", FreezeAlo__FP3ALOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", FreezeSo__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", RefreezeSwObjects__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/freeze\", UpdateSwBusyList__FP2SW);\n"
  },
  {
    "path": "src/P2/frm.c",
    "content": "#include <frm.h>\n#include <gs.h>\n#include <dmas.h>\n#include <vifs.h>\n#include <gifs.h>\n#include <phasemem.h>\n#include <sce/libdma.h>\n#include <sdk/ee/eekernel.h>\n\nextern void *g_pvVu1Code;\n\n// TODO: Should these be defined here?\nextern SLI *g_psliCur;\nextern QW *g_aqwGifsBackgroundUpload;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", VU1_Interrupt__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", StartupFrame__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", OpenFrame__Fv);\n#ifdef SKIP_ASM\n/**\n * @todo 11.12% matched.\n * Missing some global data definitions.\n */\nvoid OpenFrame()\n{\n\tSetPhase(PHASE_Main);\n\t//WaitSema(DAT_002623b4);\n\n\t// int i = g_ifrmMax * 72;\n\t// g_ifrmMax += 1;\n\n\t// ...\n\n\t// ClearPendingFrame(g_pfrmOpen);\n\n\t// ...\n}\n#endif\n\nvoid EnsureVu1Code(VIFS *pvifs, void *pvStart, void *pvEnd)\n{\n    if (g_pvVu1Code != pvStart)\n    {\n        g_pvVu1Code = pvStart;\n        uint cqw = (uint)((byte *)pvEnd - (byte *)pvStart + 0x0f) >> 0x04;\n        pvifs->AddDmaRefs(cqw, (QW *)pvStart);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", FinalizeFrameVifs__FP4VIFSPiPP2QW);\n\nvoid FinalizeFrameGifs(GIFS *pgifs, int *pcqwGifs, QW **ppqwGifs)\n{\n    pgifs->AddPrimPack(0, 1, 0x0e);\n    pgifs->PackAD(0x61, 0);\n    pgifs->AddPrimEnd();\n    pgifs->AddDmaEnd();\n    pgifs->Detach(pcqwGifs, ppqwGifs);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", CloseFrame__Fv);\n\nvoid PrepareGsForFrameRender(FRM *pfrm)\n{\n    g_psliCur = pfrm->asli;\n    PropagateShaders(pfrm->grfzon);\n\n    if (pfrm->fBackgroundUploadRequired && g_aqwGifsBackgroundUpload)\n    {\n        *((volatile uint *)0x10003010) = 4; // REG_GIF_MODE\n        sceDmaSend(g_pdcGif, g_aqwGifsBackgroundUpload);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", check_anticrack_antigrab__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", FrameRenderLoop__FPv);\n\nvoid RenderFrame(FRM *pfrm, int fRenderGifs)\n{\n    PrepareGsForFrameRender(pfrm);\n    SendDmaSyncGsFinish(g_pdcVif1, pfrm->aqwVifs);\n    if (fRenderGifs)\n    {\n        *((volatile uint *)0x10003010) = 0; // REG_GIF_MODE\n        SendDmaSyncGsFinish(g_pdcGif, pfrm->aqwGifs);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", ClearPendingFrame__FP3FRM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", FlushFrames__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", BlendPrevFrame__Fv);\n\n/**\n * @note These are automatically generated static initalization functions.\n * Once the appropriate functions are matched these can be removed.\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", func_0015F618);\nINCLUDE_ASM(\"asm/nonmatchings/P2/frm\", func_0015F658);\n"
  },
  {
    "path": "src/P2/frzg.c",
    "content": "#include <frzg.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frzg\", PostFrzgLoad__FP4FRZG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/frzg\", AddFrzgObject__FP4FRZG3OID);\n"
  },
  {
    "path": "src/P2/game.c",
    "content": "#include <game.h>\n#include <joy.h>\n#include <wipe.h>\n#include <chkpnt.h>\n#include <difficulty.h>\n#include <sce/memset.h>\n\n// I know these functions are here somewhere but I don't know which one they are. -Zac\n// void SetClife(int nParam)\n// {\n//  g_pgsCur->clife = nParam;\n// }\n// void ClearLs(LS* pls)\n// {\n//  memset(pls, 0, sizeof(LS));\n// }\n// void SetCcoin(int nParam)\n// {\n//  g_pgsCur->ccoin = nParam;\n// }\n// void OnGameLoad(GAME* pgame)\n// {\n//  memset(pgame, 0, sizeof(GAME));\n// }\n\nextern WORLDLEVEL g_worldlevelPrev;\n\nvoid StartupGame()\n{\n    StartGame();\n}\n\nJUNK_NOP();\nJUNK_WORD(0x00E0102D);\nJUNK_WORD(0x0000102D);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", search_level_by_load_data);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", search_level_by_id);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", PchzFriendlyFromWid);\n\nJUNK_WORD(0x24420010);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", call_search_level_by_id);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", FFindLevel);\n\nJUNK_WORD(0x24420010);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", get_level_completion_by_id);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", tally_world_completion);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", get_game_completion__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", UnlockIntroCutsceneFromWid__Fi);\n#ifdef SKIP_ASM\n/**\n * @todo Close to matching but there's a problem with the rodata.\n */\nvoid UnlockIntroCutsceneFromWid(int wid)\n{\n    /* Check the unlocked cutscene by setting the corresponding\n       flag on the unlocked_cutscenes in the game state */\n    switch (wid)\n    {\n    case 1:\n        /* Unlock cutscene \"Tide of Terror\" */\n        g_pgsCur->unlocked_cutscenes = g_pgsCur->unlocked_cutscenes | 0x10;\n        return;\n    case 2:\n        /* Unlock cutscene \"Sunset Snake Eyes\" */\n        g_pgsCur->unlocked_cutscenes = g_pgsCur->unlocked_cutscenes | 0x40;\n        return;\n    case 3:\n        /* Unlock cutscene \"Vicious Voodoo\" */\n        g_pgsCur->unlocked_cutscenes = g_pgsCur->unlocked_cutscenes | 0x100;\n        return;\n    case 4:\n        /* Unlock cutscene \"Fire in the Sky\" */\n        g_pgsCur->unlocked_cutscenes = g_pgsCur->unlocked_cutscenes | 0x400;\n        return;\n    case 5:\n        /* Unlock cutscene \"The Cold Heart of Hate\" */\n        g_pgsCur->unlocked_cutscenes = g_pgsCur->unlocked_cutscenes | 0x1000;\n    }\n}\n#endif // SKIP_ASM\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", DefeatBossFromWid);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", UnlockEndgameCutscenesFromFgs);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", PlayEndingFromCompletionFlags);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", InitGameState__FP2GS);\n/**\n * @todo 86.46% matched.\n */\n#ifdef SKIP_ASM\nvoid InitGameState(GS *pgs)\n{\n    memset(pgs, 0, sizeof(GS));\n    pgs->gameworldCur = GAMEWORLD_Intro;\n    pgs->grfvault = 0;\n    pgs->gsv = 0x12;\n    pgs->cbThis = sizeof(GS);\n    pgs->worldlevelCur = WORLDLEVEL_Level2;\n    pgs->clife = 5;\n    pgs->fspLast = -1;\n    // todo: implement function (name is wrong)\n    // reset_settings(pgs);\n}\n#endif // SKIP_ASM\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", FUN_00160650);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", SetupGame__FPci);\n\nvoid UpdateGameState(float dt)\n{\n    g_pgsCur->dt += dt;\n    g_pwsCur->dt += dt;\n    g_plsCur->dt += dt;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", LsFromWid);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", GrflsFromWid__F3WID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", UnloadGame__Fv);\n#ifdef SKIP_ASM\n/**\n * @todo 60.42% matched.\n */\nvoid UnloadGame()\n{\n    InitGameState(g_pgsCur);\n    // unk_gs? = NULL;\n    // clr_8_bytes_1(&DAT_002623d8);\n    OnDifficultyGameLoad(&g_difficulty);\n    g_grfcht = (GRFCHT)FCHT_None;\n    g_worldlevelPrev = WORLDLEVEL_Nil;\n    RetryGame();\n}\n#endif // SKIP_ASM\n\nvoid RetryGame()\n{\n    g_pgsCur->clife = 5; // Set lives to 5\n    g_pgsCur->ccharm = 0; // Set charms to 0\n\n    ResetChkmgrCheckpoints(&g_chkmgr);\n}\n\nvoid StartGame()\n{\n    UnloadGame();\n    WipeToWorldWarp(D_00247AB0, OID_Nil, WIPEK_Fade);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", FUN_00160948);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", CalculatePercentCompletion__FP2GS);\n\n#ifdef SKIP_ASM\nPchzLevel pchzLevelTable[0x2e];\n/**\n * @todo 59.54% matched.\n */\nint CalculatePercentCompletion(GS *pgs)\n{\n    int cTasksChecked = 0;\n    int cTasksCompleted = 0;\n\n    // Iterate over all the levels in the PchzLevel table\n    for (int i = 0; i < 0x2e; i++)\n    {\n        int levelId = *(int*)&((pchzLevelTable[0].level_id)) + i * sizeof(PchzLevel);\n        int world = levelId >> 8;\n\n        // if world is part of Intro (ie. Splash, Paris, Hideout), skip it\n        if (world != static_cast<int>(GAMEWORLD_Intro))\n        {\n            // get all tasks for the current level\n            int levelTasks = static_cast<int>(pchzLevelTable[0].tasks) + i;\n\n            // get save data for the current level\n            LS* currLs = pgs->aws[world].als + (levelId & 0xff);\n            int currFls = (int)(currLs->fls);\n\n            // check if the level is visited\n            cTasksChecked++;\n            cTasksCompleted = cTasksCompleted + (currFls & (int)(FLS_Visited));\n\n            /* Loop over the bits in the FLS cmp and count how many are set,\n            * but only if those bits are also set in the level_tasks the pchz table */\n            int flsMask = static_cast<int>(FLS_KeyCollected);\n            int tasksToCheck = (int)(levelTasks) & (int)(FLS_KeyCollected);\n            while ((flsMask & ((int)(FLS_KeyCollected) | (int)(FLS_Secondary) | (int)(FLS_Tertiary))) != 0)\n            {\n                if (tasksToCheck != 0)\n                {\n                    cTasksChecked++;\n                    if ((currFls & flsMask) != 0)\n                    {\n                        cTasksCompleted++;\n                    }\n                }\n                flsMask = flsMask << 1;\n                tasksToCheck = levelTasks & flsMask;\n            }\n        }\n    }\n\n    FWS* pCurrFws = &pgs->aws[1].fws;\n    int i = 4;\n    while (i > -1)\n    {\n        FWS fws_cmp = static_cast<FWS>(*pCurrFws);\n        cTasksChecked++;\n        pCurrFws += 1;\n        i--;\n        if (((int)(fws_cmp) & 0x20) != 0)\n        {\n            cTasksCompleted++;\n        }\n    }\n\n    /* This check ensures we only calculate the % if we have to.\n    *\n    * If cTasksCompleted is 0, finalPercent is left as 0 and\n    * the if block is skipped.\n    *\n    * If cTasksCompleted == cTasksChecked (ie. all tasks are completed),\n    * finalPercent is set to 100 and the if block is skipped.\n    *\n    * In all other cases, the if block sets finalPercent to a calculated value.\n    */\n    int finalPercent = 0;\n    if ((cTasksCompleted != 0) &&\n        (finalPercent = 100, cTasksCompleted != cTasksChecked))\n    {\n        // if cTasksChecked is 0 then something has gone wrong\n        if (cTasksChecked == 0)\n        {\n            return -1;\n        }\n\n        // convert the number of tasks completed to a value between 1 and 100\n        int percent = (cTasksCompleted * 100) / cTasksChecked;\n\n        /* This check accounts for integer division errors.\n        *\n        * If cTasksChecked is <= 0, finalPercent is left as 1 and the\n        * if block is skipped because we already know we have completed at least\n        * one task.\n        *\n        * If the calclated percent is >= 100, finalPercent is set to 99 and the\n        * if block is skipped because we already know all tasks are not complete.\n        *\n        * In all other cases, finalPercent is set to the calculated percent.\n        */\n        finalPercent = 1;\n        if ((cTasksChecked > 0) &&\n            (finalPercent = 99, percent < 100))\n        {\n            finalPercent = percent;\n        }\n    }\n\n    return finalPercent;\n}\n#endif // SKIP_ASM\n\nvoid SetCcharm(int ccharm)\n{\n    g_pgsCur->ccharm = ccharm;\n}\n\n/**\n * @todo 77.50% matched.\n */\nbool FCharmAvailable()\n{\n    return (g_pgsCur->ccharm > 0) || (g_grfcht & (GRFCHT)FCHT_InfiniteCharms);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", FUN_00160C90);\n\nint PfLookupDialog(LS *pls, OID oidDialog)\n{\n    // todo figure out what these magic numbers represent\n    if (oidDialog - 0x33bU >= 0xc)\n    {\n        return 0;\n    }\n    return -0xcd8 + (int)pls + (oidDialog * 4);\n}\n\n// TODO: Come up with a name and mangle it.\nvoid *clr_8_bytes_1(void *pv)\n{\n    return memset(pv, 0, 8);\n}\n\nvoid FUN_00160ce8(int param_1)\n{\n    STRUCT_OFFSET(param_1, 4, undefined4) = 0;\n}\n\nvoid OnGameAlarmTriggered(GAME *pgame)\n{\n    pgame->cAlarmsTriggered++;\n}\n\nvoid OnGameAlarmDisabled(GAME *pgame)\n{\n    pgame->cAlarmsTriggered--;\n}\n\nGRFVAULT GetGrfvault_unknown()\n{\n    return g_pgsCur->grfvault & STRUCT_OFFSET(g_psw, 0x235c, GRFVAULT);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", GetBlueprintInfo__FPiT0);\n#ifdef SKIP_ASM\n/**\n * @todo 97.65% matched\n * https://decomp.me/scratch/l86al\n */\nvoid GetBlueprintInfo(int *pgrfvault, int *pipdialog)\n{\n    switch (g_pgsCur->gameworldCur)\n    {\n    case GAMEWORLD_Snow:\n        pipdialog = (int *)0x00000000;\n        break;\n    case GAMEWORLD_Intro:\n        pipdialog = (int *)0x10000000;\n        break;\n    case GAMEWORLD_Clockwerk:\n        pipdialog = (int *)0x20000000;\n        break;\n    case GAMEWORLD_Underwater:\n        pipdialog = (int *)0x40000000;\n        break;\n    case GAMEWORLD_Muggshot:\n        pipdialog = (int *)0x60000000;\n        break;\n    case GAMEWORLD_Voodoo:\n        pipdialog = (int *)0x60000000;\n        break;\n    default:\n        pipdialog = (int *)0x00000000;\n        break;\n    }\n\n    if (pgrfvault)\n    {\n        *pgrfvault = (int)pipdialog;\n    }\n}\n#endif // SKIP_ASM\n\nint CcharmMost()\n{\n    // Leftover from when there was a powerup that increased the charm limit.\n    return 2;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/game\", reload_post_death);\n"
  },
  {
    "path": "src/P2/geom.c",
    "content": "#include <geom.h>\n\nvoid InitGeom(GEOM *pgeom)\n{\n    pgeom->cpos = 0;\n    pgeom->apos = NULL;\n\n    pgeom->csurf = 0;\n    pgeom->asurf = NULL;\n\n    pgeom->cedge = 0;\n    pgeom->aedge = NULL;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/geom\", CloneGeom__FP4GEOMP7MATRIX4T0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/geom\", FUN_00161028);\n"
  },
  {
    "path": "src/P2/gifs.c",
    "content": "#include <gifs.h>\n\n/**\n * @todo 100% match, but checksum check fails.\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", __4GIFS);\n/*\nGIFS::GIFS()\n{\n    m_fEndPrim = 1;\n    m_pqwPrim = 0;\n    m_creg = 0;\n    m_cregAll = 0;\n}\n*/\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", AddPrimEnd__4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", EndPrim__4GIFSi);\n\nvoid GIFS::CheckReg(int fExpectPack, int regExpect)\n{\n    m_cregAll++;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", AddPrimBulk__4GIFSiiiUlPP2QW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", AddPrimPack__4GIFSiiUl);\n\nvoid GIFS::PackRGBA(uint rgba)\n{\n    CheckReg(1, 1);\n    QW *pqw = ((QW *)m_pb)++;\n    pqw->aun[0] = (rgba) & 0xff;\n    pqw->aun[1] = (rgba & 0xff00) >> 8;\n    pqw->aun[2] = (rgba >> 16) & 0xff;\n    pqw->aun[3] = (rgba >> 24) & 0xff;\n}\n\nvoid GIFS::PackUV(int u, int v)\n{\n    CheckReg(1, 3);\n    QW *pqw = ((QW *)m_pb)++;\n    pqw->an[0] = u;\n    pqw->an[1] = v;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", PackSTQ__4GIFSfff);\n\nvoid GIFS::PackXYZ(int x, int y, int z)\n{\n    CheckReg(1, 5);\n    QW *pqw = ((QW *)m_pb)++;\n    pqw->an[0] = x;\n    pqw->an[1] = y;\n    pqw->al[1] = z;\n}\n\nvoid GIFS::PackXYZF(int x, int y, int z, int fog)\n{\n    CheckReg(1, 4);\n    QW *pqw = ((QW *)m_pb)++;\n    pqw->an[0] = x;\n    pqw->an[1] = y;\n    pqw->an[2] = z;\n    pqw->an[3] = (fog & 0xff) << 4;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", PackXYZFNoKick__4GIFSiiii);\n\nvoid GIFS::PackAD(long int a, long int d)\n{\n    CheckReg(1, 14);\n    QW *pqw = ((QW *)m_pb)++;\n    pqw->aul[0] = d;\n    pqw->aul[1] = a;\n}\n\nJUNK_ADDIU(30);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", AddPrimList__4GIFSiUl);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", ListRGBAQ__4GIFSUif);\n\nJUNK_ADDIU(30);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", ListUV__4GIFSii);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", ListXYZF__4GIFSiiii);\n\nJUNK_ADDIU(80);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gifs\", AddImage__4GIFSi);\n"
  },
  {
    "path": "src/P2/glbs.c",
    "content": "#include <glbs.h>\n#include <sw.h>\n#include <sce/memset.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glbs\", __4GLBS);\n\nGLBS::~GLBS()\n{\n    return;\n}\n\nvoid GLBS::SetTransform(VECTOR *ppos, MATRIX3 *pmat)\n{\n    EndStrip();\n    LoadMatrixFromPosRot(ppos, pmat, &m_rgld.matObjectToWorld);\n    LoadMatrixFromPosRotInverse(ppos, pmat, &m_rgld.matWorldToObject);\n}\n\nvoid GLBS::FindLights(VECTOR *ppos, float sRadius)\n{\n    if (m_pshd->shdk != SHDK_ThreeWay)\n    {\n        m_cplightStatic = 0;\n        m_cplightAll = 0;\n        m_rgld.trlk = TRLK_Nil;\n        return;\n    }\n\n    m_rgld.twps = TwpsFindSwLights(g_psw, ppos, sRadius, 1, 0x10, &m_cplightStatic, &m_cplightAll, m_aplight);\n    m_rgld.trlk = TRLK_Quick;\n}\n\nvoid GLBS::ResetStrip()\n{\n    m_pshd = NULL;\n    m_cvtxg = 0;\n    memset(m_avtxg, 0, 148 * sizeof(VTXG));\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glbs\", BeginStrip__4GLBSP3SHD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glbs\", DrawPrelit__4GLBS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glbs\", DrawThreeWay__4GLBS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glbs\", EndStrip__4GLBS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glbs\", SetNormal__4GLBSP6VECTOR);\n\nJUNK_WORD(0xE4800110);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glbs\", SetRgba__4GLBSG4RGBA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glbs\", SetUv__4GLBSP3UVF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glbs\", AddVtx__4GLBSi);\n"
  },
  {
    "path": "src/P2/glob.c",
    "content": "#include <glob.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", BuildGlobsetSaaArray__FP7GLOBSET);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", LoadGlobsetFromBrx__FP7GLOBSETP18CBinaryInputStreamP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", EnsureBuffer__FiP4VIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", EnsureBufferCel__FiP4VIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", BuildSubcel__FP7GLOBSETiP6SUBCELiP7VECTORFiP4TWEFP8SUBPOSEFT4PfP4VIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", BuildSubglobSinglePass__FP7GLOBSETP4GLOBiP7SUBGLOBP3SHDP7VECTORFT5P4RGBAP3UVFiP4VTXFP8SUBPOSEFT5T5PfP4VIFSP4SGVR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", BuildSubglobThreeWay__FP7GLOBSETP4GLOBiP7SUBGLOBP3SHDP7VECTORFT5P4RGBAP3UVFiP4VTXFP8SUBPOSEFT5T5PfP4VIFSP4SGVR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", BuildSubglobLighting__FP4GLOBP7SUBGLOBP8SUBGLOBI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", PostGlobsetLoad__FP7GLOBSETP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", BindGlobset__FP7GLOBSETP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", CloneGlobset__FP7GLOBSETP3ALOT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", CloneGlob__FP7GLOBSETP4GLOBP5GLOBI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", UpdateGlobset__FP7GLOBSETP3ALOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", UpdateAloConstraints__FP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", UpdateAloInfluences__FP3ALOP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", PredrawGlob__FP7GLOBSETP4GLOBP5GLOBIP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", RotateVu1Buffer__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", DrawGlob__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", glob__static_initialization_and_destruction_0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/glob\", _GLOBAL_$I$g_dro);\n"
  },
  {
    "path": "src/P2/gomer.c",
    "content": "#include <gomer.h>\n#include <stepguard.h>\n#include <find.h>\n#include <memory.h>\n#include <aseg.h>\n#include <waypoint.h>\n#include <basic.h>\n#include <sw.h>\n#include <chkpnt.h>\n\n#define PI 3.1415927f\n\nvoid InitGomer(GOMER *pgomer)\n{\n    InitStepguard(pgomer);\n    STRUCT_OFFSET(pgomer, 0xC20, float) = 1000.0f;\n    STRUCT_OFFSET(pgomer, 0xC24, float) = 1500.0f;\n    STRUCT_OFFSET(pgomer, 0xC28, float) = PI / 4.0f;\n    STRUCT_OFFSET(pgomer, 0xC2C, float) = PI;\n    STRUCT_OFFSET(pgomer, 0xC10, float) = 2000.0f;\n    STRUCT_OFFSET(pgomer, 0xC30, OID) = OID_Nil;\n    STRUCT_OFFSET(pgomer, 0xC14, float) = 300.0f;\n    STRUCT_OFFSET(pgomer, 0xC18, OID) = OID_Nil;\n    STRUCT_OFFSET(pgomer, 0x73C, float) = 300.0f;\n    STRUCT_OFFSET(pgomer, 0x738, int) = 0;\n    STRUCT_OFFSET(pgomer, 0x74C, float) = PI / 3.0f;\n}\n\nvoid PostGomerLoad(GOMER *pgomer)\n{\n    PostStepguardLoad(pgomer);\n\n    // If OID at 0xC18 is not NIL, find nearest LO of OID at 0xc18, and save it to 0xC1C.\n    if (STRUCT_OFFSET(pgomer, 0xC18, OID) != OID_Nil)\n    {\n        STRUCT_OFFSET(pgomer, 0xC1C, LO *) = PloFindSwNearest(\n            pgomer->psw,\n            STRUCT_OFFSET(pgomer, 0xC18, OID),\n            pgomer);\n    }\n\n    // If OID at 0xC30 is not NIL, find nearest LO of OID at 0xc30, and save it to 0xC34.\n    if (STRUCT_OFFSET(pgomer, 0xC30, OID) != OID_Nil)\n    {\n        STRUCT_OFFSET(pgomer, 0xC34, LO *) = PloFindSwNearest(\n            pgomer->psw,\n            STRUCT_OFFSET(pgomer, 0xC30, OID),\n            pgomer);\n    }\n\n    // If aseg pointer at 0x750 is null, skip waypoint collection.\n    if (!STRUCT_OFFSET(pgomer, 0x750, ASEG *))\n    {\n        return;\n    }\n\n    InitStackImpl();\n\n    // Collect aseg waypoints.\n    WAYPOINT **apwaypoint;\n    int cpwaypoint;\n    GetAsegWaypoints(STRUCT_OFFSET(pgomer, 0x750, ASEG *), pgomer, &cpwaypoint, &apwaypoint);\n\n    for (int i = 0; i < cpwaypoint; i++)\n    {\n        WAYPOINT *waypoint = apwaypoint[i];\n        if (!STRUCT_OFFSET(waypoint, 0x328, WPSG *))\n        {\n            WPSG *newwpsg = PwpsgNew();\n            STRUCT_OFFSET(waypoint, 0x328, WPSG *) = newwpsg;\n            AddWpsgWaypoint(newwpsg, (WAYPOINT *)waypoint);\n        }\n    }\n\n    FreeStackImpl();\n}\n\nvoid RenderGomerSelf(GOMER *pgomer, CM *pcm, RO *pro)\n{\n    RenderStepguardSelf(pgomer, pcm, pro);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gomer\", FDetectGomer__FP5GOMER);\n#ifdef SKIP_ASM\nextern float func_001C7A60(GOMER *pgomer);\nextern int func_001CB3D0(GOMER *pgomer);\n\n/**\n * @todo 52.12% matched.\n */\nint FDetectGomer(GOMER *pgomer)\n{\n    if (!pgomer->psw)\n    {\n        return 0;\n    }\n\n    GOMERS gomers = STRUCT_OFFSET(pgomer, 0x724, GOMERS);\n    if (gomers == (GOMERS)0x10 || gomers == (GOMERS)0x08)\n    {\n        return 0;\n    }\n\n    // Call func at pvtgomer->0x198 to get pbasic.\n    VT *pvtgomer = STRUCT_OFFSET(pgomer, 0x0, VT *);\n    void *fp = STRUCT_OFFSET(pvtgomer, 0x198, void *);\n    void *(*fn)(GOMER *) = (void *(*)(GOMER *))fp;\n    void *pbasic = fn(pgomer);\n\n    // If C40 flag set, or basic is null, clear latch and return 0.\n    if (!STRUCT_OFFSET(pgomer, 0xC40, int) || !pbasic)\n    {\n        STRUCT_OFFSET(pgomer, 0xC38, int) = 0;\n        return 0;\n    }\n\n    if (pbasic && FIsBasicDerivedFrom((BASIC *)pbasic, (CID)5)) // CID_PO?\n    {\n        // If basic derived from CID 5, call method at pvt???->0x144 and check for return == 2.\n        VTBASIC *pvtbasic = STRUCT_OFFSET(pbasic, 0x0, VTBASIC *);\n        void *fp2 = STRUCT_OFFSET(pvtbasic, 0x144, void *);\n        int (*getState)(void *) = (int (*)(void *))fp2;\n        if (getState(pbasic) == 2)\n        {\n            STRUCT_OFFSET(pgomer, 0xC38, int) = 0;\n            return 0;\n        }\n    }\n\n    // If exclude volume at 0xC1C exists, and point NOT inside it, clear C38 and return 0.\n    if (STRUCT_OFFSET(pgomer, 0xC1C, void *))\n    {\n        VOL *vol = STRUCT_OFFSET(pgomer, 0xC1C, VOL *);\n        int inside = FCheckVolPoint(vol, &STRUCT_OFFSET(pbasic, 0x140, VECTOR));\n        if (!inside)\n        {\n            STRUCT_OFFSET(pgomer, 0xC38, int) = 0;\n            return 0;\n        }\n    }\n    else\n    {\n        // Vertical threshold then 2D XY distance check against C10 using pbasic@0x140 vs pgomer@0x190.\n        float vert_diff;\n        float vth;\n        float dx;\n        float dy;\n        float dist;\n        float *tpos;\n        float *gpos2;\n        vert_diff = STRUCT_OFFSET(pbasic, 0x148, float) - STRUCT_OFFSET(pgomer, 0x198, float);\n        if (vert_diff < 0.0f)\n        {\n            vert_diff = -vert_diff;\n        }\n        vth = STRUCT_OFFSET(pgomer, 0xC14, float);\n        if (vert_diff > vth)\n        {\n            STRUCT_OFFSET(pgomer, 0xC38, int) = 0;\n            return 0;\n        }\n\n        tpos = &STRUCT_OFFSET(pbasic, 0x140, float);\n        gpos2 = &STRUCT_OFFSET(pgomer, 0x190, float);\n        dx = tpos[0] - gpos2[0];\n        dy = tpos[1] - gpos2[1];\n        /* sqrtf prototype (avoid including headers) */\n        {\n            extern float sqrtf(float);\n            dist = sqrtf(dx * dx + dy * dy);\n        }\n        if (dist > STRUCT_OFFSET(pgomer, 0xC10, float))\n        {\n            STRUCT_OFFSET(pgomer, 0xC38, int) = 0;\n            return 0;\n        }\n    }\n\n    /* Second-phase: if already latched (C38!=0), return 1 */\n    if (STRUCT_OFFSET(pgomer, 0xC38, int))\n    {\n        return 1;\n    }\n\n    /* If include volume at 0xC34 exists and point inside, skip straight to final checks */\n    if (STRUCT_OFFSET(pgomer, 0xC34, void *))\n    {\n        int inside2 = FCheckVolPoint(STRUCT_OFFSET(pgomer, 0xC34, VOL *), &STRUCT_OFFSET(pbasic, 0x140, VECTOR));\n        if (inside2)\n        {\n            if (func_001CB3D0(pgomer))\n            {\n                return 0;\n            }\n\n            STRUCT_OFFSET(pgomer, 0xC38, int) = 1;\n            return 1;\n        }\n    }\n\n    /* Range gating using positions at 0x140 for both */\n    float *gpos;\n    float *tpos2;\n    float dx2;\n    float dy2;\n    float dist2;\n    float outer;\n\n    gpos = &STRUCT_OFFSET(pgomer, 0x140, float);\n    tpos2 = &STRUCT_OFFSET(pbasic, 0x140, float);\n    dx2 = gpos[0] - tpos2[0];\n    dy2 = gpos[1] - tpos2[1];\n    {\n        extern float sqrtf(float);\n        dist2 = sqrtf(dx2 * dx2 + dy2 * dy2);\n    }\n\n    outer = STRUCT_OFFSET(pgomer, 0xC24, float);\n    if (!(dist2 < outer))\n    {\n        return 0;\n    }\n\n    float inner;\n    float angle_min;\n    float angle_max;\n    float f20;\n    float a;\n\n    inner = STRUCT_OFFSET(pgomer, 0xC20, float);\n    if (dist2 < inner)\n    {\n        f20 = STRUCT_OFFSET(pgomer, 0xC2C, float);\n    }\n    else\n    {\n        float one;\n        float num;\n        float den;\n        float t;\n\n        one = 1.0f;\n        angle_max = STRUCT_OFFSET(pgomer, 0xC2C, float);\n        angle_min = STRUCT_OFFSET(pgomer, 0xC28, float);\n        num = dist2 - inner;\n        den = outer - inner;\n        if (den != 0.0f)\n        {\n            t = num / den;\n        }\n        else\n        {\n            t = 0.0f;\n        }\n        f20 = t * angle_min + (one - t) * angle_max;\n    }\n\n    a = func_001C7A60(pgomer);\n    if (a < 0.0f)\n    {\n        a = -a;\n    }\n    if (a <= f20)\n    {\n        return 0;\n    }\n\n    if (func_001CB3D0(pgomer))\n    {\n        return 0;\n    }\n\n    STRUCT_OFFSET(pgomer, 0xC38, int) = 1;\n    return STRUCT_OFFSET(pgomer, 0xC38, int);\n}\n#endif\n"
  },
  {
    "path": "src/P2/gs.c",
    "content": "#include <gs.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", BlendDisplayOnBufferMismatch__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", VBlankS_Interrupt__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", SyncVBlank__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", SwapGsBuffers__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", RestoreGsBuffers__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", GS_Interrupt__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", ResetGs__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", SendDmaSyncGsFinish__FP10sceDmaChanP2QW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", BuildClearGifs__FP2QWG4RGBAi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", StartupGs__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", BlastAqwGifsBothFrames__FP2QW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", ClearFrameBuffers__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", FadeFramesToBlack__Ff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", ResetGsMemory__Fv);\n\nuint NLog2(uint value)\n{\n    uint log2 = 0;\n    uint bit = 1;\n\n    while (bit < value && log2 < 31)\n    {\n        bit <<= 1;\n        log2++;\n    }\n\n    return log2;\n}\n\nvoid InitGsb(GSB *pgsb, int igsMin, int igsMax)\n{\n    pgsb->igsMac = igsMin;\n    pgsb->igsMin = igsMin;\n    pgsb->igsMax = igsMax;\n}\n\nvoid ResetGsb(GSB *pGsb)\n{\n    pGsb->igsMac = pGsb->igsMin;\n}\n\nint IgsAllocGsb(GSB *pgsb, int iCount)\n{\n    int igsOld = pgsb->igsMac;\n    pgsb->igsMac += iCount;\n    return igsOld;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", BuildImageGifs__FiiiiiiP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", BuildClutTex2__FP4CLUTi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", BuildClutGifs__FP4CLUTiP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", BuildBmpTex0__FP3BMPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", BuildBmpGifs__FP3BMPiP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", FBuildUploadBitmapGifs__FiP3GSBP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", UploadBitmaps__FiP3GSB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", PqwGifsBitmapUpload__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", PropagateSur__FP3SUR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", ReferenceShaderAqwRegs__FP3SHDP4SHDPP2QWiiP3SAI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", ReferenceUVAnimation__FP2QWiP3SAI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", RebaseSurs__FiiPvT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", PropagateSurs__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", PqwVifsBitmapUpload__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/gs\", DrawOnBitmap__FP3BMPP4GIFS);\n"
  },
  {
    "path": "src/P2/hide.c",
    "content": "#include <hide.h>\n#include <dl.h>\n\nextern DL g_dlHshape;\nextern DL g_dlHpnt;\nextern DL g_dlHbsk;\n\nvoid StartupHide()\n{\n    InitDl(&g_dlHshape, 0x38);\n    InitDl(&g_dlHpnt, 0x50);\n    InitDl(&g_dlHbsk, 0x558);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", ResetHideList__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", InitHshape__FP6HSHAPE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", OnHshapeAdd__FP6HSHAPE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", OnHshapeRemove__FP6HSHAPE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", BindHshape__FP6HSHAPE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", CloneHshape__FP6HSHAPET0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", GetHshapeHidePos__FP6HSHAPEfP6VECTORPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", GetHshapeClosestHidePos__FP6HSHAPEPfP6VECTORT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", InitHpnt__FP4HPNT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", OnHpntAdd__FP4HPNT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", OnHpntRemove__FP4HPNT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", BindHpnt__FP4HPNT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", CloneHpnt__FP4HPNTT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", GetHpntClosestHidePos__FP4HPNTP6VECTORPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", FUN_0016a320);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", InitHbsk__FP4HBSK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", LoadHbskFromBrx__FP4HBSKP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", OnHbskAdd__FP4HBSK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", OnHbskRemove__FP4HBSK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", CloneHbsk__FP4HBSKT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", FIgnoreHbskIntersection__FP4HBSKP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", PresetHbskAccel__FP4HBSKf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", SetHbskHbsks__FP4HBSK5HBSKS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", CdartStuckHbsk__FP4HBSK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", PdartOldestHbskStuck__FP4HBSK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/hide\", GetHbskClosestHidePos__FP4HBSKP6VECTORPf);\n"
  },
  {
    "path": "src/P2/hnd.c",
    "content": "#include <hnd.h>\n\nextern float D_0024A7DC;\n\nvoid InitHnd(HND *phnd)\n{\n    InitTarget(phnd);\n\n    float val = D_0024A7DC;\n    STRUCT_OFFSET(phnd, 0x88, int) = 1; // phnd->grftak\n    STRUCT_OFFSET(phnd, 0xa8, int) = 8; // Likely phnd->sfxidRelease\n    STRUCT_OFFSET(phnd, 0xac, int) = 9; // Likely phnd->sfxidGrab\n    STRUCT_OFFSET(phnd, 0xb4, float) = val;\n}\n\n/**\n * @todo Objdiff reports a 100% match, but checksum check still fails.\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/hnd\", LoadHndFromBrx__FP3HNDP18CBinaryInputStream);\n#ifdef SKIP_ASM\nvoid LoadHndFromBrx(HND *phnd, CBinaryInputStream *pbis)\n{\n    LoadXfmFromBrx(phnd, pbis);\n}\n#endif // SKIP_ASM\n\nJUNK_ADDIU(A0);\nJUNK_ADDIU(E0);\n"
  },
  {
    "path": "src/P2/ik.c",
    "content": "#include <ik.h>\n\nvoid RenderIkhSelf(IKH *pikh, CM *pcm, RO *pro)\n{\n    RenderSoSelf(pikh, pcm, pro);\n}\n\nvoid RenderLikhSelf(LIKH *plikh, CM *pcm, RO *pro)\n{\n    RenderAloSelf(plikh, pcm, pro);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ik\", SolveAloIK__FP3ALO);\n"
  },
  {
    "path": "src/P2/jlo.c",
    "content": "#include <jlo.h>\n#include <mat.h>\n\nextern JLO *g_pjloCur;\nextern VECTOR g_normalZ; // TODO: This should be elsewhere.\n\nvoid InitJlo(JLO *pjlo)\n{\n    InitSo(pjlo);\n    STRUCT_OFFSET(pjlo, 0x578, JLOS) = JLOS_Nil; // pjlo->jlos\n    STRUCT_OFFSET(pjlo, 0x598, OID) = OID_Nil; // pjlo->oidJlovolStart\n    STRUCT_OFFSET(pjlo, 0x5c4, float) = 3000.0f;\n    STRUCT_OFFSET(pjlo, 0x5c8, float) = 1000.0f;\n\n    InitDl(&STRUCT_OFFSET(pjlo, 0x55c, DL), 0x7b0); // pjlo->dlJlovol\n\n    SMP *psmp = &STRUCT_OFFSET(pjlo, 0x5b0, SMP);\n    STRUCT_OFFSET(psmp, 0x00, float) = 25.0f; // pjlo->smpSpin.ag[0]\n    STRUCT_OFFSET(psmp, 0x04, float) = 0.0f; // pjlo->smpSpin.svSlow\n    STRUCT_OFFSET(psmp, 0x08, float) = 0.25f; // pjlo->smpSpin.dtFast\n\n    g_pjloCur = NULL;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", LoadJloFromBrx__FP3JLOP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", PostJloLoad__FP3JLO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", FUN_0016d040);\n\nvoid PresetJloAccel(JLO *pjlo, float dt)\n{\n    PresetSoAccel(pjlo, dt);\n    if (STRUCT_OFFSET(pjlo, 0x5d8, int) == 0)\n    {\n        MATRIX3 matTarget;\n        LoadRotateMatrixRad(STRUCT_OFFSET(pjlo, 0x5a0, float), &g_normalZ, &matTarget);\n        AccelSoTowardMatSmooth(pjlo, dt, &matTarget, &STRUCT_OFFSET(pjlo, 0x5b0, SMP));\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", UpdateJlo__FP3JLOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", JlosNextJlo__FP3JLO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", SetJloJlovol__FP3JLOP6JLOVOL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", FireJlo__FP3JLO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", LandJlo__FP3JLO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", JumpJlo__FP3JLO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", FUN_0016d928);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", FUN_0016d9a8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", HandleJloMessage__FP3JLO5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", SetJloJlos__FP3JLO4JLOS);\n\nvoid ActivateJlo(JLO *pjlo)\n{\n    g_pjloCur = pjlo;\n}\n\nvoid DeactivateJlo(JLO *pjlo)\n{\n    g_pjloCur = NULL;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", InitJloc__FP4JLOC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", LoadJlocFromBrx__FP4JLOCP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", PostJlocLoad__FP4JLOC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", PxfmChooseJloc__FP4JLOC);\n\nvoid InitJlovol(JLOVOL *pjlovol)\n{\n    InitVolbtn(pjlovol);\n    STRUCT_OFFSET(pjlovol, 0x7a0, OID) = OID_Nil; // pjlovol->oidJloc\n    STRUCT_OFFSET(pjlovol, 0x7a8, OID) = OID_Nil; // pjlovol->oidLand\n    STRUCT_OFFSET(pjlovol, 0x6e8, float) = 0.0f; // pjlovol->btn.dtRepush\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", BindJlovol__FP6JLOVOL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jlo\", HandleJlovolMessage__FP6JLOVOL5MSGIDPv);\n"
  },
  {
    "path": "src/P2/joy.c",
    "content": "#include <joy.h>\n#include <game.h>\n#include <text.h>\n#include <clock.h>\n#include <sound.h>\n#include <memory.h>\n#include <screen.h>\n#include <transition.h>\n#include <sce/memset.h>\n#include <sdk/ee/libpad.h>\n\n// static char g_chzThePasswordIs[] = \"The password is: %s\";\n// static char g_chzCiphertext[] = \"@KFWHJGL\"; // decrypts to \"chetkido\"\nextern char g_chzThePasswordIs[];\nextern char g_chzCiphertext[];\n\nvoid StartupJoy()\n{\n    UpdateGrfjoytFromGrfusr();\n    scePadInit(0);\n    InitJoy(&g_joy, 0, 0);\n}\n\nvoid AddGrfusr(int mask)\n{\n    g_grfusr |= mask;\n    UpdateGrfjoytFromGrfusr();\n}\n\nvoid RemoveGrfusr(int mask)\n{\n    g_grfusr &= ~mask;\n    UpdateGrfjoytFromGrfusr();\n}\n\nvoid UpdateGrfjoytFromGrfusr()\n{\n    if (g_grfusr & 0x84)\n    {\n        // Unknown state\n        g_grfjoyt = 0;\n    }\n    else if (g_grfusr & FUSR_Menu)\n    {\n        // Pause menu/dialog box is open\n        g_grfjoyt = 5;\n    }\n    else if (g_grfusr & FUSR_HandsOff)\n    {\n        // In-game cutscene/transition/animation is playing\n        g_grfjoyt = 4;\n    }\n    else\n    {\n        // Game is running normally\n        g_grfjoyt = 7;\n    }\n}\n\n// todo: investigate if aullDma assignment can be cleaned up when type is known\nvoid InitJoy(JOY *pjoy, int nPort, int nSlot)\n{\n    memset(pjoy, 0, sizeof(JOY));\n    SetJoyJoys(pjoy, JOYS_Searching, JOYK_Unknown);\n    pjoy->nPort = nPort;\n    pjoy->nSlot = nSlot;\n    pjoy->aullDma = (uint *)(((int)PvAllocGlobalImpl(0x140) + 0x3F) & ~0x3F);\n    scePadPortOpen(pjoy->nPort, pjoy->nSlot, pjoy->aullDma);\n    pjoy->prumble = (RUMBLE *)PvAllocGlobalImpl(0x20);\n    pjoy->fRumbleEnabled = true;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/joy\", UpdateJoy__FP3JOY);\n#ifdef SKIP_ASM\n/**\n * @todo 31.94% matched.\n */\nvoid UpdateJoy(JOY *pjoy)\n{\n    bool cond = false;\n    JOYS joysNew;\n    JOYK joykNew, joyk;\n    uint padState;\n\n    // if the joy manager is initializing, early return\n    if (pjoy->joys == JOYS_Initing)\n        return;\n\n    padState = scePadGetState(pjoy->nPort, pjoy->nSlot);\n    if (padState == 6 || padState == 2) // todo: enum for padState\n    {\n        cond = true; // todo: what is this condition?\n    }\n    joysNew = pjoy->joys;\n\n    if (joysNew != JOYS_Ready)\n    {\n        if (pjoy->joyk != JOYK_Unknown)\n        {\n            if (g_clock.tReal - pjoy->tJoys >= 2.0f)\n            {\n                padState = 0;\n            }\n        }\n    }\n\n    if (pjoy->joyk != JOYK_Unknown && padState == 0)\n    {\n        SetJoyJoys(pjoy, JOYS_Searching, JOYK_Unknown);\n    }\n\n    // Return if condition not met\n    if (!cond)\n        return;\n\n    joysNew = pjoy->joys;\n    joykNew = pjoy->joyk;\n    if (joysNew == JOYS_Waiting)\n    {\n        padState = scePadGetState(pjoy->nPort, pjoy->nSlot);\n        if (padState != '\\x01')\n        {\n            if (padState > '\\x01')\n            {\n                if (padState != '\\x02')\n                {\n                    joykNew = JOYK_Unknown;\n                }\n                SetJoyJoys(pjoy, joysNew, joykNew);\n                return;\n            }\n            joykNew = JOYK_Unknown;\n            if (padState != '\\0')\n            {\n                SetJoyJoys(pjoy, joysNew, joykNew);\n                return;\n            }\n\n            joyk = pjoy->joyk;\n            if (joyk == JOYK_Analog)\n            {\n                joykNew = JOYK_Shock;\n            }\n            else\n            {\n                if (static_cast<int>(joyk) > 2)\n                {\n                    joykNew = JOYK_Unknown;\n\n                    if (joyk != JOYK_Shock)\n                    {\n                        SetJoyJoys(pjoy, joysNew, joykNew);\n                        return;\n                    }\n                    joykNew = JOYK_Shock2;\n                    joysNew = JOYS_Ready;\n                    SetJoyJoys(pjoy, joysNew, joykNew);\n                    return;\n                }\n                // todo\n                //...\n            }\n        }\n    }\n    else\n    {\n        // todo\n        // ...\n    }\n\n    SetJoyJoys(pjoy, joysNew, joykNew);\n}\n#endif // SKIP_ASM\n\nvoid SetJoyJoys(JOY *pjoy, JOYS joys, JOYK joyk)\n{\n    if (joys == pjoy->joys && joyk == pjoy->joyk)\n        return;\n\n    if (joyk == JOYK_Unknown)\n    {\n        pjoy->term = 0;\n        joys = JOYS_Searching;\n    }\n\n    JOYK joykPrev = pjoy->joyk;\n    if (joykPrev < JOYK_Shock && joyk > JOYK_Analog)\n    {\n        InitRumble(pjoy->prumble, pjoy->nPort, pjoy->nSlot);\n    }\n\n    if (joys == JOYS_Ready)\n    {\n        uint i = 0;\n        pjoy->tRead = 0.0f;\n        pjoy->fStickMoved2 = 0;\n        pjoy->fStickMoved = 0;\n        pjoy->grfbtn = 0;\n\n        float *almDeflectMax = &pjoy->almDeflect[0].gMax;\n        float *almDeflect2Max = &pjoy->almDeflect2[0].gMax;\n        LM *almDeflect = pjoy->almDeflect;\n        LM *almDeflect2 = pjoy->almDeflect2;\n\n        for (; i < 4; i++)\n        {\n            almDeflect2->gMin = -0.75f;\n            almDeflect2++;\n\n            almDeflect->gMin = -0.75f;\n            almDeflect++;\n\n            *almDeflect2Max = 0.75f;\n            almDeflect2Max += 2;\n\n            *almDeflectMax = 0.75f;\n            almDeflectMax += 2;\n        }\n    }\n\n    pjoy->joys = joys;\n    pjoy->joyk = joyk;\n    pjoy->tJoys = g_clock.tReal;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/joy\", GetJoyXYDeflection__FP3JOYUcUcPfN23PUcT6PiP2LM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/joy\", FReadJoy__FP3JOY);\n\nvoid SetJoyBtnHandled(JOY *pjoy, GRFBTN btn)\n{\n    pjoy->grfbtnPressed &= ~btn;\n}\n\nvoid TriggerJoyRumbleRumk(JOY *pjoy, RUMK rumk, float dt)\n{\n    if (pjoy->fRumbleEnabled && pjoy->joyk > JOYK_Analog && pjoy->joys == JOYS_Ready)\n    {\n        TriggerRumbleRumk(pjoy->prumble, rumk, dt);\n    }\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\n\nvoid StartJoySelection(JOY *pjoy)\n{\n    pjoy->dxLatch = 0;\n    pjoy->dyLatch = 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/joy\", DxSelectionJoy__FP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/joy\", DySelectionJoy__FP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/joy\", UBtnpJoy__FP3JOY4BTNP);\n\nvoid AddCode(CODE *pcode)\n{\n    CODE *p_inputs_counter = g_pcode;\n\n    while (p_inputs_counter)\n    {\n        if (pcode == p_inputs_counter)\n        {\n            return;\n        }\n        p_inputs_counter = p_inputs_counter->pchtNext;\n    }\n\n    pcode->pchtNext = g_pcode;\n    g_pcode = pcode;\n    if (g_joy.grfbtn == *pcode->ajbc)\n    {\n        pcode->nInputCounter = 1;\n    }\n    else\n    {\n        pcode->nInputCounter = 0;\n    }\n}\n\nJUNK_NOP();\nJUNK_WORD(0xAC820014);\n\nvoid _ResetCodes()\n{\n    CODE *pcode = g_pcode;\n    if (!pcode)\n        return;\n\n    pcode->nInputCounter = 0;\n    while (pcode = pcode->pchtNext)\n    {\n        pcode->nInputCounter = 0;\n    }\n}\n\nvoid _MatchCodes(JOY *pjoy, GRFBTN btn)\n{\n    if (!g_pcode || pjoy != &g_joy || btn == g_joy.grfbtn || g_joy.grfbtn == 0)\n        return;\n\n    CODE *pcode = g_pcode;\n    while (pcode)\n    {\n        if (pcode->nInputCounter < pcode->cjbc)\n        {\n            if (g_joy.grfbtn == pcode->ajbc[pcode->nInputCounter])\n            {\n                pcode->nInputCounter++;\n            }\n            else\n            {\n                pcode->nInputCounter = 0;\n            }\n        }\n\n        pcode = pcode->pchtNext;\n    }\n\n    g_tCodeCheck = g_clock.tReal + 1.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/joy\", UpdateCodes__Fv);\n#ifdef SKIP_ASM\n/**\n * @todo 45.89% matched.\n */\nvoid UpdateCodes()\n{\n    int i;\n    CODE **ppcht;\n    CODE *pchtToExecute;\n    CODE *pcht;\n\n    if (g_tCodeCheck != 0x0f && g_tCodeCheck <= g_clock.tReal)\n    {\n        pchtToExecute = NULL;\n        pcht = g_pcode;\n\n        if (g_pcode != NULL)\n        {\n            i = g_pcode->index;\n            pcht = g_pcode;\n            while (true)\n            {\n                if (i == 0)\n                {\n                    if (pcht->nInputCounter < pcht->cjbc)\n                    {\n                        ppcht = &pcht->pchtNext;\n                    }\n                    else if ((/* pchtToExecute == NULL || */ // todo fix\n                              ppcht = &pcht->pchtNext,\n                              pchtToExecute->cjbc < pcht->cjbc))\n                    {\n                        ppcht = &pcht->pchtNext;\n                        pchtToExecute = pcht;\n                    }\n                }\n                else\n                {\n                    *ppcht = pcht->pchtNext;\n                    pcht->pchtNext = NULL;\n                    pcht->nInputCounter = 0;\n                    pcht->index = 0;\n                }\n                pcht = *ppcht;\n                if (pcht == NULL)\n                    break;\n\n                i = pcht->index;\n            }\n        }\n\n        // Check if we found a match\n        if (pchtToExecute != NULL)\n        {\n            // Execute the cheat\n            StartSound(SFXID_UiTick, NULL, NULL, NULL, 3000, 300, 1, 0, 0, NULL, NULL);\n            //(pchtToExecute->pfn)(pchtToExecute->nParam); //todo fix function pointer\n        }\n\n        _ResetCodes();\n        g_tCodeCheck = 0.0f;\n    }\n}\n#endif\n\nvoid ClearFchts()\n{\n    g_grfcht = FCHT_None;\n    ResetWorld(FTRANS_None);\n}\n\nvoid AddFcht(int nParam)\n{\n    g_grfcht |= nParam & ~FCHT_ResetWorld;\n    if (nParam & FCHT_ResetWorld)\n    {\n        ResetWorld(FTRANS_None);\n    }\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\n\nvoid Chetkido()\n{\n    // Check preconditions.\n    int widCur = (g_pgsCur->gameworldCur << 8) | (g_pgsCur->worldlevelCur);\n    if (widCur != 0x400) // level is \"A Perilous Ascent\"\n        return;\n\n    FGS cmpFlags = get_game_completion();\n    if ((cmpFlags & (FGS_HalfClues | FGS_AllClues)) != (FGS_HalfClues | FGS_AllClues)) // clues collected\n        return;\n\n    GS *gsCur = g_pgsCur;\n    if (gsCur->ccoin != 99 || gsCur->clife != 0) // 99 coins and 0 lives\n        return;\n\n    // Decrypt chetkido using XOR cipher, key 0x23\n    char buf[64];\n    char achzPlaintext[16];\n    strcpy(achzPlaintext, g_chzCiphertext);\n\n    char *pchCur = achzPlaintext;\n    while (*pchCur != '\\0')\n    {\n        *pchCur++ ^= 0x23;\n    }\n\n    // Show note blot with message\n    sprintf(buf, g_chzThePasswordIs, achzPlaintext);\n    ((NOTE *)&g_note.unk278)->pvtnote->pfnSetNoteAchzDraw((NOTE *)&g_note.unk278, buf);\n    SetBlotDtVisible((NOTE *)&g_note.unk278, 10.0f);\n    ((NOTE *)&g_note.unk278)->pvtnote->pfnShowBlot((NOTE *)&g_note.unk278);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/joy\", StartupCodes__Fv);\n#ifdef SKIP_ASM\n/**\n * @todo 4.38% matched.\n */\nvoid StartupCodes()\n{\n    ////AddCode(&cheat_reload_level.pCodeSeq);\n    ////AddCode(&cheat_reload_no_cheats.pCodeSeq);\n    ////AddCode(&cheat_reload_slippery_movement.pCodeSeq);\n    ////AddCode(&cheat_slippery_objects.pCodeSeq);\n    ////AddCode(&cheat_infinite_charms.pCodeSeq);\n    ////AddCode(&cheat_collect_bottles.pCodeSeq);\n    ////AddCode(&cheat_unlock_pages.pCodeSeq);\n    ////AddCode(&cheat_unlock_all_worlds.pCodeSeq);\n    ////AddCode(&cheat_chetkido_password.pCodeSeq);\n}\n#endif // SKIP_ASM\n"
  },
  {
    "path": "src/P2/jsg.c",
    "content": "#include <jsg.h>\n#include <sw.h>\n#include <clock.h>\n#include <memory.h>\n#include <sce/memset.h>\n\nextern JSGE s_jsge;\n\nvoid InitJsg(JSG *pjsg)\n{\n    InitLo(pjsg);\n    pjsg->ajsge = (JSGE *)PvAllocSwImpl(0xa00);\n    pjsg->unk3 = 1;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jsg\", GetJsgLocation__FP3JSGP2LOP6VECTORPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jsg\", SetJsgFocus__FP3JSGP2LO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jsg\", SetJsgTn__FP3JSGP2TN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jsg\", NextJsgJsge__FP3JSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jsg\", FIsJsgJsgeComplete__FP3JSGP4JSGE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jsg\", UpdateJsgJsge__FP3JSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jsg\", ReadJsgJoystick__FP3JSGP3JOY);\n\nint FIsJsgActive(JSG *pjsg)\n{\n    UpdateJsgJsge(pjsg);\n\n    int fActive = 0;\n    if (pjsg->cjsge > 0)\n    {\n        fActive = pjsg->ijsgeCur < pjsg->cjsge;\n    }\n\n    return fActive;\n}\n\nvoid ClearJsg(JSG *pjsg)\n{\n    if (pjsg->pjt)\n    {\n        RetractJsg(pjsg);\n    }\n\n    pjsg->ijsgeCur = 0;\n    pjsg->cjsge = 0;\n}\n\nvoid ApplyJsg(JSG *pjsg, JT *pjt)\n{\n    STRUCT_OFFSET(pjt, 0x2740, JSG *) = pjsg; // pjt->pjsgCur\n    pjsg->pjt = pjt;\n    pjsg->ijsgeCur = -1;\n\n    HandleLoSpliceEvent(pjsg, 0x17, 0, NULL);\n\n    if (pjsg->unk3)\n    {\n        AddGrfusr(4);\n        IncrementSwHandsOff(pjsg->psw);\n    }\n}\n\nvoid RetractJsg(JSG *pjsg)\n{\n    if (!pjsg->pjt)\n        return;\n\n    SetJsgTn(pjsg, NULL);\n    SetJsgFocus(pjsg, NULL);\n\n    if (pjsg->pasegaCur)\n    {\n        RetractAsega(pjsg->pasegaCur);\n        pjsg->pasegaCur = 0;\n    }\n\n    SetClockRate(1.0f);\n    pjsg->ijsgeCur = pjsg->cjsge;\n    pjsg->ploContext = NULL;\n    pjsg->pjsgeJoy = NULL;\n    STRUCT_OFFSET(pjsg->pjt, 0x2740, JSG *) = NULL; // pjsg->pjt->pjsgCur\n    pjsg->pjt = NULL;\n\n    HandleLoSpliceEvent(pjsg, 0x19, 0, NULL);\n\n    if (pjsg->unk3)\n    {\n        RemoveGrfusr(4);\n        DecrementSwHandsOff(pjsg->psw);\n    }\n}\n\n/**\n * @todo Objdiff reports a 100% match, but compiler seemingly\n * adds extra instructions?\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/jsg\", PjsgeAllocJsg__FP3JSG5JSGEK3OIDi);\n#ifdef SKIP_ASM\nJSGE *PjsgeAllocJsg(JSG *pjsg, JSGEK jsgek, OID oid, int fAsync)\n{\n    JSGE *pjsge;\n    int cjsge = pjsg->cjsge;\n\n    if (cjsge < 0x80)\n    {\n        pjsg->cjsge = cjsge + 1;\n        pjsge = &pjsg->ajsge[cjsge];\n        memset(pjsge, 0, sizeof(JSGE));\n\n        pjsge->jsgek = jsgek;\n        pjsge->oid = oid;\n        pjsge->fAsync = fAsync;\n    }\n    else\n    {\n        pjsge = &s_jsge;\n    }\n\n    return pjsge;\n}\n#endif // SKIP_ASM\n\nvoid AddJsgContext(JSG *pjsg, OID oid)\n{\n    PjsgeAllocJsg(pjsg, JSGEK_Context, oid, 1);\n}\n\nvoid AddJsgCut(JSG *pjsg, OID oid)\n{\n    PjsgeAllocJsg(pjsg, JSGEK_Cut, oid, 1);\n}\n\nvoid AddJsgFocus(JSG *pjsg, OID oid)\n{\n    PjsgeAllocJsg(pjsg, JSGEK_Focus, oid, 1);\n}\n\nvoid AddJsgLabel(JSG *pjsg, OID oid)\n{\n    JSGE *pjsge = PjsgeAllocJsg(pjsg, JSGEK_Label, OID_Nil, 1);\n    pjsge->label.oid = oid;\n}\n\nvoid AddJsgTunnel(JSG *pjsg, OID oid)\n{\n    PjsgeAllocJsg(pjsg, JSGEK_Tunnel, oid, 1);\n}\n\nvoid AddJsgPause(JSG *pjsg, OID oid, float dtPause)\n{\n    JSGE *pjsge = PjsgeAllocJsg(pjsg, JSGEK_Pause, oid, 0);\n    pjsge->pause.dtPause = dtPause;\n}\n\nvoid AddJsgAseg(JSG *pjsg, OID oid, int fAsync)\n{\n    PjsgeAllocJsg(pjsg, JSGEK_Aseg, oid, fAsync);\n}\n\nvoid AddJsgJump(JSG *pjsg, OID oid, JSGJK jsgjk, JSGLK jsglk, int fAsync)\n{\n    JSGE *pjsge = PjsgeAllocJsg(pjsg, JSGEK_Jump, oid, fAsync);\n    pjsge->jump.jsgjk = jsgjk;\n    pjsge->jump.jsglk = jsglk;\n}\n\nvoid AddJsgRun(JSG *pjsg, OID oid, float uRun, int fAsync)\n{\n    JSGE *pjsge = PjsgeAllocJsg(pjsg, JSGEK_Run, oid, fAsync);\n    pjsge->run.uRun = uRun;\n}\n\nvoid AddJsgClimb(JSG *pjsg, OID oid, float uClimb, int fAsync)\n{\n    JSGE *pjsge = PjsgeAllocJsg(pjsg, JSGEK_Climb, oid, fAsync);\n    pjsge->climb.uClimb = uClimb;\n}\n\nvoid AddJsgAttack(JSG *pjsg, OID oid, FTAK ftak, int fAsync)\n{\n    JSGE *pjsge = PjsgeAllocJsg(pjsg, JSGEK_Attack, oid, fAsync);\n    pjsge->attack.ftak = ftak;\n}\n\nvoid AddJsgClock(JSG *pjsg, float rdt)\n{\n    JSGE *pjsge = PjsgeAllocJsg(pjsg, JSGEK_Clock, OID_Nil, 1);\n    pjsge->clock.rdt = rdt;\n}\n\nvoid AddJsgUnknown(JSG *pjsg)\n{\n    PjsgeAllocJsg(pjsg, JSGEK_Unknown, OID_Nil, 0);\n}\n"
  },
  {
    "path": "src/P2/jt.c",
    "content": "#include <jt.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", InitJt__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", LoadJtFromBrx__FP2JTP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", PostJtLoad__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", PresetJtAccelBase);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", PresetJtAccel__FP2JTf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", AdjustJtNewXp__FP2JTP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", AdjustJtDz__FP2JTiP2DZif);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", HandleJtGrfjtsc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJtInternalXps__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FCheckJtXpBase__FP2JTP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", AdjustJtXpVelocity__FP2JTP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", HandleJtMessage__FP2JT5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FTurnJtToTarget__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJtBalance__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", RebuildJtXmg__FP2JTP3ALOfT1P6ACTADJP3XMG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FMatchJtXmg__FP2JTP3XMGP6ACTADJ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJtStand__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", ThrowJt__FP2JTP6VECTORff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UnhookJt__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", CalculateJtToolSpin__FP2JTfP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", RenderJtAll__FP2JTP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FUN_00172530);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FUN_001725e0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJtTool__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FUN_00172898);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJtPosWorldPrev__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FUN_00172b08);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJtBounds__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", PsoGetJtEffect__FP2JTPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", AddJtCustomXps__FP2JTP2SOiP3BSPT3PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", CtTorqueJt__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FUN_00172ee0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", GetJtCpdefiFlatten__FP2JTP6CPDEFI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FUN_00173708);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FUN_00173750);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJtActive__FP2JTP3JOYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJt__FP2JTf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJtDrive__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", ChooseJtPhys__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", EnableJtActadj__FP2JTi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", SetJtJts__FP2JT3JTS4JTBS);\n\nvoid ProfileJt(JT *pjt, int fProfile)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", SetJtPuppet__FP2JTP5ASEGA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FUN_00177828);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", PaloAbsorbWkr__FP3WKRiPP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", NCmpWkr__FP3WKRT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", UpdateJtEffect__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", FIsJtSoundBase__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", CollectJtPrize__FP2JT3PCKP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", GetJtDiapi__FP2JTP6DIALOGP5DIAPI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jt\", PlayJtDialog__FP2JTP6DIALOG);\n"
  },
  {
    "path": "src/P2/jump.c",
    "content": "#include <jump.h>\n#include <find.h>\n\nextern DL g_dlJmt;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", PresetJtAccelJump__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", UpdateJtActiveJump__FP2JTP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", FCheckJtSingleEdge__FP2JTP2SOP4EDGEP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", FCheckJtEdgeNormal__FP2JTP6VECTORT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", FCheckJtEdgeGrab__FP2JTP2SOP6VECTOR3XPKPvT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", PxpFindJtBestEdge__FP2JTPiP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", JtsResetJt__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", HandleJtDiveEffect__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", FUN_0017ece8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", UpdateJtJump__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", FTimeJtJumpToTarget__FP2JTP6VECTORN31Pf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", GetJtJumpVelocity__FP2JTP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", GetJtJumpToTargetVelocity__FP2JTP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", GetJtJumpBoostVelocity__FP2JTP6VECTOR);\n\nvoid StartupJmt()\n{\n    InitDl(&g_dlJmt, 0x50);\n}\n\nvoid ResetJmtList()\n{\n    ClearDl(&g_dlJmt);\n}\n\nvoid OnJmtAdd(JMT *pjmt)\n{\n    OnLoAdd(pjmt);\n    AppendDlEntry(&g_dlJmt, pjmt);\n}\n\nvoid OnJmtRemove(JMT *pjmt)\n{\n    OnLoRemove(pjmt);\n    RemoveDlEntry(&g_dlJmt, pjmt);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/jump\", CloneJmt__FP3JMTT0);\n\nvoid PostJmtLoad(JMT *pjmt)\n{\n    PostLoLoad(pjmt);\n\n    if (pjmt->oidSetIgnoreJt != OID_Nil)\n    {\n        pjmt->psoSetIgnoreJt = (SO *)PloFindSwObject(pjmt->psw, 0x104, pjmt->oidSetIgnoreJt, pjmt);\n    }\n}\n"
  },
  {
    "path": "src/P2/keyhole.c",
    "content": "#include <keyhole.h>\n\nextern KEYHOLE *g_pkeyhole;\n\nvoid InitKeyhole(KEYHOLE *pkeyhole)\n{\n    InitLo(pkeyhole);\n    g_pkeyhole = pkeyhole;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/keyhole\", LoadKeyholeFromBrx__FP7KEYHOLEP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/keyhole\", DrawKeyholeMask__FP7KEYHOLEffff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/keyhole\", DrawKeyhole__FP7KEYHOLEf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/keyhole\", keyhole__static_initialization_and_destruction_0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/keyhole\", _GLOBAL_$I$InitKeyhole__FP7KEYHOLE);\n"
  },
  {
    "path": "src/P2/landing.c",
    "content": "#include <landing.h>\n#include <sw.h>\n\nvoid OnLandingAdd(LANDING *planding)\n{\n    OnLoAdd(planding);\n    AppendDlEntry(&planding->psw->dlLanding, planding);\n}\n\nvoid OnLandingRemove(LANDING *planding)\n{\n    OnLoRemove(planding);\n    RemoveDlEntry(&planding->psw->dlLanding, planding);\n}\n\nvoid CloneLanding(LANDING *planding, LANDING *plandingBase)\n{\n    DLE dleLanding = planding->dleLanding;\n    CloneLo(planding, plandingBase);\n    planding->dleLanding = dleLanding;\n}\n"
  },
  {
    "path": "src/P2/lgn.c",
    "content": "#include <lgn.h>\n#include <suv.h>\n\nvoid InitLgn(LGN *plgn)\n{\n    InitSuv((SUV *)plgn);\n    STRUCT_OFFSET(plgn, 0xbf4, float) = -10.0f; // plgn->tFlash\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", PostLgnLoad__FP3LGN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", UpdateLgnActive__FP3LGNP3JOYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", UpdateLgn__FP3LGNf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", FUN_00181658);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", OnLgnActive__FP3LGNiP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", RenderLgnAll__FP3LGNP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", GetLgnCpdefi__FP3LGNfP6CPDEFI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", FInvulnerableLgn__FP3LGN3ZPK);\n\nJTHS JthsCurrentLgn(LGN *plgn)\n{\n    return (JTHS)(STRUCT_OFFSET(plgn, 0xbf0, int) != 0); // plgn->fFlash\n}\n\nvoid UseLgnCharm(LGN *plgn)\n{\n    UsePoCharm((PO *)plgn);\n    SetLgnLgns(plgn, LGNS_Active);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", ApplyLgnThrow__FP3LGNP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", FTakeLgnDamage__FP3LGNP3ZPR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", HandleLgnMessage__FP3LGN5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", FUN_00181d88);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", SetLgnLgns__FP3LGN4LGNS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", UpdateLgnrAim__FP4LGNRP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", DrawLgnr__FP4LGNR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", InitSwp__FP3SWP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", PostSwpLoad__FP3SWP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", UpdateSwp__FP3SWPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", ProjectSwpTransform__FP3SWPfi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lgn\", SetSwpShape__FP3SWPP5SHAPEf);\n"
  },
  {
    "path": "src/P2/light.c",
    "content": "#include <light.h>\n#include <gcc/math.h>\n#include <shd.h>\n#include <frm.h>\n#include <sw.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", InitLight__FP5LIGHT);\n\nvoid UpdateLightXfWorldHierarchy(LIGHT *plight)\n{\n    UpdateAloXfWorldHierarchy(plight);\n    RebuildLightVifs(plight);\n    UpdateLightBeamGrfzon(plight);\n}\n\nvoid RemoveLightFromSw(LIGHT *plight)\n{\n    RemoveDlEntry(&plight->psw->dlLight, plight);\n    InvalidateLight(plight);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", AddLightToSw__FP5LIGHT);\n\nvoid OnLightAdd(LIGHT *plight)\n{\n    OnAloAdd(plight);\n    AddLightToSw(plight);\n}\n\nvoid OnLightRemove(LIGHT *plight)\n{\n    OnAloRemove(plight);\n    RemoveLightFromSw(plight);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", CloneLight__FP5LIGHTT0);\n\nvoid FitLinearFunction(float x0, float y0, float x1, float y1, float *pdu, float *pru)\n{\n    if (FFloatsNear(x0, x1, 0.0001f))\n    {\n        *pru = 0.0f;\n        *pdu = y0;\n        return;\n    }\n\n    float a = (y1 - y0) / (x1 - x0);\n    *pru = a;\n    *pdu = y0 - a * x0;\n}\n\n/**\n * @todo 88.80% match. The code is possibly in the wrong order.\n * https://decomp.me/scratch/c1tUS\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", FitRecipFunction__FffffPfT4);\n#ifdef SKIP_ASM\nvoid FitRecipFunction(float x0, float y0, float x1, float y1, float *pdu, float *pru)\n{\n    float gEpsilon = 0.0001f;\n    if (!FFloatsNear(x0, x1, gEpsilon) && __builtin_fabsf(x0) < gEpsilon && __builtin_fabsf(x1) < gEpsilon)\n    {\n        *pru = 0.0f;\n        *pdu = y0;\n        return;\n    }\n\n    float deltaX = x0 - x1;\n    float deltaY = y1 - y0;\n\n    float r = ((x0 * x1) * deltaY) / deltaX;\n    float d = y0 - (r / x0);\n\n    *pru = r;\n    *pdu = d;\n}\n#endif // SKIP_ASM\n\nvoid ConvertFallOff(LM *plm, float *pdu, float *pru)\n{\n    FitLinearFunction(plm->gMin, 1.0f, plm->gMax, 0.0f, pdu, pru);\n}\n\nvoid ConvertAngleStrength(float deg0, float g0, float deg1, float g1, float *pdu, float *pru)\n{\n    // NOTE: The constant kDegToHalfRad is (3.1415926f / 180.0f) * 0.5f\n    // Putting that here doesn't yield the same output due to precision loss.\n    const float kDegToHalfRad = 0.008726647f;\n    const float kStrengthScale = 1.0f / 255.0f;\n\n    float strength0 = cosf(deg0 * kDegToHalfRad);\n    strength0 += strength0 * strength0 * strength0;\n\n    float strength1 = cosf(deg1 * kDegToHalfRad);\n    strength1 += strength1 * strength1 * strength1;\n\n    FitLinearFunction(strength0, g0 * kStrengthScale, strength1, g1 * kStrengthScale, pdu, pru);\n}\n\nvoid InvalidateLight(LIGHT *plight)\n{\n    if (STRUCT_OFFSET(plight, 0x304, int) == 0) // plight->fDynamic\n    {\n        g_cframeStaticLightsInvalid = g_cframe;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", RebuildLightVifs__FP5LIGHT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", SetLightKind__FP5LIGHT6LIGHTK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", SetLightHighlightColor__FP5LIGHTP6VECTOR);\n\nvoid SetLightMidtoneStrength(LIGHT *plight, float gMidtone)\n{\n    STRUCT_OFFSET(plight, 0x2f0, float) = gMidtone; // plight->gMidtone\n    RebuildLightVifs(plight);\n}\n\nvoid SetLightShadowStrength(LIGHT *plight, float gShadow)\n{\n    STRUCT_OFFSET(plight, 0x2f4, float) = gShadow; // plight->gShadow\n    RebuildLightVifs(plight);\n}\n\nvoid SetLightHighlightAngle(LIGHT *plight, float degHighlight)\n{\n    STRUCT_OFFSET(plight, 0x2f8, float) = degHighlight; // plight->degHighlight\n    RebuildLightVifs(plight);\n}\n\nvoid SetLightMidtoneAngle(LIGHT *plight, float degMidtone)\n{\n    STRUCT_OFFSET(plight, 0x2fc, float) = degMidtone; // plight->degMidtone\n    RebuildLightVifs(plight);\n}\n\nvoid SetLightShadowAngle(LIGHT *plight, float degShadow)\n{\n    STRUCT_OFFSET(plight, 0x300, float) = degShadow; // plight->degShadow\n    RebuildLightVifs(plight);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", SetLightDirection__FP5LIGHTP6VECTOR);\n\nvoid SetLightDynamic(LIGHT *plight, int fDynamic)\n{\n    if (fDynamic != STRUCT_OFFSET(plight, 0x304, int)) // plight->fDynamic\n    {\n        STRUCT_OFFSET(plight, 0x304, int) = fDynamic; // plight->fDynamic\n        RebuildLightVifs(plight);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", SetLightFallOff__FP5LIGHTP2LM);\n\nvoid SetLightConeAngle(LIGHT *plight, float degCone)\n{\n    STRUCT_OFFSET(plight, 0x338, float) = degCone; // plight->degCone\n    RebuildLightFrustrum(plight);\n    RebuildLightVifs(plight);\n    UpdateLightBeamGrfzon(plight);\n}\n\nvoid SetLightHotSpotAngle(LIGHT *plight, float degHotSpot)\n{\n    STRUCT_OFFSET(plight, 0x33c, float) = degHotSpot; // plight->degHotSpot\n    RebuildLightFrustrum(plight);\n    RebuildLightVifs(plight);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", SetLightFrustrumUp__FP5LIGHTP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", RebuildLightFrustrum__FP5LIGHT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", UpdateLightBeamGrfzon__FP5LIGHT);\n\nvoid SetLightDiffuse_Old(LIGHT *plight, float gDiffuse)\n{\n    SetLightMidtoneStrength(plight, gDiffuse);\n    SetLightShadowStrength(plight, gDiffuse);\n}\n\nvoid GetLightDiffuse_Old(LIGHT *plight, float *pgDiffuse)\n{\n    *pgDiffuse = STRUCT_OFFSET(plight, 0x2f0, float); // plight->gMidtone\n}\n\nvoid SetLightSaturate_Old(LIGHT *plight, VECTOR *pvecSaturate)\n{\n    VECTOR vecHsv;\n    ConvertUserRgbToUserHsv(pvecSaturate, &vecHsv);\n    SetLightHighlightColor(plight, &vecHsv);\n}\n\nvoid GetLightSaturate_Old(LIGHT *plight, VECTOR *pvecSaturate)\n{\n    ConvertUserHsvToUserRgb(&STRUCT_OFFSET(plight, 0x2e0, VECTOR), pvecSaturate); // plight->vecHighlight\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", NCmpFindLight__FPP5LIGHTT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", PrepareSwLightsForDraw__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/light\", TwpsFindSwLights__FP2SWP6VECTORfiiPiT5PP5LIGHT);\n"
  },
  {
    "path": "src/P2/lo.c",
    "content": "#include <lo.h>\n#include <sw.h>\n#include <alo.h>\n#include <brx.h>\n#include <util.h>\n#include <find.h>\n#include <game.h>\n#include <memory.h>\n#include <spliceobj.h>\n#include <splice/gc.h>\n#include <splice/ref.h>\n#include <splice/vecmat.h>\n\nextern CGc g_gc;\n\nvoid InitLo(LO *plo)\n{\n    plo->pvtlo->pfnSetLoDefaults(plo);\n    plo->pvtlo->pfnAddLo(plo);\n}\n\nvoid PostLoLoad(LO *plo)\n{\n    HandleLoSpliceEvent(plo, 0, 0, NULL);\n}\n\nvoid AddLo(LO *plo)\n{\n    DL *pdl = plo->paloParent ? &plo->paloParent->dlChild : &plo->psw->dlChild;\n    if (FFindDlEntry(pdl, plo))\n        return;\n\n    AppendDlEntry(pdl, plo);\n\n    if (FIsLoInWorld(plo))\n    {\n        plo->pvtlo->pfnAddLoHierarchy(plo);\n    }\n}\n\nvoid AddLoHierarchy(LO *plo)\n{\n    plo->pvtlo->pfnOnLoAdd(plo);\n    plo->pvtlo->pfnSendLoMessage(plo, MSGID_added, plo);\n}\n\nvoid OnLoAdd(LO *plo)\n{\n    return;\n}\n\nvoid RemoveLo(LO *plo)\n{\n    DL *pdl = plo->paloParent ? &plo->paloParent->dlChild : &plo->psw->dlChild;\n    if (!FFindDlEntry(pdl, plo))\n        return;\n\n    if (FIsLoInWorld(plo))\n    {\n        RemoveDlEntry(pdl, plo);\n        plo->pvtlo->pfnRemoveLoHierarchy(plo);\n    }\n    else\n    {\n        RemoveDlEntry(pdl, plo);\n    }\n}\n\nvoid DeferLoRemove(LO *plo)\n{\n    ALO *palo = (plo->pvtlo->grfcid & 1U) ? (ALO *)plo : plo->paloParent;\n    if (!palo)\n        return;\n\n    DLR *pdlr = (DLR *)PvAllocSwImpl(sizeof(DLR));\n    pdlr->oidChild = plo->oid;\n    pdlr->pdlrNext = STRUCT_OFFSET(palo, 0x2c4, DLR *); // palo->pdlrFirst\n    STRUCT_OFFSET(palo, 0x2c4, DLR *) = pdlr; // palo->pdlrFirst\n}\n\nvoid SetLoSuckHideLimits(LO *plo, LM *plmUSuck)\n{\n    if (FCheckLm(plmUSuck, g_plsCur->uSuck))\n    {\n        DeferLoRemove(plo);\n    }\n}\n\nvoid RemoveLoHierarchy(LO *plo)\n{\n    plo->pvtlo->pfnOnLoRemove(plo);\n    plo->pvtlo->pfnSendLoMessage(plo, MSGID_removed, plo);\n}\n\nvoid OnLoRemove(LO *plo)\n{\n    return;\n}\n\nvoid SnipLo(LO *plo)\n{\n    if (!FIsLoInWorld(plo))\n        return;\n\n    if (plo->pvtlo->pfnBindLo)\n    {\n        plo->pvtlo->pfnBindLo(plo);\n    }\n\n    plo->pvtlo->pfnPostLoLoad(plo);\n    plo->pvtlo->pfnRemoveLo(plo);\n}\n\nint FFindLoParent(LO *plo, ALO *paloParent)\n{\n    if (!plo)\n    {\n        return 0;\n    }\n\n    while (plo)\n    {\n        if (plo == paloParent)\n        {\n            return 1;\n        }\n\n        plo = plo->paloParent;\n    }\n\n    return (paloParent == NULL);\n}\n\nvoid SetLoParent(LO *plo, ALO *paloParent)\n{\n    plo->pvtlo->pfnRemoveLo(plo);\n    plo->paloParent = paloParent;\n    plo->pvtlo->pfnAddLo(plo);\n}\n\nint FIsLoInWorld(LO *plo)\n{\n    while (plo)\n    {\n        ALO *paloParent = plo->paloParent;\n\n        if (paloParent)\n        {\n            if (!FFindDlEntry(&paloParent->dlChild, plo))\n            {\n                return 0;\n            }\n        }\n        else\n        {\n            if (!FFindDlEntry(&plo->psw->dlChild, plo))\n            {\n                return 0;\n            }\n        }\n\n        plo = paloParent;\n    }\n\n    return 1;\n}\n\nvoid GetLoInWorld(LO *plo, int *pfInWorld)\n{\n    *pfInWorld = FIsLoInWorld(plo);\n}\n\nJUNK_ADDIU(30);\n\nLO *PloCloneLo(LO *plo, SW *psw, ALO *paloParent)\n{\n    LO *ploClone = PloNew(plo->pvtbasic->cid, psw, paloParent, plo->oid, -1);\n    ploClone->pvtlo->pfnCloneLoHierarchy(ploClone, plo);\n    return ploClone;\n}\n\nvoid CloneLoHierarchy(LO *plo, LO *ploBase)\n{\n    plo->pvtlo->pfnCloneLo(plo, ploBase);\n}\n\nvoid CloneLo(LO *plo, LO *ploBase)\n{\n    if (ploBase->psidebag)\n    {\n        CSidebag *psidebag = PsidebagNew();\n        ploBase->psidebag->CloneTo(psidebag);\n        plo->psidebag = psidebag;\n        g_gc.AddRootSidebag(psidebag);\n    }\n\n    SW *psw = plo->psw;\n\n    // Adjusted arguments for target assembly alignment\n    CopyAb(&STRUCT_OFFSET(plo, 0x34, void *), &STRUCT_OFFSET(ploBase, 0x34, void *), ploBase->pvtlo->cb - 0x34);\n\n    DL *pdl = PdlFromSwOid(psw, plo->oid);\n    RemoveDlEntry(pdl, plo);\n    pdl = PdlFromSwOid(psw, ploBase->oid);\n    AppendDlEntry(pdl, plo);\n\n    plo->oid = ploBase->oid;\n\n    if (ploBase->pframe)\n    {\n        g_gc.UpdateRecyclable();\n        CFrame *pframe = PframeNew();\n        ploBase->pframe->CloneTo(pframe);\n        plo->pframe = pframe;\n        g_gc.AddRootFrame(pframe);\n    }\n\n    plo->ppxr = ploBase->ppxr;\n}\n\nvoid SubscribeSwPpmqStruct(SW *psw, MQ **ppmqFirst, PFNMQ pfnmq, void *pvContext)\n{\n    MQ *pmq = PmqAllocSw(psw);\n    pmq->pfnmq = pfnmq;\n    pmq->pvContext = pvContext;\n    pmq->pmqNext = *ppmqFirst;\n    *ppmqFirst = pmq;\n}\n\nvoid UnsubscribeSwPpmqStruct(SW *psw, MQ **ppmqFirst, PFNMQ pfnmq, void *pvContext)\n{\n    MQ *pmq;\n\n    while (pmq = *ppmqFirst)\n    {\n        MQ *pmqTarget;\n        MQ **ppmqList = ppmqFirst;\n\n        if (pmq->pfnmq == pfnmq && pmq->pvContext == pvContext)\n        {\n            *ppmqFirst = pmq->pmqNext;\n            pmq->pmqNext = NULL;\n            pmqTarget = pmq;\n            FreeSwMqList(psw, pmqTarget);\n            break;\n        }\n\n        pmqTarget = *ppmqList;\n        pmq = pmqTarget;\n        ppmqFirst = &pmq->pmqNext;\n    }\n}\n\nvoid SubscribeLoStruct(LO *plo, PFNMQ pfnmq, void *pvContext)\n{\n    SubscribeSwPpmqStruct(plo->psw, &plo->pmqFirst, pfnmq, pvContext);\n}\n\nvoid UnsubscribeLoStruct(LO *plo, PFNMQ pfnmq, void *pvContext)\n{\n    UnsubscribeSwPpmqStruct(plo->psw, &plo->pmqFirst, pfnmq, pvContext);\n}\n\nvoid SubscribeLoObject(LO *plo, LO *ploTarget)\n{\n    SubscribeSwPpmqStruct(plo->psw, &plo->pmqFirst, ploTarget->pvtlo->pfnHandleLoMessage, ploTarget);\n}\n\nvoid UnsubscribeLoObject(LO *plo, LO *ploTarget)\n{\n    UnsubscribeSwPpmqStruct(plo->psw, &plo->pmqFirst, ploTarget->pvtlo->pfnHandleLoMessage, ploTarget);\n}\n\nvoid SendLoMessage(LO *plo, MSGID msgid, void *pv)\n{\n    if (plo->pvtlo->pfnHandleLoMessage)\n    {\n        plo->pvtlo->pfnHandleLoMessage(plo, msgid, pv);\n    }\n\n    MQ *pmq = plo->pmqFirst;\n\n    while (pmq)\n    {\n        PFNMQ pfnmq = pmq->pfnmq;\n        void *pmqContext = pmq->pvContext;\n\n        pmq = pmq->pmqNext;\n\n        pfnmq(pmqContext, msgid, pv);\n    }\n}\n\nvoid LoadLoFromBrx(LO *plo, CBinaryInputStream *pbis)\n{\n    LoadOptionsFromBrx(plo, pbis);\n}\n\nint FMatchesLoName(LO *plo, OID oid)\n{\n    if (oid == OID_Nil)\n    {\n        return 0;\n    }\n\n    if (plo->oid == oid || (plo->ppxr && plo->ppxr->oidProxyRoot == oid))\n    {\n        return 1;\n    }\n\n    return 0;\n}\n\nOID OidProxyLo(LO *plo)\n{\n    if (plo->ppxr)\n    {\n        return plo->ppxr->oidProxyRoot;\n    }\n\n    return OID_Nil;\n}\n\nOID OidProxyLoPreferred(LO *plo)\n{\n    if (plo->ppxr)\n    {\n        return plo->ppxr->oidProxyRoot;\n    }\n\n    return plo->oid;\n}\n\nvoid GetLoOidProxy(LO *plo, OID *poid)\n{\n    *poid = OidProxyLo(plo);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lo\", PostSpliceEventCallback__FP2LOUiPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lo\", FFilterSpliceEvent__FP2LO7SYMEVIDiPPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lo\", HandleLoSpliceEvent__FP2LOUiiPPv);\n\nvoid EnsureLoSidebagBool(LO *plo, OPTID optid, int f)\n{\n    CRef ref = CRef();\n    ref.SetBool(f);\n    RefEnsureOption(plo, optid, &ref);\n}\n\nvoid EnsureLoSidebagInt(LO *plo, OPTID optid, int n)\n{\n    CRef ref = CRef();\n    ref.SetS32(n);\n    RefEnsureOption(plo, optid, &ref);\n}\n\nvoid EnsureLoSidebagFloat(LO *plo, OPTID optid, float g)\n{\n    CRef ref = CRef();\n    ref.SetF32(g);\n    RefEnsureOption(plo, optid, &ref);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lo\", EnsureLoSidebagClq__FP2LO5OPTIDP3CLQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lo\", EnsureLoSidebagLm__FP2LO5OPTIDP2LM);\n\nvoid EnsureLoSidebagOid(LO *plo, OPTID optid, OID oid)\n{\n    CRef ref = CRef();\n    ref.SetS32(oid);\n    RefEnsureOption(plo, optid, &ref);\n}\n\n/**\n * @todo 92.29% match.\n * https://decomp.me/scratch/uhZNV\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/lo\", EnsureLoSidebagVector__FP2LO5OPTIDP6VECTOR);\n#ifdef SKIP_ASM\nvoid EnsureLoSidebagVector(LO *plo, OPTID optid, VECTOR *pvec)\n{\n    CRef ref = CRef();\n    VECTOR *pvector = PvectorNew();\n    *pvector = *pvec;\n    ref.SetVector(pvector);\n    RefEnsureOption(plo, optid, &ref);\n}\n#endif // SKIP_ASM\n"
  },
  {
    "path": "src/P2/lookat.c",
    "content": "#include <lookat.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lookat\", InitActla__FP5ACTLAP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lookat\", SetActlaTarget__FP5ACTLAP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lookat\", PaloGetActlaTarget__FP5ACTLA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lookat\", UpdateActla__FP5ACTLAf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/lookat\", GetActlaRotationGoal__FP5ACTLAfP7MATRIX3P6VECTOR);\n"
  },
  {
    "path": "src/P2/main.c",
    "content": "#include \"common.h\"\n#include <lib/libkernl/filestub.h>\n#include <sdk/ee/eekernel.h>\n#include <sdk/ee/sifrpc.h>\n#include <sdk/ee/sifdev.h>\n#include <sdk/libcdvd.h>\n#include <sce/libdma.h>\n#include <phasemem.h>\n#include <memcard.h>\n#include <memory.h>\n#include <target.h>\n#include <thread.h>\n#include <render.h>\n#include <clock.h>\n#include <blip.h>\n#include <aseg.h>\n#include <mpeg.h>\n#include <jump.h>\n#include <font.h>\n#include <hide.h>\n#include <pipe.h>\n#include <wipe.h>\n#include <prog.h>\n#include <dmas.h>\n#include <frm.h>\n#include <joy.h>\n#include <brx.h>\n#include <ui.h>\n#include <sw.h>\n#include <cm.h>\n#include <cd.h>\n#include <gs.h>\n\nextern void *D_00211E10;\nextern void *D_00212110;\n\n// Forward declarations.\nvoid Startup();\nvoid StartupSif();\nvoid StartupVU0();\nvoid StartupVU1();\n\n/**\n * @brief List of IOP modules.\n */\nstatic char *s_apchzSifModules[6] =\n{\n    \"sio2man.irx\", \"padman.irx\", \"mcman.irx\",\n    \"mcserv.irx\", \"libsd.irx\", \"989snd.irx\"\n};\n\n/**\n * @brief Startup function pointer.\n */\ntypedef void (*SFN)(void);\n\n/**\n * @brief Array of startup functions.\n */\nstatic SFN s_asfn[29] =\n{\n    StartupAseg,   StartupMemMgr,  StartupDma,\n    StartupThread, StartupGs,      StartupSif,\n    StartupCd,     StartupCatalog, StartupJoy,\n    StartupCodes,  StartupFrame,   StartupFont,\n    StartupBrx,    StartupCm,      StartupSound,\n    StartupScreen, StartupUi,      StartupTarget,\n    StartupJmt,    StartupPipe,    StartupHide,\n    StartupVU0,    StartupVU1,     StartupBlips,\n    StartupRender, StartupClock,   StartupMemcard,\n    StartupGame,   StartupMpeg\n};\n\n/**\n * @brief Global pointers to command-line arguments.\n * @todo Are these the right way around?\n */\nint g_cpchzArgs = 0;\nchar **g_apchzArgs = NULL;\n\n/**\n * @brief Main function.\n *\n * Invoked by the startup routine, starts the main game loop.\n *\n * @todo 80.99% matched\n * https://decomp.me/scratch/4XwiN\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/main\", main);\n#ifdef SKIP_ASM\nint main(char **argv, int argc) {\n    g_apchzArgs = argv;\n    g_cpchzArgs = argc;\n\n    // These appear to be loaded into registers in the target assembly\n    Startup();\n    CMpeg* mpeg = &g_mpeg;\n\n    while (true)\n    {\n        if (g_mpeg.oid_1 && g_pwipe->wipes != WIPES_WipingOut)\n        {\n            FlushFrames(1);\n            mpeg->ExecuteOids();\n        }\n\n        if (g_transition.m_fPending)\n        {\n            FlushFrames(1);\n            g_transition.Execute();\n        }\n\n        if (g_mpeg.oid_1 && g_pwipe->wipes != WIPES_WipingOut)\n        {\n            FlushFrames(1);\n            mpeg->ExecuteOids();\n        }\n\n        UpdateJoy(&g_joy);\n        UpdateCodes();\n        UpdateSave(&g_save);\n        UpdateUi(&g_ui);\n        UpdateGameState(g_clock.dt);\n\n        if (g_psw)\n        {\n            SetupCm(g_pcm);\n            OpenFrame();\n\n            MarkClockTick(&g_clock);\n\n            if (g_psw->pcbUpdate)\n            {\n                g_psw->pcbUpdate(g_clock.dt);\n            }\n\n            RenderSw(g_psw, g_pcm);\n            RenderUi();\n            DrawSw(g_psw, g_pcm);\n            DrawUi();\n            CloseFrame();\n        }\n\n        g_cframe += 1;\n    }\n}\n#endif\n\n/**\n * @brief Starts up the PS2 subsystem interface.\n */\nvoid StartupSif()\n{\n    // Create a path to the \"ioprp243.img\" image.\n    char achzPath[256];\n    CdPath(achzPath, \"ioprp243.img\", 1);\n    \n    // Initialize SIF RPC system and CD/DVD subsystem.\n    sceSifInitRpc(0);\n    sceCdInit(0);\n\n    // Hang if the CD media mode is invalid at startup.\n    if (!FValidCdMmode())\n    {\n        while (true) {}\n    }\n\n    // Set the CD media mode and reset the filesystem.\n    SetCdMmode();\n    sceFsReset();\n\n    // Reboot the IOP using the \"ioprp243.img\" image and wait until it completes.\n    while (!sceSifRebootIop(achzPath)) {}\n    while (!sceSifSyncIop()) {}\n\n    // Reinitialize SIF and CD/DVD systems after reboot.\n    sceSifInitRpc(0);\n    sceSifLoadFileReset();\n    sceCdInit(0);\n\n    // Hang if the CD media mode is invalid after reboot.\n    if (!FValidCdMmode())\n    {\n        while (true) {}\n    }\n\n    // Restore CD media mode and reset FS again after reboot.\n    SetCdMmode();\n    sceFsReset();\n    sceCdDiskReady(0);\n    FCdCompleted(1);\n\n    // Load IOP modules listed in s_apchzSifModules.\n    for (uint i = 0; i < 6; i++)\n    {\n        CdPath(achzPath, s_apchzSifModules[i], 1);\n        while (sceSifLoadModule(achzPath, 0, 0) < 0) {}\n    }\n}\n\n/**\n * @brief Starts up the VU0.\n */\nvoid StartupVU0()\n{\n    g_pdcVif0->chcr.TTE = 1;\n    FlushCache(0); /* XXX: bring in eekernel defs and use WRITEBACK_DCACHE */\n\n    // Send VU0 init DMAtag\n    sceDmaSend(g_pdcVif0, &D_00211E10); // D_00211E10 is start of .vutext\n    sceDmaSync(g_pdcVif0, 0, 0);\n\n    g_pdcVif0->chcr.TTE = 0;\n}\n\n/**\n * @brief Starts up the VU1.\n */\nvoid StartupVU1()\n{\n    // Enable tag transfer\n    g_pdcVif1->chcr.TTE = 1;\n    FlushCache(0); /* XXX: bring in eekernel defs and use WRITEBACK_DCACHE */\n\n    // Send initialization DMAtag and wait. Then, disable tag transfer again.\n    sceDmaSend(g_pdcVif1, &D_00212110);\n    sceDmaSync(g_pdcVif1, 0, 0);\n    g_pdcVif1->chcr.TTE = 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/main\", Startup__Fv);\n#ifdef SKIP_ASM\n/**\n * @brief Starts each game system.\n *\n * @todo 99.71% matched.\n * Stack frame is 48 bytes smaller than expected.\n * https://decomp.me/scratch/IOVxc\n * https://decomp.me/scratch/NNtNR\n */\nvoid Startup()\n{\n    // Set up the progress bar.\n    int nRemain = 26;\n    int rgbaComplete = 0x007f0000; // blue\n    int rgbaRemain = 0x003f3f3f; // gray\n    int rgbaWarning = 0x00003f3f; // yellow\n    int rgbaTrouble = 0x0000003f; // red\n    CProg prog = CProg((RGBA *)&rgbaComplete, (RGBA *)&rgbaRemain, (RGBA *)&rgbaWarning, (RGBA *)&rgbaTrouble);\n\n    // Begin startup phase.\n    SetPhase(PHASE_Startup);\n    prog.Begin();\n\n    // Call each function in the startup function array.\n    SFN *psfn = s_asfn;\n    for (int i = 0; i < sizeof(s_asfn) / sizeof(s_asfn[0]); i++)\n    {\n        if (i > 2)\n        {\n            prog.SetRemain(nRemain);\n        }\n\n        (*psfn++)();\n        nRemain--;\n    }\n\n    // Cleanup.\n    prog.SetRemain(0);\n    prog.End();\n    ClearPhase(PHASE_Startup);\n}\n#endif\n"
  },
  {
    "path": "src/P2/mark.c",
    "content": "#include <mark.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", MuFromAmtlk__FP4MTLK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", ElasFromAmtlk__FP4MTLK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", PxpAdd__FP2SOT0P6VECTORT2f3XPKPvT6PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", RecalcSwXpPos__FP2SWiPP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", RecalcSwXpMovement__FP2SWiPP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", FreeSwXpList__FP2SWP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", FindClosestPointOnLine__FP6VECTORN20PfT3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", FindClosestPointOnLineSegment__FP6VECTORN20PfT3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", ClsgClipSoAllEdges__FP2SOT0P3BSPiP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", ClsgClipSoBspEdges__FP2SOT0iP3BSPiP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", CategorizeAlsg__FiP3LSGPiT2PP3LSGT4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", CplsgFindEdgePath__FP4SURFiiP3LSGPP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", MarkSoContactsBspBsp__FP2SOT0iP3BSPT3PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", CsbiIntersectSphereBsp__FP6VECTORfiP3BSPT3P4GEOMiP3SBI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", MarkSoContactsSphereBsp__FP2SOP6VECTORfT0iP3BSPT5PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", MarkSoContactsSphereSphere__FP2SOT0PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", CalculateCenterContact__FP2SOP6VECTORfT1Pf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", FMarkSoContactsCenterBsp__FP2SOT0iP3BSPT3PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", FClipEdgeToSphere__FP6VECTORfT0T0PfT0T0T4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", FMarkSoContactsCenterSphere__FP2SOT0PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", AddSoXps__FP2SOT0iiP3BSPT4PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mark\", PxpMarkSwContactsRoot__FP2SWPP2SOi);\n"
  },
  {
    "path": "src/P2/mat.c",
    "content": "#include <mat.h>\n#include <sce/memset.h>\n\nextern VECTOR g_normalZ;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", PostCopyMatrix3__7MATRIX4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", __as__7MATRIX4RC7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", MatMulMatTransMat__FRC7MATRIX3T0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadIdentityMatrix4__FP7MATRIX4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", __ml__FRC7MATRIX4G8VU_FLOAT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", __ml__FRC7MATRIX4T0);\n\nJUNK_ADDIU(50);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", MultiplyMatrix4Vector__FP7MATRIX4P6VECTORfT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", __ml__FRC7MATRIX4G10VU_VECTOR4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", TransposeMatrix4__FP7MATRIX4T0);\n\nvoid AddMatrix4Matrix4(MATRIX4 *pmatLeft, MATRIX4 *pmatRight, MATRIX4 *pmatDst)\n{\n    for (int i = 0; i < 16; i++)\n    {\n        pmatDst->mat[0][i] = pmatLeft->mat[0][i] + pmatRight->mat[0][i];\n    }\n}\n\nJUNK_NOP();\nJUNK_WORD(0x24020001);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadRotateMatrixRad__FfP6VECTORP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadRotateMatrix__FP6VECTORP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadRotateMatrixEuler__FP6VECTORP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadMatrixFromPosRot__FP6VECTORP7MATRIX3P7MATRIX4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadMatrixFromPosRotInverse__FP6VECTORP7MATRIX3P7MATRIX4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadMatrixFromPosRotScale__FP6VECTORP7MATRIX3T0P7MATRIX4);\n\nJUNK_WORD(0x7CC30020);\nJUNK_NOP();\nJUNK_NOP();\nJUNK_ADDIU(60);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", CosRotateMatrixMagnitude__FP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", DecomposeRotateMatrixRad__FP7MATRIX3PfP6VECTOR);\n\nJUNK_ADDIU(50);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", DecomposeRotateMatrixEuler__FP7MATRIX3P6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", NormalizeRotateMatrix3__FP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", CalculateDmat__FP7MATRIX3N20);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", CalculateDmat4__FP7MATRIX4N20);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", DecomposeRotateMatrixPanTilt__FP7MATRIX3PfT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadRotateMatrixPanTilt__FffP7MATRIX3);\n\nvoid LoadLookAtMatrix(VECTOR *pdpos, MATRIX3 *pmat)\n{\n    BuildOrthonormalMatrixZ(pdpos, &g_normalZ, pmat);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", TiltMatUpright__FP7MATRIX3N20);\n\nJUNK_WORD(0x27BD0130);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", FInvertMatrix__FiPfT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", FInvertMatrix3__FP7MATRIX3T0);\n\nbool FInvertMatrix4(MATRIX4 *pmatSrc, MATRIX4 *pmatDst)\n{\n    return FInvertMatrix(4, (float *)pmatSrc, (float *)pmatDst);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", BuildOrthonormalMatrixY__FP6VECTORT0P7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", BuildOrthonormalMatrixZ__FP6VECTORT0P7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", BuildRotateVectorsMatrix__FP6VECTORT0P7MATRIX3);\n\nvoid BuildSimpleProjectionMatrix(float rx, float ry, float dxOffset, float dyOffset, float sFar, float sNear, MATRIX4 *pmat)\n{\n    memset(pmat, 0, sizeof(MATRIX4));\n\n    float zScale = (sFar + sNear) / (sFar - sNear);\n    float zTrans = (sFar * (1.0f - zScale));\n\n    pmat->mat[0][0] = rx;\n    pmat->mat[2][3] = 1.0f;\n    pmat->mat[2][0] = dxOffset;\n\n    pmat->mat[1][1] = ry;\n    pmat->mat[2][1] = dyOffset;\n\n    pmat->mat[2][2] = zScale;\n    pmat->mat[3][2] = zTrans;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadScaleMatrixScalar__FP6VECTORfP7MATRIX4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadScaleMatrixVector__FP6VECTORP7MATRIX3T0P7MATRIX4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mat\", LoadRotateVectorMatrix__FP6VECTORT0P7MATRIX3);\n"
  },
  {
    "path": "src/P2/mb.c",
    "content": "#include <mb.h>\n\nextern SNIP s_asnipLoadMbg[2];\n\nvoid InitMbg(MBG *pmbg)\n{\n    InitStepguard(pmbg);\n    STRUCT_OFFSET(pmbg, 0xe3c, int) = -1;\n}\n\nvoid LoadMbgFromBrx(MBG *pmbg, CBinaryInputStream *pbis)\n{\n    LoadStepguardFromBrx(pmbg, pbis);\n    SnipAloObjects(pmbg, 2, s_asnipLoadMbg);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", PostMbgLoad__FP3MBG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FUN_0018a510);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FUN_0018a628);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", PsoHitTestCylinderObjects__FiP6VECTORT1fiPP2SOP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FFilterMbgAttackObjects__FP3MBGP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FObstructedMbg__FP3MBGP6VECTORT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FCanMbgAttack__FP3MBG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FDetectMbg__FP3MBG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FUN_0018ab88__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FUN_0018abf0__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FUN_0018ac58__Fi);\n\nvoid UpdateMbg(MBG *pmbg, float dt)\n{\n    UpdateStepguard(pmbg, dt);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FUN_0018acf0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", UpdateMbgGoal__FP3MBGi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", UpdateMbgSgs__FP3MBG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", OnMgExitingSgs__FP3MBG3SGS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", HandleMbgMessage__FP3MBG5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mb\", FUN_0018b460);\n"
  },
  {
    "path": "src/P2/memory.c",
    "content": "#include <memory.h>\n#include <thread.h>\n#include <sce/memset.h>\n\n/**\n * @todo Change these to static when possible.\n */\nextern int s_pvGlobalMin;\nextern int s_pvGlobalMac;\nextern int s_pvWorldMin;\nextern int s_pvWorldMac;\nextern int s_pvStackMin;\nextern int s_pvStackMac;\nextern CRITSECT s_critsectStack;\nextern int s_ipvStackCur;\nextern int s_apvStackMin[];\n\nextern int g_pvHeapMin;\nextern int g_pvHeapMax;\nextern int D_0064C70F;\n\nvoid StartupMemMgr()\n{\n    int end = (int)&D_0064C70F & ~0x0f;\n\n    g_pvHeapMin = end;\n    g_pvHeapMax = 0x02000000;\n\n    s_pvGlobalMin = s_pvGlobalMac = s_pvWorldMin = s_pvWorldMac = end;\n\n    s_pvStackMin = s_pvStackMac = 0x02000000;\n    s_ipvStackCur = -1;\n\n    InitCritSect(&s_critsectStack);\n}\n\nvoid *PvAllocGlobalImpl(int cb)\n{\n    if (cb == 0)\n    {\n        return 0;\n    }\n\n    void *pv = (void *)s_pvGlobalMac;\n    s_pvGlobalMac += (cb + 0x0f) & -0x10;\n    s_pvWorldMin = s_pvWorldMac = s_pvGlobalMac;\n    return pv;\n}\n\nJUNK_NOP();\nJUNK_WORD(0xACC20004);\n\n#ifdef DEBUG\n/**\n * @todo Implement debugging function (low-priority).\n */\nvoid HardLockError()\n{\n}\n#endif\n\nvoid CheckForOutOfMemory()\n{\n    return;\n}\n\nvoid *PvAllocSwImpl(int cb)\n{\n    if (cb == 0)\n    {\n        return NULL;\n    }\n\n    CheckForOutOfMemory();\n    void *pvSw = (void *)s_pvWorldMac;\n    s_pvWorldMac += (cb + 0x0f) & -0x10;\n    return pvSw;\n}\n\nvoid FreeSw()\n{\n    s_pvWorldMac = s_pvWorldMin;\n}\n\nvoid *PvAllocSwCopyImpl(int cb, void *pvBase)\n{\n    void *pvDst = PvAllocSwImpl(cb);\n    if (pvDst)\n    {\n        CopyAb(pvDst, pvBase, cb);\n    }\n\n    return pvDst;\n}\n\nvoid *PvAllocSwClearImpl(int cb)\n{\n    void *pvBlock = PvAllocSwImpl(cb);\n    if (pvBlock)\n    {\n        memset(pvBlock, 0, cb);\n    }\n\n    return pvBlock;\n}\n\nvoid InitStackImpl()\n{\n    EnterCritSect(&s_critsectStack);\n    s_apvStackMin[++s_ipvStackCur] = s_pvStackMin;\n}\n\nvoid *PvAllocStackImpl(int cb)\n{\n    if (cb == 0)\n    {\n        return NULL;\n    }\n\n    CheckForOutOfMemory();\n    s_pvStackMin -= (cb + 0x0f) & -0x10;\n    return (void *)s_pvStackMin;\n}\n\nvoid *PvAllocStackClearImpl(int cb)\n{\n    void *pvBlock = PvAllocStackImpl(cb);\n    if (pvBlock)\n    {\n        memset(pvBlock, 0, cb);\n    }\n\n    return pvBlock;\n}\n\nvoid FreeStackImpl()\n{\n    s_pvStackMin = s_apvStackMin[s_ipvStackCur--];\n    LeaveCritSect(&s_critsectStack);\n}\n\nvoid *malloc(uint __size)\n{\n    return NULL;\n}\n\nvoid *_malloc_r(_reent *pre, uint __size)\n{\n    return NULL;\n}\n\nvoid free(void *pv)\n{\n    return;\n}\n\nvoid *__builtin_new(unsigned int cb)\n{\n    return PvAllocSwClearImpl(cb);\n}\n\nvoid __builtin_delete()\n{\n    return;\n}\n\nvoid CopyAqw(void *pvDst, void *pvSrc, int cqw)\n{\n    qword *dst = (qword *)pvDst;\n    qword *src = (qword *)pvSrc;\n\n    int remainder = cqw & 0x03;\n    int nQWords = cqw - remainder;\n\n    int processed = 0;\n    while (processed < remainder)\n    {\n        *dst++ = *src++;\n        processed++;\n    }\n\n    processed = 0;\n    while (processed < nQWords)\n    {\n        qword qw0 = src[0];\n        qword qw1 = src[1];\n        qword qw2 = src[2];\n        qword qw3 = src[3];\n        src += 4;\n\n        dst[0] = qw0;\n        dst[1] = qw1;\n        dst[2] = qw2;\n        dst[3] = qw3;\n        dst += 4;\n\n        processed += 4;\n    }\n}\n\nvoid CopyAb(void *pvDst, void *pvSrc, uint cb)\n{\n    // Do a byte copy, if not word aligned.\n    if (((uint)pvDst | (uint)pvSrc | cb) & 0x03)\n    {\n        uchar *dst = (uchar *)pvDst;\n        uchar *src = (uchar *)pvSrc;\n        for (uint i = 0; i < cb; i++)\n        {\n            *dst++ = *src++;\n        }\n\n        return;\n    }\n\n    // Copy 4 uints at a time, if aligned properly.\n    if (((uint)pvDst | (uint)pvSrc | cb) & 0x0f)\n    {\n        uint *dst = (uint *)pvDst;\n        uint *src = (uint *)pvSrc;\n\n        int remainder = (cb >> 2) & 0x03;\n        int nWords = (cb >> 2) - remainder;\n\n        int processed = 0;\n        while (processed < remainder)\n        {\n            *dst++ = *src++;\n            processed++;\n        }\n\n        // TODO: This part might be possible to clean up,\n        // but I wasn't able to. -545u\n        processed = 0;\n        while (processed < nWords)\n        {\n            uint w0 = src[0];\n            uint w1 = src[1];\n            uint w2 = src[2];\n            uint w3 = src[3];\n            src += 4;\n\n            dst[0] = w0;\n            dst[1] = w1;\n            dst[2] = w2;\n            dst[3] = w3;\n            dst += 4;\n\n            processed += 4;\n        }\n\n        return;\n    }\n\n    // Use CopyAqw, if fully 16-byte aligned.\n    CopyAqw(pvDst, pvSrc, cb >> 4);\n}\n"
  },
  {
    "path": "src/P2/missile.c",
    "content": "#include <missile.h>\n#include <asega.h>\n\nvoid InitMissile(MISSILE *pmissile)\n{\n    InitBomb(pmissile);\n    STRUCT_OFFSET(pmissile, 0x6b8, int) = 1; // pmissile->fFollowTrajectory\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", LoadMissileFromBrx__FP7MISSILEP18CBinaryInputStream);\n\nvoid OnMissileRemove(MISSILE *pmissile)\n{\n    OnSoRemove(pmissile);\n    if (STRUCT_OFFSET(pmissile, 0x6b4, ASEGA *)) // pmissile->pasegaCur\n    {\n        RetractAsega(STRUCT_OFFSET(pmissile, 0x6b4, ASEGA *));\n        STRUCT_OFFSET(pmissile, 0x6b4, ASEGA *) = NULL; // pmissile->pasegaCur\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", ProjectMissileTransform__FP7MISSILEfi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", FireMissile__FP7MISSILEP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", RenderMissileAll__FP7MISSILEP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", FUN_0018dc88);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", FUN_0018dd50);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", FUN_0018dd78);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", InitAccmiss__FP7ACCMISS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", FireAccmiss__FP7ACCMISSP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", PresetAccmissAccel__FP7ACCMISSf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", FireSplmiss__FP7SPLMISSP3ALOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/missile\", ProjectSplmissTransform__FP7SPLMISSfi);\n"
  },
  {
    "path": "src/P2/mpeg.c",
    "content": "#include <mpeg.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FUN_0018e410);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FUN_0018e480);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FUN_0018e4c0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FUN_0018e4f0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FUN_0018e558);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", StartupMpeg__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Init__15CQueueOutputIopii);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Reset__15CQueueOutputIop);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", CbWrite__15CQueueOutputIopiPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", CbSend__15CQueueOutputIopiPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Update__15CQueueOutputIop);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FAsyncDrain__15CQueueOutputIop);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", CbWrite__15CQueueOutputIpuiPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FAsyncDrain__15CQueueOutputIpu);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Init__10CMpegAudio);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Reset__10CMpegAudio);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Close__10CMpegAudio);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FAccept__10CMpegAudioiPUc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Update__10CMpegAudio);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FMpegAcceptVideo__FP7sceMpegP16sceMpegCbDataStrP5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FMpegAcceptAudio__FP7sceMpegP16sceMpegCbDataStrP5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FMpegDecodeVideo__FP7sceMpegP13sceMpegCbDataP5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FMpegDecoderIdle__FP7sceMpegP13sceMpegCbDataP5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FMpegDecoderError__FP7sceMpegP13sceMpegCbDataP5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", BuildMpegGifs__FP2QWP11sceIpuRGB32iiiii);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FUN_0018ef78);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FUN_0018f0e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", ExecuteOids__5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Execute__5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Start__5CMpegP18CBinaryAsyncStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", FUN_0018f610__5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Update__5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", Finish__5CMpeg);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", CbDemuxed__5CMpegi);\n\nJUNK_WORD(0x0002102B);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", mpeg__static_initialization_and_destruction_0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/mpeg\", _GLOBAL_$I$g_mpeg);\n"
  },
  {
    "path": "src/P2/mrkv.c",
    "content": "#include <mrkv.h>\n\nvoid InitMrkv(MRKV *pmrkv)\n{\n    InitSo(pmrkv);\n    STRUCT_OFFSET(pmrkv, 0x538, ulong) = STRUCT_OFFSET(pmrkv, 0x538, ulong) | 0x80000000000;\n    SetSoConstraints(pmrkv, CT_Locked, NULL, CT_Locked, NULL);\n}\n"
  },
  {
    "path": "src/P2/ms.c",
    "content": "#include <ms.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ms\", RenderMsGlobset__FP2MSP2CMP2RO);\n"
  },
  {
    "path": "src/P2/murray.c",
    "content": "#include <murray.h>\n\nvoid InitMurray(MURRAY *pmurray)\n{\n    InitStepguard(pmurray);\n    STRUCT_OFFSET(pmurray, 0xbd4, int) = 0; // pmurray->fAutoFadeDying\n    STRUCT_OFFSET(pmurray, 0xbd0, float) = 0.0f; // pmurray->uFling\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", PostMurrayLoad__FP6MURRAY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", FUN_0018ffb0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", OnMurrayExitingSgs__FP6MURRAY3SGS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", UpdateMurrayGoal__FP6MURRAYi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", UpdateMurraySgs__FP6MURRAY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", FUN_001903f0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", FUN_00190450);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", FAbsorbMurrayWkr__FP6MURRAYP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", FDetectMurray__FP6MURRAY);\n\nint FCanMurrayAttack(MURRAY *pmurray)\n{\n    return false;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", FUN_00190660);\n\nvoid SetMurrayPursueXfm(MURRAY *pmurray, XFM *pxfm)\n{\n    STRUCT_OFFSET(pmurray, 0xc28, XFM *) = pxfm; // pmurray->pxfmPursue\n}\n\nvoid SetMurrayPatrolXfm(MURRAY *pmurray, XFM *pxfm)\n{\n    STRUCT_OFFSET(pmurray, 0xc24, XFM *) = pxfm; // pmurray->pxfmPatrol\n}\n\nvoid CollectMurrayPrize(MURRAY *pmurray, PCK pck, ALO *palo)\n{\n    CollectPoPrize(pmurray, pck, palo);\n    if (pck == PCK_Key)\n    {\n        SetStepguardSgs(pmurray, SGS_LostPlayer, STRUCT_OFFSET(pmurray, 0x5f0, ASEG *)); // pmurray->pasegCelebrateKey\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", FUN_00190740);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/murray\", HandleMurrayMessage);\n"
  },
  {
    "path": "src/P2/path.c",
    "content": "#include <path.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", PcbspExtract__FP4CBSP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", PcgtExtract__FP3CGT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", PcgtPointInCbspQuick__FP4CBSPP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", PcgtPointInCbspSafe__FP4CBSPP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", CbskFromG__Ff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", ClsgClipEdgeToCbsp__FP4CBSPP6VECTORT1iP3LSG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", FClipEdgeToCbsp__FP4CBSPP6VECTORT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", IcgvFromPcgv__FP2CGP3CGV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", FindPathAStar__FP2CGP3CGVT1iPiPP3CGV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", SimplifyApcgvNeighbor__FP4CBSPPiPP3CGV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", CposFindPath__FP2CGP6VECTORT1iT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", FindClosestPointInCg__FP2CGP6VECTORT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", LoadPathzoneFromBrx__FP8PATHZONEP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", HookupCg__FP2CG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", CposFindPathzonePath__FP8PATHZONEP6VECTORT1iT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", FindPathzoneClosestPoint__FP8PATHZONEP6VECTORT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", FUN_00191aa8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", FUN_00191ac8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/path\", ChoosePathzoneRandomPoint__FP8PATHZONEP6VECTOR);\n"
  },
  {
    "path": "src/P2/phasemem.c",
    "content": "#include <phasemem.h>\n#include <sdk/ee/eekernel.h>\n\n// PHASE g_phase = PHASE_None; // TODO: There may be other data in this file.\n\nvoid SetPhase(PHASE phase)\n{\n    if (g_phase == phase)\n        return;\n\n    FlushCache(0);\n    g_phase = phase;\n}\n\nvoid ClearPhase(PHASE phase)\n{\n    g_phase = PHASE_None;\n}\n"
  },
  {
    "path": "src/P2/pipe.c",
    "content": "#include <pipe.h>\n#include <find.h>\n#include <dl.h>\n\nextern DL g_dlPipe;\n\nvoid StartupPipe()\n{\n    InitDl(&g_dlPipe, 0x38);\n}\n\nvoid ResetPipeList()\n{\n    ClearDl(&g_dlPipe);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pipe\", InitPipe__FP4PIPE);\n\nvoid OnPipeAdd(PIPE *ppipe)\n{\n    OnLoAdd(ppipe);\n    AppendDlEntry(&g_dlPipe, ppipe);\n}\n\nvoid OnPipeRemove(PIPE *ppipe)\n{\n    OnLoRemove(ppipe);\n    RemoveDlEntry(&g_dlPipe, ppipe);\n}\n\nvoid PostPipeLoad(PIPE *ppipe)\n{\n    PostLoLoad(ppipe);\n    if (ppipe->oid != OID_Nil)\n    {\n        // TODO: Check whether this is LO or something that inherits from it.\n        ppipe->plo = PloFindSwObject(ppipe->psw, 4, ppipe->oid, ppipe);\n    }\n}\n\nvoid ClonePipe(PIPE *ppipe, PIPE *ppipeBase)\n{\n    DLE dlePipe = ppipe->dlePipe;\n    CloneLo(ppipe, ppipeBase);\n    ppipe->dlePipe = dlePipe;\n}\n"
  },
  {
    "path": "src/P2/pnt.c",
    "content": "#include <pnt.h>\n#include <brx.h>\n\nvoid LoadPntFromBrx(PNT *ppnt, CBinaryInputStream *pbis)\n{\n    pbis->ReadVector(&ppnt->posLocal);\n    LoadOptionsFromBrx(ppnt, pbis);\n}\n\nvoid GetPntPos(PNT *ppnt, VECTOR *ppos)\n{\n    ConvertAloPos(ppnt->paloParent, NULL, &ppnt->posLocal, ppos);\n}\n\nvoid SetPntParent(PNT *ppnt, ALO *paloParent)\n{\n    ConvertAloPos(ppnt->paloParent, paloParent, &ppnt->posLocal, &ppnt->posLocal);\n    SetLoParent(ppnt, paloParent);\n}\n\nvoid ApplyPntProxy(PNT *ppnt, PROXY *pproxyApply)\n{\n    ConvertAloPos((ALO *)pproxyApply, NULL, &ppnt->posLocal, &ppnt->posLocal);\n}\n\n/**\n * @todo Rename function and figure out what does it actually do.\n */\nvoid FUN_00192150(PNT *ppnt, CBinaryInputStream *pbis)\n{\n    LoadPntFromBrx(ppnt, pbis);\n    pbis->ReadStringSw(&STRUCT_OFFSET(ppnt, 0x50, char *));\n}\n\n/**\n * @todo Rename function and figure out what does it actually do.\n */\nvoid FUN_00192190(PNT *ppnt)\n{\n    STRUCT_OFFSET(ppnt, 0x54, float) = 0.5f;\n    STRUCT_OFFSET(ppnt, 0x58, float) = 0.5f;\n}\n"
  },
  {
    "path": "src/P2/po.c",
    "content": "#include <po.h>\n#include <jt.h>\n#include <zap.h>\n\nextern int g_ippoCur;\nextern PO *g_appo[];\n\nvoid InitPo(PO *ppo)\n{\n    InitSo(ppo);\n\n    STRUCT_OFFSET(ppo, 0x598, PO *) = ppo;\n    STRUCT_OFFSET(ppo, 0x580, int) = 1;\n\n    SetPoPlayable(ppo, 1);\n}\n\nvoid ClonePo(PO *ppo, PO *ppoBase)\n{\n    CloneSo(ppo, ppoBase);\n    if (STRUCT_OFFSET(ppo, 0x550, int) == 0) // ppo->fPlayable\n    {\n        STRUCT_OFFSET(ppo, 0x550, int) = 1; // ppo->fPlayable\n        SetPoPlayable(ppo, 0);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", HandlePoMessage__FP2PO5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", OnPoActive__FP2POiT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", GetPoCpdefi__FP2POfP6CPDEFI);\n\nint FIsPoSoundBase(PO *ppo)\n{\n    return 1;\n}\n\nvoid MakePoActive(PO *ppo)\n{\n    if (ppo != PpoCur())\n    {\n        SwitchToPo(ppo);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", FInvulnerablePo__FP2PO3ZPK);\n\nint FTakePoDamage(PO *ppo, ZPR *pzpr)\n{\n    return 0;\n}\n\nJTHS JthsCurrentPo(PO *ppo)\n{\n    return JTHS_Normal;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", FUN_00192498);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", CollectPoPrize__FP2PO3PCKP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", FUN_001925C0);\n\nPO *PpoCur()\n{\n    if (g_ippoCur < 0)\n    {\n        return NULL;\n    }\n\n\treturn g_appo[g_ippoCur];\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", PpoStart__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", _IppoFindPo__FP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", AddPoToList__FP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", RemovePoFromList__FP2PO);\n\nvoid OnPoAdd(PO *ppo)\n{\n    OnSoAdd(ppo);\n    AddPoToList(ppo);\n}\n\nvoid OnPoRemove(PO *ppo)\n{\n    OnSoRemove(ppo);\n    RemovePoFromList(ppo);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", SwitchToIppo__Fi);\n\nJUNK_ADDIU(10);\n\nvoid SetPoPlayable(PO *ppo, int fPlayable)\n{\n    if (STRUCT_OFFSET(ppo, 0x550, int) == fPlayable)\n        return;\n\n    STRUCT_OFFSET(ppo, 0x550, int) = fPlayable;\n    if (fPlayable)\n    {\n        AddPoToList(ppo);\n    }\n    else\n    {\n        RemovePoFromList(ppo);\n    }\n}\n\nvoid SwitchToPo(PO *ppo)\n{\n    SwitchToIppo(_IppoFindPo(ppo));\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", PpziCur__Fv);\n\nvoid GetPoDiapi(PO *ppo, DIALOG *pdialog, DIAPI *pdiapi)\n{\n    pdiapi->fPlayable = 1;\n    pdiapi->fCallable = 1;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", PlayPoDialog__FP2POP6DIALOG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", FUN_00192a70);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", UpdatePo__FP2POf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", UsePoCharm__FP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", FUN_00192dd0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", FUN_001930B0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", po__static_initialization_and_destruction_04);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/po\", _GLOBAL_$I$InitPo__FP2PO);\n"
  },
  {
    "path": "src/P2/prog.c",
    "content": "#include <prog.h>\n#include <dmas.h>\n#include <util.h>\n#include <render.h>\n#include <gs.h>\n\nCProg::CProg(RGBA *rgbaComplete, RGBA *rgbaRemain, RGBA *rgbaWarning, RGBA *rgbaTrouble)\n{\n    m_rgbaComplete = *rgbaComplete;\n    m_rgbaRemain = *rgbaRemain;\n    m_rgbaWarning = *rgbaWarning;\n    m_rgbaTrouble = *rgbaTrouble;\n    m_fActive = 0;\n    m_cRetry = 0;\n    m_nRemain = 0;\n    m_nTarget = 0;\n    m_nMax = 0;\n}\n\nvoid CProg::Begin()\n{\n    m_fActive = 0;\n    m_cRetry = 0;\n    m_nRemain = 0;\n    m_nTarget = 0;\n    m_nMax = 0;\n}\n\nvoid CProg::SetRemain(int nRemain)\n{\n    if (m_fActive != 0)\n    {\n        if (m_nTarget == 0)\n        {\n            m_nTarget = nRemain;\n            m_nMax = nRemain << 1;\n            ClearFrameBuffers();\n        }\n        else if (this->m_nRemain == nRemain)\n        {\n            m_cRetry = m_cRetry + 1;\n        }\n        else\n        {\n            m_cRetry = 0;\n        }\n        this->m_nRemain = nRemain;\n        Draw();\n    }\n}\n\nvoid CProg::End()\n{\n    m_fActive = 0;\n    m_cRetry = 0;\n    m_nRemain = 0;\n    m_nTarget = 0;\n    m_nMax = 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/prog\", Draw__5CProg);\n#ifdef SKIP_ASM\n/**\n * @todo 34.05% matched.\n * Stack frame doesn't line up.\n * https://decomp.me/scratch/06mco\n */\nvoid CProg::Draw() {\n    QW aqwProgress[64];\n    GIFS gifs = GIFS();\n    RGBA fgColor, bgColor;\n    float xLeft, yTop, xRight, yBottom;\n\n    const float width = 620.0f;\n    const float offsetY = 412.9091f;\n\n    int totalWidth = (int)(((float)m_nTarget * width) / (float)m_nMax);\n    int filledWidth = (int)((float)totalWidth * (float)(m_nTarget - m_nRemain) / (float)m_nTarget);\n\n    gifs.AllocStatic(0x40, aqwProgress);\n    gifs.AddDmaCnt();\n\n    fgColor = m_rgbaComplete;\n\n    xLeft = 10.0f;\n    yTop = GTrunc(offsetY) * 1.1;\n    xRight = (float)filledWidth + 10.0f;\n    yBottom = GTrunc(offsetY) * 1.1 + 6.6;\n    FillScreenRect(fgColor.bRed, fgColor.bGreen, fgColor.bBlue, 0xFF, xLeft, yTop, xRight, yBottom, &gifs);\n\n    if (m_cRetry < 1) {\n        bgColor = m_rgbaRemain;\n    } else if (m_cRetry == 1) {\n        bgColor = m_rgbaWarning;\n    } else {\n        bgColor = m_rgbaTrouble;\n    }\n\n    xLeft = filledWidth + 10.0f;\n    yTop = GTrunc(offsetY) * 1.1;\n    xRight = (float)totalWidth + 10.0f;\n    yBottom = GTrunc(offsetY) * 1.1 + 6.6;\n    FillScreenRect(bgColor.bRed, bgColor.bGreen, bgColor.bBlue, 0xFF, xLeft, yTop, xRight, yBottom, &gifs);\n\n    gifs.AddPrimEnd();\n    gifs.AddDmaEnd();\n    gifs.EndDmaCnt();\n    gifs.Detach(NULL, NULL);\n    BlastAqwGifsBothFrames(aqwProgress);\n}\n#endif\n"
  },
  {
    "path": "src/P2/proxy.c",
    "content": "#include <proxy.h>\n#include <sw.h>\n\nvoid InitProxy(PROXY *pproxy)\n{\n    InitAlo(pproxy);\n    AppendDlEntry(&pproxy->psw->dlProxy, pproxy);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/proxy\", LoadProxyFromBrx__FP5PROXYP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/proxy\", CloneProxy__FP5PROXYT0);\n\nvoid PostProxyLoad(PROXY *pproxy)\n{\n    PostAloLoad(pproxy);\n    pproxy->pvtlo->pfnRemoveLo(pproxy);\n}\n"
  },
  {
    "path": "src/P2/puffer.c",
    "content": "#include <puffer.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", InitPuffer__FP6PUFFER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", LoadPufferFromBrx__FP6PUFFERP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", PostPufferLoad__FP6PUFFER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", PresetPufferAccel__FP6PUFFERf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FFilterPuffer__FP6PUFFERP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", UpdatePuffer__FP6PUFFERf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", PpufftChoosePuffer__FP6PUFFER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FUN_001973d8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FUN_00197458);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", OnPufferActive__FP6PUFFERiP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", UpdatePufferActive__FP6PUFFERP3JOYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FUN_00197788);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FUN_00197848);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FUN_00197a08);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FUN_00197a68);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", AddPufferWaterAcceleration__FP6PUFFERP5WATERf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", HandlePufferMessage__FP6PUFFER5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", PostPuffcLoad__FP5PUFFC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", PresetPuffcAccel__FP5PUFFCf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FUN_001982a0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", UpdatePuffcGoal__FP5PUFFCi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", OnPuffcExitingSgs__FP5PUFFC3SGS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", OnPuffcEnteringSgs__FP5PUFFC3SGSP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", UpdatePuffcSgs__FP5PUFFC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", HandlePuffcMessage__FP5PUFFC5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", UpdatePuffc__FP5PUFFCf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FCanPuffcAttack__FP5PUFFC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", FUN_00198860);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/puffer\", PostPuffbLoad__FP5PUFFB);\n"
  },
  {
    "path": "src/P2/pzo.c",
    "content": "#include <pzo.h>\n#include <find.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", InitSprize__FP6SPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", LoadSprizeFromBrx__FP6SPRIZEP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", BindSprize__FP6SPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", PostSprizeLoad__FP6SPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", UpdateSprize__FP6SPRIZEf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", CollectSprize__FP6SPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", EmitSprizeExplosion__FP6SPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", PcsFromSprize__FP6SPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", AddSprizeAseg__FP6SPRIZE3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", HandleSprizeMessage__FP6SPRIZE5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", FIgnoreSprizeIntersection__FP6SPRIZEP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", FUN_00199000);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", InitScprize__FP7SCPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", CloneScprize__FP7SCPRIZET0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", PcsFromScprize__FP7SCPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", CollectScprize__FP7SCPRIZE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", LoadLockFromBrx__FP4LOCKP18CBinaryInputStream);\n#ifdef SKIP_ASM\n/**\n * @todo 95.80% matched. s_asnip may not be defined correctly.\n */\nvoid LoadLockFromBrx(LOCK *plock, CBinaryInputStream *pbis)\n{\n    static SNIP *s_asnip;\n    LoadAloFromBrx(plock, pbis);\n    SnipAloObjects(plock, 1, s_asnip);\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", PostLockLoad__FP4LOCK);\n#ifdef SKIP_ASM\n/**\n * @todo 95.00% matched. s_asnip may not be defined correctly.\n */\nvoid PostLockLoad(LOCK *plock)\n{\n    static SNIP *s_asnip;\n    PostAloLoad(plock);\n    SnipAloObjects(plock, 1, s_asnip);\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", LoadLockgFromBrx__FP5LOCKGP18CBinaryInputStream);\n#ifdef SKIP_ASM\n/**\n * @todo 95.00% matched. s_asnip may not be defined correctly.\n */\nvoid LoadLockgFromBrx(LOCKG *plockg, CBinaryInputStream *pbis)\n{\n    LoadAloFromBrx(plockg, pbis);\n    // SnipAloObjects(plockg, 1, PostLockgLoad);\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", PostLockgLoad__FP5LOCKG);\n#ifdef SKIP_ASM\n/**\n * @todo 63.40% matched.\n */\nvoid PostLockgLoad(LOCKG *plockg)\n{\n    PostAloLoad(plockg);\n\n    int count;\n    SW *psw = plockg->psw;\n    LO **aplo = STRUCT_OFFSET(plockg, 0x304, LO **);\n    count = CploFindSwObjectsByClass(psw, 1, (CID)0x5C, (LO *)plockg, 8, aplo);\n    STRUCT_OFFSET(plockg, 0x300, uint) = count;\n\n    count = STRUCT_OFFSET(plockg, 0x2DC, uint);\n    if (count > 0) {\n        LO **aploIn = STRUCT_OFFSET(plockg, 0x2E0, LO **);\n        LO **aploOut = STRUCT_OFFSET(plockg, 0x304, LO **);\n        for (int i = 0; i < count; i++) {\n            LO *plo = PloFindSwObject(psw, 4, STRUCT_OFFSET(aploIn, i * 4, OID), (LO *)plockg);\n            if (plo) {\n                uint curCount = STRUCT_OFFSET(plockg, 0x300, uint);\n                if (curCount < 8) {\n                    aploOut[curCount] = plo;\n                    curCount++;\n                    STRUCT_OFFSET(plockg, 0x300, uint) = curCount;\n                }\n            }\n        }\n    }\n\n    int mask = STRUCT_OFFSET(plockg, 0x2D0, int);\n    int goalStart = 0x22E;\n    int goalEnd = 0x22F;\n    if ((STRUCT_OFFSET(g_pwsCur, 0x448, int) & mask))\n        goalStart = goalEnd;\n\n    SMA *psma;\n    count = STRUCT_OFFSET(plockg, 0x300, uint);\n    if (count > 0) {\n        ALO **aploState = STRUCT_OFFSET(plockg, 0x304, ALO **);\n        for (int i = 0; i < count; i++) {\n            ALO *paloChild = aploState[i];\n            psma = PsmaApplySm(STRUCT_OFFSET(paloChild, 0x2D0, SM *), paloChild, (OID)-1, 0);\n            STRUCT_OFFSET(paloChild, 0x2D4, SMA *) = psma;\n            SetSmaGoal(psma, (OID)goalStart);\n        }\n    }\n\n    psma = PsmaApplySm(STRUCT_OFFSET(plockg, 0x2D4, SM *), (ALO *)plockg, OID_Nil, 0);\n    STRUCT_OFFSET(plockg, 0x2D8, SMA *) = psma;\n    SetSmaGoal(psma, (OID)goalStart);\n}\n#endif\n\nvoid SetLockgIndex(LOCKG *plockg, int ifws)\n{\n    STRUCT_OFFSET(plockg, 0x2D0, int) = 1 << ++ifws;\n}\n\n/**\n * @note Will stop matching if ALO or LOCKG fields are changed.\n */\nvoid AddLockgLock(LOCKG *plockg, OID oidLock)\n{\n    uint ccur = plockg->coidLock;\n    if (ccur >= 8)\n        return;\n\n    plockg->aoidLock[ccur] = oidLock;\n    plockg->coidLock = ++ccur;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", TriggerLockg__FP5LOCKG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", InitClue__FP4CLUE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", LoadClueFromBrx__FP4CLUEP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", CloneClue__FP4CLUET0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", PostClueLoad__FP4CLUE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", UpdateClue);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", OnClueSmack__FP4CLUE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", CollectClue__FP4CLUE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", BreakClue__FP4CLUE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", CollectClueSilent__FP4CLUE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", FUN_00199c10);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", ImpactClue__FP4CLUEi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", FAbsorbClueWkr__FP4CLUEP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", RenderClueAll__FP4CLUEP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", CollectAllClues__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", SetGrfvault__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", FUN_0019a000);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", FUN_0019a088);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", FUN_0019a0f0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", InitVault__FP5VAULT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", PostTmblLoad__FP4TMBL3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", PostVaultLoad__FP5VAULT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", OnVaultActive__FP5VAULTiP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", UpdateVaultActive__FP5VAULTP3JOYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", HandleVaultMessage__FP5VAULT5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", AddVaultGoadDialog__FP5VAULT5GOADK3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/pzo\", OpenVault__FP5VAULT);\n"
  },
  {
    "path": "src/P2/rail.c",
    "content": "#include <rail.h>\n#include <find.h>\n#include <sw.h>\n\nextern float D_0024C8C4;\n\nvoid InitRail(RAIL *prail)\n{\n    InitLo(prail);\n    prail->unk1 = D_0024C8C4;\n    prail->oid = OID_Nil;\n}\n\nvoid OnRailAdd(RAIL *prail)\n{\n    OnLoAdd(prail);\n    AppendDlEntry(&prail->psw->dlRail, prail);\n}\n\nvoid OnRailRemove(RAIL *prail)\n{\n    OnLoRemove(prail);\n    RemoveDlEntry(&prail->psw->dlRail, prail);\n}\n\nvoid PostLoadRail(RAIL *prail)\n{\n    PostLoLoad(prail);\n    if (prail->oid != OID_Nil)\n    {\n        // TODO: Check if the field at 0x58 is LO or something that inherits from it.\n        prail->plo = PloFindSwObject(prail->psw, 4, prail->oid, prail);\n    }\n}\n\nvoid CloneRail(RAIL *prail, RAIL *prailBase)\n{\n    DLE dleRail = prail->dleRail;\n    CloneLo(prail, prailBase);\n    prail->dleRail = dleRail;\n}\n"
  },
  {
    "path": "src/P2/rat.c",
    "content": "#include <rat.h>\n#include <util.h>\n#include <sw.h>\n\nvoid InitRat(RAT *prat)\n{\n    InitSo(prat);\n    STRUCT_OFFSET(prat, 0x608, LM).gMin = 0.5f; // prat->lmDtStop.gMin\n    STRUCT_OFFSET(prat, 0x608, LM).gMax = 1.0f; // prat->lmDtStop.gMax\n    STRUCT_OFFSET(prat, 0x55c, float) = GRandGaussian(g_clock.t + 3.0f, 1.0f, 2.5f); // prat->tRatSqueak\n    STRUCT_OFFSET(prat, 0x664, int) = -1; // prat->ccoin\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", LoadRatFromBrx__FP3RATP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", PostRatLoad__FP3RAT);\n\nvoid OnRatAdd(RAT *prat)\n{\n    OnSoAdd(prat);\n    AppendDlEntry(&prat->psw->dlRat, prat);\n}\n\nvoid OnRatRemove(RAT *prat)\n{\n    OnSoRemove(prat);\n    RemoveDlEntry(&prat->psw->dlRat, prat);\n}\n\nvoid CloneRat(RAT *prat, RAT *pratBase)\n{\n    DLE dleRat = STRUCT_OFFSET(prat, 0x600, DLE); // prat->dleRat\n    CloneSo(prat, pratBase);\n    STRUCT_OFFSET(prat, 0x600, DLE) = dleRat; // prat->dleRat\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", PresetRatAccel__FP3RATf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", UpdateRat__FP3RATf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", AdjustRatNewXp__FP3RATP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", AdjustRatXpVelocity__FP3RATP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", RenderRatAll__FP3RATP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", FAbsorbRatWkr__FP3RATP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", ChooseRatFleeTarget__FP3RAT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", HideRat__FP3RATi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rat\", SetRatRats__FP3RAT4RATS);\n\nvoid OnRatholeAdd(RATHOLE *prathole)\n{\n    OnLoAdd(prathole);\n    AppendDlEntry(&prathole->psw->dlRathole, prathole);\n}\n\nvoid OnRatholeRemove(RATHOLE *prathole)\n{\n    OnLoRemove(prathole);\n    RemoveDlEntry(&prathole->psw->dlRathole, prathole);\n}\n"
  },
  {
    "path": "src/P2/rchm.c",
    "content": "#include <rchm.h>\n\nvoid InitRchm(RCHM *prchm)\n{\n    InitLo(prchm);\n    prchm->oidTouch = OID_Nil;\n    prchm->oidHost = OID_Nil;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", LoadRchmFromBrx__FP4RCHMP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", PostRchmLoad__FP4RCHM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", ReblendRchm__FP4RCHMP3TWRP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", BuildRchmCoefficients__FP4RCHMfffPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", ConvertRchmIposToRclIoLhub__FP4RCHMiPfN22);\n\nvoid SetRchmNaturalCoefficients(RCHM *prchm, float rcl, float io, float lhub)\n{\n    prchm->rclNatural = rcl;\n    prchm->ioNatural = io;\n    prchm->lhubNatural = lhub;\n}\n\nvoid SetRchmCenterCoefficients(RCHM *prchm, float rcl, float io, float lhub)\n{\n    prchm->fCenterSet = 1;\n    prchm->rclNatural = rcl;\n    prchm->ioNatural = io;\n    prchm->lhubNatural = lhub;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", PredictRchmTargetPos__FP4RCHMP6TARGETfP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", PredictRchmTargetLocalPos__FP4RCHMP6TARGETfP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", PtwrMapRchmSafe__FP4RCHMP3BSPP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", FindRchmClosestPoint__FP4RCHMP6VECTORT1PP3TWRPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", TrackJtTarget__FP2JTP4RCHMP6TARGET);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rchm\", TrackJtPipe__FP2JTP4RCHMP4PIPEPf);\n"
  },
  {
    "path": "src/P2/render.c",
    "content": "#include <render.h>\n\nextern int s_fFBCleared;\nextern int s_fZBCleared;\nextern int s_fCameraGlobals;\nextern int s_fRenderGlobals;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", SubmitRpl__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", NCmpPrplReverseZ__FPP3RPLT0);\n#ifdef SKIP_ASM\n/**\n * @todo 100% match, if the struct is exactly 8 bytes long.\n * Once the struct is fully implemented this code needs to be changed to account for that.\n * https://decomp.me/scratch/4xKRS\n */\nint NCmpPrplReverseZ(RPL **pprpl1, RPL **pprpl2)\n{\n    RPL *plhs = *pprpl1;\n    RPL *prhs = *pprpl2;\n\n    if (prhs->z < plhs->z)\n    {\n        return -1;\n    }\n    if (plhs->z < prhs->z)\n    {\n        return 1;\n    }\n\n    return (plhs - prhs) >> 0x04;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", CprplPartitionArpl__FiP3RPLPP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", RenderSw__FP2SWP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", EnsureRenderGlobals__Fv);\n\nvoid EnsureCameraGlobals()\n{\n    if (s_fCameraGlobals == 0)\n    {\n        s_fCameraGlobals = 1;\n        DrawCm(g_pcm);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", EnsureScreenCleared__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", SetupRpDynamicTexture__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", SetupRpBackground__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", SetupRpBlotContext__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", SetupRpGlob__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", SetupRpBlip__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", SetupRpWorldMap__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", DrawSw__FP2SWP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", FillScreenRect__FiiiiffffP4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/render\", StartupRender__Fv);\n"
  },
  {
    "path": "src/P2/rip.c",
    "content": "#include <rip.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", PripgNew__FP2SW5RIPGT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitRipg__FP4RIPG);\n\nvoid SetRipgEmitb(RIPG *pripg, EMITB *pemitb)\n{\n    // pripg->sExpand & pemib->emitp.emitrip.sExpand\n    STRUCT_OFFSET(pripg, 0x554, float) = STRUCT_OFFSET(pemitb, 0x1e8, float);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", OnRipgRemove__FP4RIPG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ProjectRipgTransform__FP4RIPGfi);\n\nvoid UpdateRipgBounds(RIPG *pripg)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", FUN_0019e420);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", BounceRipgRips__FP4RIPG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderRipgSelf__FP4RIPGP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", PvtripFromRipt__F4RIPT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", PripNewRipg__F4RIPTP4RIPG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitRip__FP3RIPP6VECTORfP2SO);\n\nvoid RemoveRip(RIP *prip)\n{\n\tRemoveDlEntry(&STRUCT_OFFSET(prip->pripg, 0x558, DL), prip);\n    ReleaseRip(prip);\n}\n\nvoid AddRipRef(RIP *prip)\n{\n    prip->cref++;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ReleaseRip__FP3RIP);\n\nvoid TouchRip(RIP *prip, int fTouching)\n{\n    if (fTouching)\n    {\n        RemoveRip(prip);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ForceRipFade__FP3RIPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", FBounceRip__FP3RIPP2SOP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ProjectRipTransform__FP3RIPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UpdateRip__FP3RIPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", FRenderRipPosMat__FP3RIPP2CMP6VECTORP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderRip__FP3RIPP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", SubscribeRipObject__FP3RIPP2LO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", SubscribeRipStruct__FP3RIPPFPv5MSGIDPv_vPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UnsubscribeRipStruct__FP3RIPPFPv5MSGIDPv_vPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitDroplet__FP7DROPLETP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", TouchDroplet__FP7DROPLETi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitBublet__FP6BUBLETP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ProjectBubletTransform__FP6BUBLETf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", TouchBublet__FP6BUBLETi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitRipple__FP6RIPPLEP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitPuff__FP4PUFFP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitDablet__FP6DABLETP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitFlake__FP5FLAKEP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UpdateFlake__FP5FLAKEf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderFlake__FP5FLAKEP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", TouchFlake__FP5FLAKEi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitSpark__FP5SPARKP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderSpark__FP5SPARKP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitBurst__FP5BURSTP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitTrail__FP5TRAILP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", OnTrailRemove__FP5TRAIL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", SetTrailTrls__FP5TRAIL4TRLSPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", DetachTrail__FP5TRAIL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ProjectTrailTransform__FP5TRAILf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderTrail__FP5TRAILP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", HandleTrailMessage__FP5TRAIL5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitFireball__FP8FIREBALLP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UpdateFireball__FP8FIREBALLf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitSmokecloud__FP10SMOKECLOUDP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitSmoketrail__FP10SMOKETRAILP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitDebris__FP6DEBRISP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitSmack__FP5SMACKP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ProjectSmackTransform__FP5SMACKf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderSmack__FP5SMACKP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UpdateSmack__FP5SMACKf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitOrbit__FP5ORBITP6VECTORfP2SO);\n\nJUNK_ADDIU(80);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ProjectOrbitTransform__FP5ORBITf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UpdateOrbit__FP5ORBITf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderOrbit__FP5ORBITP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitRay__FP3RAYP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitRose__FP4ROSEP6VECTORfP2SO);\n\nvoid ProjectRoseTransform(ROSE *prose, float dt)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UpdateRose__FP4ROSEf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderRose__FP4ROSEP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", SetRoseRoses__FP4ROSE5ROSES);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", SgnCmpHp__FPCvT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ChpBuildConvexHullScreen__FP6VECTORiP2HP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ChpBuildConvexHullXY__FP7MATRIX4iP2HP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", PostFlyingEmit__FP6FLYINGP5EMITB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderFlying__FP6FLYINGP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", CreateStuck__FP3RIPP3ALOP2SOP6VECTORT3PP5STUCK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", FBounceFlying__FP6FLYINGP2SOP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UpdateStuck__FP5STUCKf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderStuck__FP5STUCKP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", PostLeafEmit__FP4LEAFP5EMITB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ProjectLeafTransform__FP4LEAFf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", FBounceLeaf__FP4LEAFP2SOP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", FFilterFlameObjects__FPvP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", PostFlameEmit__FP5FLAMEP5EMITB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", PostBulletEmit__FP6BULLETP5EMITB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderBullet__FP6BULLETP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", FBounceBullet__FP6BULLETP2SOP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", PostShrapnelEmit__FP8SHRAPNELP5EMITB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", FBounceShrapnel__FP8SHRAPNELP2SOP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderShrapnel__FP8SHRAPNELP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitGlint__FP5GLINTP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderGlint__FP5GLINTP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", InitMatch__FP5MATCHP6VECTORfP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", LaunchMatch__FP5MATCH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", ProjectMatchTransform__FP5MATCHf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UpdateMatch__FP5MATCHf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", RenderMatch__FP5MATCHP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", PostRemitEmit__FP5REMITP5EMITB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rip\", UpdateRemit__FP5REMITf);\n\nJUNK_ADDIU(10);\nJUNK_WORD(0x7C450000);\nJUNK_WORD(0x48220800);\n"
  },
  {
    "path": "src/P2/rog.c",
    "content": "#include <rog.h>\n#include <cm.h>\n\nextern SNIP s_asnipLoadRov[2];\n\nvoid InitRov(ROV *prov)\n{\n    InitPo(prov);\n    STRUCT_OFFSET(prov, 0x628, float) = 2000.0f; // prov->svMax\n    STRUCT_OFFSET(prov, 0x610, ROVS) = ROVS_Nil; // prov->rovs\n    STRUCT_OFFSET(prov, 0x614, ROVTS) = ROVTS_Nil; // prov->rovts\n}\n\nvoid LoadRovFromBrx(ROV *prov, CBinaryInputStream *pbis)\n{\n    LoadSoFromBrx(prov, pbis);\n    SnipAloObjects(prov, 2, s_asnipLoadRov);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", PostRovLoad__FP3ROV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", UpdateRovActive__FP3ROVP3JOYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", UpdateRov__FP3ROVf);\n\nvoid ReadRovJoystick(ROV *prov, JOY *pjoy)\n{\n    if (pjoy->uDeflect > 0.3f)\n    {\n        // prov->radJoyLeft\n        AdjustCmJoy(g_pcm, pjoy, JOYID_Left, &STRUCT_OFFSET(prov, 0x618, float));\n    }\n    STRUCT_OFFSET(prov, 0x61c, float) = pjoy->uDeflect;\n\n    if (pjoy->uDeflect2 > 0.8f)\n    {\n        // prov->radJoyRight\n        AdjustCmJoy(g_pcm, pjoy, JOYID_Right, &STRUCT_OFFSET(prov, 0x620, float));\n    }\n    STRUCT_OFFSET(prov, 0x624, float) = pjoy->uDeflect2;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", RovsNextRov__FP3ROV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", SetRovRovs__FP3ROV4ROVS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", RovtsNextRov__FP3ROV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", SetRovRovts__FP3ROV5ROVTS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", HandleRovMessage__FP3ROV5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", PresetRovAccel__FP3ROVf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", AdjustRovXpVelocity__FP3ROVP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", AdjustRovNewXp__FP3ROVP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", PropagateRovForce__FP3ROViP2XPiP2DZP2FX);\n\nint FIsRovSoundBase(ROV *prov)\n{\n    return 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", InitRob__FP3ROB);\n\nvoid SetRobCollectible(ROB *prob, OID oidCollectible)\n{\n    STRUCT_OFFSET(prob, 0x2d0, OID) = oidCollectible;\n}\n\nvoid SetRobHarvester(ROB *prob, OID oidHarvester)\n{\n    STRUCT_OFFSET(prob, 0x2d4, OID) = oidHarvester;\n}\n\nvoid SetRobVehicle(ROB *prob, OID oidVehicle)\n{\n    STRUCT_OFFSET(prob, 0x2d8, OID) = oidVehicle;\n}\n\nvoid SetRobPrize(ROB *prob, OID oidPrize)\n{\n    STRUCT_OFFSET(prob, 0x2dc, OID) = oidPrize;\n}\n\nvoid AddRobSpawnTunnel(ROB *prob, OID oidSpawnTunnel)\n{\n    int coidRost = STRUCT_OFFSET(prob, 0x2e0, int); // prob->coidRost\n    OID *aoidRost = &STRUCT_OFFSET(prob, 0x2e4, OID); // prob->aoidRost\n    aoidRost[coidRost] = oidSpawnTunnel;\n    STRUCT_OFFSET(prob, 0x2e0, int) = coidRost + 1; // prob->coidRost\n}\n\n/**\n * @brief 80% match.\n * https://decomp.me/scratch/s3oRy\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", RobkCur__Fv);\n#ifdef SKIP_ASM\nROBK RobkCur()\n{\n    if ((uint)g_plsCur->fls & FLS_Secondary)\n    {\n        return ROBK_Tertiary;\n    }\n\n    return (ROBK)((uint)g_plsCur->fls & FLS_KeyCollected);\n}\n#endif // SKIP_ASM\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", BindRob__FP3ROB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", PostRobLoad__FP3ROB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", UpdateRob__FP3ROBf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", FUN_001a4d60);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", RobsNextRob__FP3ROB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", SetRobRobs__FP3ROB4ROBS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", AddRobRoc__FP3ROB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", AddRobRoh__FP3ROB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", AdjustRobDifficulty__FP3ROBf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", DestroyedRobRoc__FP3ROBP3ROC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", SpawnedRobRoh__FP3ROBP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", GrabbedRobRoh__FP3ROBP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", DroppedRobRoh__FP3ROBP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", ReturnedRobRoh__FP3ROBP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", ExitedRobRoh__FP3ROBP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", KilledRobRoh__FP3ROBP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", FChooseRobRoc__FP3ROBP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", TakeRobRoc__FP3ROBP3ROHP3ROC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", FChooseRobRoh__FP3ROBP3ROC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", FChooseRobReturnPoint__FP3ROBP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", ChooseRobWanderLocation__FP3ROBP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", ProddCurRob__FP3ROB4ENSK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", InitRoh__FP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", LoadRohFromBrx__FP3ROHP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", CloneRoh__FP3ROHT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", PostRohLoad__FP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", UpdateRoh__FP3ROHf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", MoveRohToTarget__FP3ROHP6VECTORi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", RohsNextRoh__FP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", SetRohRohs__FP3ROH4ROHS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", FAbsorbRohWkr__FP3ROHP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", ProcContactRoh__FP3ROH);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", InitRoc__FP3ROC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", LoadRocFromBrx__FP3ROCP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", CloneRoc__FP3ROCT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", PostRocLoad__FP3ROC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", UpdateRoc__FP3ROCf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", PresetRocAccel__FP3ROCf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", AdjustRocNewXp__FP3ROCP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", FAbsorbRocWkr__FP3ROCP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", RocsNextRoc__FP3ROC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", SetRocRocs__FP3ROC4ROCS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", InitRost__FP4ROST);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", LoadRostFromBrx__FP4ROSTP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", CloneRost__FP4ROSTT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", PostRostLoad__FP4ROST);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", UpdateRost__FP4ROSTf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", RostsNextRost__FP4ROST);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", SetRostRosts__FP4ROST5ROSTS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", InitRop__FP3ROP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", LoadRopFromBrx__FP3ROPP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", PostRopLoad__FP3ROP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", UpdateRop__FP3ROPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", SetRopRops__FP3ROP4ROPS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rog\", RopsNextRop__FP3ROP);\n"
  },
  {
    "path": "src/P2/rumble.c",
    "content": "#include <rumble.h>\n#include <clock.h>\n#include <sdk/ee/libpad.h>\n\n/**\n * @brief Rename.\n */\nextern int DAT_0026c3dc;\n\nvoid InitRumble(RUMBLE *prumble, int nPort, int nSlot)\n{\n    if (prumble->rums == RUMS_Dead)\n    {\n        SetRumbleRums(prumble, RUMS_Idle);\n    }\n    else\n    {\n        SetRumbleRums(prumble, RUMS_Stop);\n    }\n\n    prumble->nPort = nPort;\n    prumble->nSlot = nSlot;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rumble\", UpdateRumble__FP6RUMBLE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rumble\", TriggerRumbleRumk__FP6RUMBLE4RUMKf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rumble\", TriggerRumbleRumpat__FP6RUMBLEP6RUMPATf);\n\n/**\n * @brief 100% match. Rodata issue.\n * https://decomp.me/scratch/tFbRA\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/rumble\", SetRumbleRums__FP6RUMBLE4RUMS);\n#ifdef SKIP_ASM\nvoid SetRumbleRums(RUMBLE *prumble, RUMS rums)\n{\n    if (rums == prumble->rums)\n        return;\n\n    unsigned char abShockDirect[6];\n    switch(rums)\n    {\n        case RUMS_Dead:\n        case RUMS_Idle:\n        {\n            break;\n        }\n        case RUMS_Rumble:\n        {\n            abShockDirect[0] = prumble->prumpat->arumins[0].fHighSpeedMotor;\n            abShockDirect[1] = prumble->prumpat->arumins[0].bLowSpeedMotor;\n            scePadSetActDirect(prumble->nPort, prumble->nSlot, abShockDirect);\n            prumble->rums = rums;\n            break;\n        }\n        case RUMS_Stop:\n        case RUMS_Kill:\n        {\n            StopRumbleActuators(prumble);\n            prumble->dtRumins = g_clock.dtReal * 4.0f;\n        }\n        default:\n        {\n            prumble->rums = rums;\n            break;\n        }\n    }\n}\n#endif // SKIP_ASM\n\nvoid StopRumbleActuators(RUMBLE *prumble)\n{\n    unsigned char abShockDirect[6];\n    abShockDirect[0] = '\\0';\n    abShockDirect[1] = '\\0';\n    scePadSetActDirect(prumble->nPort, prumble->nSlot, abShockDirect);\n}\n\n/**\n * @todo Rename and figure out what does this do.\n */\nvoid FUN_001A7E70()\n{\n    if (DAT_0026c3dc == 0)\n    {\n        DAT_0026c3dc = 1;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rumble\", FUN_001A7E90);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rumble\", FUN_001A7EE8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rumble\", FUN_001A7F50);\n"
  },
  {
    "path": "src/P2/rwm.c",
    "content": "#include <rwm.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", InitRwm__FP3RWM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", OnRwmRemove);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", FUN_001a8110);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", FUN_001a8150);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", InitRwmCallback__FP3RWM5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", FUN_001a84c8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", PostRwmLoad__FP3RWM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", FUN_001a86f8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", PrwcFindRwm__FP3RWM3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", EnableRwmRwc__FP3RWM3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", DisableRwmRwc__FP3RWM3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", ResizeRwmRwc__FP3RWM3OIDi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", FIsRwmAmmo__FP3RWMP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", FAvailableRwmAmmo__FP3RWMP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", CycleRwmCache__FP3RWM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", ReloadRwm__FP3RWM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", FEnsureRwmLoaded__FP3RWM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", FFireRwm__FP3RWMi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", FUN_001a93c8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", ClearRwmFireInfo__FP3RWM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", ClearRwmTargetInfo__FP3RWM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", ClearRwmAimConstraints__FP3RWM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", GetRwfiPosMat__FP4RWFIP6VECTORP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", GetRwtiPos__FP4RWTIP6VECTORT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", GetRwacPan__FP4RWACPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/rwm\", GetRwacTilt__FP4RWACPf);\n"
  },
  {
    "path": "src/P2/sb.c",
    "content": "#include <sb.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sb\", PostSbgLoad__FP3SBG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sb\", FUN_001a9928__FP3SBG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sb\", UpdateSbgGoal__FP3SBGi);\n\nvoid UpdateSbgSgs(SBG *psbg)\n{\n    UpdateStepguardSgs(psbg);\n\n    // TODO: This might be an enum?\n    if (STRUCT_OFFSET(psbg, 0x724, int) == 0x10)\n    {\n        LookStepguardAtGoal(psbg);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sb\", OnSbgEnteringSgs__FP3SBG3SGSP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sb\", UpdateSbg__FP3SBGf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sb\", FUN_001a9a98);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sb\", FAbsorbSbgWkr__FP3SBGP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sb\", FUN_001a9c58);\n"
  },
  {
    "path": "src/P2/screen.c",
    "content": "#include <screen.h>\n#include <clock.h>\n#include <font.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", StartupScreen__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", PostBlotsLoad__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", UpdateBlots__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", ForceHideBlots__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", ResetBlots__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", RenderBlots__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawBlots__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", InitBlot__FP4BLOT5BLOTK);\n\nvoid PostBlotLoad(BLOT *pblot)\n{\n    pblot->pfont = g_pfont;\n    *(int*)&pblot->rgba = 0xff808080; // Union?\n    pblot->achzDraw[0] = 0;\n    pblot->rFontScale = 1.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", UpdateBlot__FP4BLOT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", SetBlotAchzDraw__FP4BLOTPc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", SetBlotRgba__FP4BLOTUi);\n\nvoid SetBlotFontScale(float rFontScale, BLOT *pblot)\n{\n    pblot->rFontScale = rFontScale;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawBlot__FP4BLOT);\n\nJUNK_ADDIU(10);\n\nfloat DtAppearBlot(BLOT *pblot)\n{\n    return pblot->dtAppear;\n}\n\nfloat DtVisibleBlot(BLOT *pblot)\n{\n    return pblot->dtVisible;\n}\n\nfloat DtDisappearBlot(BLOT *pblot)\n{\n    return pblot->dtDisappear;\n}\n\nvoid SetBlotDtAppear(BLOT *pblot, float dtAppear)\n{\n    pblot->dtAppear = dtAppear;\n}\n\nvoid SetBlotDtVisible(BLOT *pblot, float dtVisible)\n{\n    pblot->dtVisible = dtVisible;\n}\n\nvoid SetBlotDtDisappear(BLOT *pblot, float dtDisappear)\n{\n    pblot->dtDisappear = dtDisappear;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", OnBlotReset__FP4BLOT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", ShowBlot__FP4BLOT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", HideBlot__FP4BLOT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", SetBlotBlots__FP4BLOT5BLOTS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FIncludeBlotForPeg__FP4BLOTT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", ResizeBlot__FP4BLOTff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", RepositionBlot__FP4BLOT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", RepositionBlotDependents__FP4BLOT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", SetBlotClock__FP4BLOTPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", PostCtrLoad__FP3CTR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", UpdateCtr__FP3CTR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawCtr__FP3CTR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", RebuildCtrAchzDraw__FP3CTR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DtVisibleCtr__FP3CTR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ab600);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", UpdateTimer__FP5TIMER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawTimer__FP5TIMER);\n\nvoid SetTimer(TIMER *ptimer, float dt)\n{\n    float threshold = D_0024CD4C;\n    ptimer->pfntnThreshold = NULL;\n    ptimer->fThreshold = 0;\n    ptimer->dtExpire = 0.0;\n    ptimer->pfntnExpire = NULL;\n    ptimer->fStopped = 0;\n    *(int*)&ptimer->rgba = 0xff808080; // Union?\n    ptimer->svt = -1.0;\n    ptimer->nSecondsLast = -1;\n    ptimer->nTenthsLast = -1;\n    ptimer->dtThreshold = threshold;\n    ptimer->dt = dt;\n    SetTimerTimers(ptimer, TIMERS_Paused);\n    RebuildTimerAchzDraw(ptimer, 0.0);\n    ptimer->pvttimer->pfnShowBlot(ptimer);\n}\n\nvoid SetTimerSpeed(TIMER *ptimer, float svt)\n{\n    ptimer->svt = svt;\n}\n\n/**\n * @brief Sets the time until the timer expires, and callback function.\n */\nvoid SetTimerExpire(TIMER *ptimer, float dt, void *pfntn)\n{\n    STRUCT_OFFSET(ptimer, 0x288, float) = dt; // ptimer->dt = dt;\n    STRUCT_OFFSET(ptimer, 0x28c, void *) = pfntn; // ptimer->pfntnThreshold = pfntn;\n}\n\nvoid StartTimer(TIMER *ptimer)\n{\n    SetTimerTimers(ptimer, TIMERS_Running);\n}\n\nvoid StopTimer(TIMER *ptimer)\n{\n    ptimer->fStopped = 1;\n    SetTimerTimers(ptimer, TIMERS_Expired);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", RebuildTimerAchzDraw__FP5TIMERf);\n\nvoid SetTimerTimers(TIMER *ptimer, TIMERS timers)\n{\n    if (ptimer->timers != timers)\n    {\n        ptimer->timers = timers;\n        ptimer->tTimers = g_clock.t;\n    }\n}\n\nfloat DtVisibleTrunkctr(TRUNKCTR *ptrunkctr)\n{\n    return 0.0f;\n}\n\nfloat DtVisibleCrusherctr(CRUSHERCTR *pcrusherctr)\n{\n    return 0.0f;\n}\n\n/**\n * @todo Rename function.\n */\nfloat FUN_001ABE60()\n{\n    return 0.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001abe70);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ac060);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ac0e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", PostNoteLoad__FP4NOTE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", SetNoteAchzDraw__FP4NOTEPc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawNote__FP4NOTE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ac888);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ac910);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ac990);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ac9e0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001aca30);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001aca68);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawTitle__FP5TITLE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", PostTotalsLoad__FP6TOTALS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ace38);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001acee0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", render_level_info_from_id);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", render_level_info);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", render_hideout_world_info);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", SetTotalsBlots__FP6TOTALS5BLOTS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", ShowTotalsQMARK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", HideTotalsQMARK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawTotals__FP6TOTALS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ad6a8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ad718);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ad7b0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ad940);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ad970);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawLetterbox__FP9LETTERBOX);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001adc60);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawLogo__FP4LOGO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001adf28);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001adff0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ae130);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", UpdateAttract__FP7ATTRACT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawAttract__FP7ATTRACT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", DrawLineScreen__FUiUiUiUiUiUiG4RGBAi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ae510);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ae5e0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ae758);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ae7f8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001ae820);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001aea08);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001aea70);\n\nJUNK_WORD(0xE48C0000);\nJUNK_WORD(0xE48C0008);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/screen\", FUN_001aec90);\n"
  },
  {
    "path": "src/P2/sensor.c",
    "content": "#include <sensor.h>\n#include <so.h>\n#include <lo.h>\n#include <alarm.h>\n#include <game.h>\n\nvoid InitSensor(SENSOR *psensor)\n{\n\tInitSo(psensor);\n\tSTRUCT_OFFSET(psensor, 0x558, SENSORS) = SENSORS_Nil;\n\tSTRUCT_OFFSET(psensor, 0x554, int) = 0;\n}\n\nvoid SetSensorAlarm(SENSOR *psensor, ALARM *palarm)\n{\n\tSTRUCT_OFFSET(psensor, 0x550, ALARM *) = palarm; // psensor->palarm = palarm;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", SetSensorSensors__FP6SENSOR7SENSORS);\n#ifdef SKIP_ASM\n/**\n * @todo 82.08% matched.\n */\nvoid SetSensorSensors(SENSOR *psensor, SENSORS sensors)\n{\n\tSENSORS sensorsCur = STRUCT_OFFSET(psensor, 0x558, SENSORS); // sensorsCur = psensor->sensors;\n\n\tif (sensorsCur == sensors)\n\t{\n\t\treturn;\n\t}\n\n\tif (sensorsCur == SENSORS_SenseEnabled && sensors == SENSORS_SenseTriggered)\n\t{\n\t\tALARM *palarm = STRUCT_OFFSET(psensor, 0x550, ALARM *);\n\t\tif (palarm)\n\t\t{\n\t\t\tTriggerAlarm(palarm, ALTK_Trigger);\n\t\t}\n\n\t\t// Recheck current sensor state: if it's not SENSORS_SenseEnabled,\n\t\t// override the current sensors with the new one.\n\t\tsensorsCur = STRUCT_OFFSET(psensor, 0x558, SENSORS);\n\t\tif (sensorsCur != SENSORS_SenseEnabled)\n\t\t{\n\t\t\tsensors = sensorsCur;\n\t\t}\n\t}\n\n\tHandleLoSpliceEvent(psensor, 2, 0, NULL);\n\tSTRUCT_OFFSET(psensor, 0x558, SENSORS) = sensors; // psensor->sensors = sensors;\n\tSTRUCT_OFFSET(psensor, 0x55C, float) = g_clock.t;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", FCheckSensorObject__FP6SENSORP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", FIgnoreSensorObject__FP6SENSORP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", FOnlySensorTriggerObject__FP6SENSORP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", PauseSensor__FP6SENSOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", UpdateSensor__FP6SENSORf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", AddSensorTriggerObject__FP6SENSOR3OID);\n #ifdef SKIP_ASM\n/**\n * @todo 100% matched but sensor struct offsets are wrong.\n */\nvoid AddSensorTriggerObject(SENSOR *psensor, OID oid)\n{\n\tuint ccur = psensor->ctriggerObjects;\n\tif (ccur >= 4)\n\t\treturn;\n\n\tpsensor->atriggerObjects[ccur] = oid;\n\tpsensor->ctriggerObjects = ccur + 1;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", AddSensorNoTriggerObject__FP6SENSOR3OID);\n #ifdef SKIP_ASM\n/**\n * @todo 100% matched but sensor struct offsets are wrong.\n */\nvoid AddSensorNoTriggerObject(SENSOR *psensor, OID oid)\n{\n\tuint ccur = psensor->cnoTriggerObjects;\n\tif (ccur >= 4)\n\t\treturn;\n\n\tpsensor->anoTriggerObjects[ccur] = oid;\n\tpsensor->cnoTriggerObjects = ccur + 1;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", AddSensorTriggerClass__FP6SENSOR3CID);\n #ifdef SKIP_ASM\n/**\n * @todo 100% matched but sensor struct offsets are wrong.\n */\nvoid AddSensorTriggerClass(SENSOR *psensor, CID cid)\n{\n\tuint ccur = psensor->ctriggerClasses;\n\tif (ccur >= 4)\n\t\treturn;\n\n\tpsensor->atriggerClasses[ccur] = cid;\n\tpsensor->ctriggerClasses = ccur + 1;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", AddSensorNoTriggerClass__FP6SENSOR3CID);\n #ifdef SKIP_ASM\n/**\n * @todo 100% matched but sensor struct offsets are wrong.\n */\nvoid AddSensorNoTriggerClass(SENSOR *psensor, CID cid)\n{\n\tuint ccur = psensor->cnoTriggerClasses;\n\tif (ccur >= 4)\n\t\treturn;\n\n\tpsensor->anoTriggerClasses[ccur] = cid;\n\tpsensor->cnoTriggerClasses = ccur + 1;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", InitLasen__FP5LASEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", LoadLasenFromBrx__FP5LASENP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", BindLasen__FP5LASEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", PostLasenLoad__FP5LASEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", UpdateBusyLasenSenseTimes__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", UpdateLasen__FP5LASENf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", FreezeLasen__FP5LASENi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", RenderLasenSelf__FP5LASENP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", FUN_001afaf8__FP6SENSORP2SO);\n#ifdef SKIP_ASM\n/**\n * @todo 73.57% matched.\n */\nint FUN_001afaf8(SENSOR *psensor, SO *pso)\n{\n\textern void *g_pjt;\n\tunsigned long long mask;\n\tuint tmp2cc;\n\n\t/* Mask: (0x8000 << 28) in 64-bits */\n\tmask = ((ulong)0x8000) << 28;\n\tif (STRUCT_OFFSET(pso, 0x538, ulong) & mask)\n\t\treturn 0;\n\n\tif (STRUCT_OFFSET(pso, 0x50, uint) == STRUCT_OFFSET(psensor, 0x50, uint))\n\t\treturn 0;\n\n\tif (FIgnoreSensorObject(psensor, pso))\n\t\treturn 0;\n\n\tif (pso == g_pjt)\n\t{\n\t\tif (STRUCT_OFFSET(pso, 0x2220, uint) != 6)\n\t\t\treturn 0;\n\t\tif (STRUCT_OFFSET(pso, 0x239C, uint) != 3)\n\t\t\treturn 0;\n\t\tif (GetGrfvault_unknown() & 0x12000)\n\t\t\treturn 0;\n\t}\n\n\ttmp2cc = STRUCT_OFFSET(pso, 0x2CC, uint);\n\t/* Invert lowest bit and mask to 1 */\n\treturn (int)(((tmp2cc ^ 1u) & 1u));\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", SenseLasen__FP5LASENP7SENSORS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", EnableLasen__FP5LASEN5SENSM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", DisableLasen__FP5LASEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", OnLasenAlarmTriggered__FP5LASEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", SetLasenSensors__FP5LASEN7SENSORS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", SCalcLasenShapeExtent__FP5LASENP5LBEAM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", RetractLasen__FP5LASENf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", ExtendLasen__FP5LASENf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", InitCamsen__FP6CAMSEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", PostCamsenLoad__FP6CAMSEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", UpdateCamsen__FP6CAMSENf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", RenderCamsenSelf__FP6CAMSENP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", FIgnoreCamsenIntersection__FP6CAMSENP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", FFilterCamsen__FPvP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", SenseCamsen__FP6CAMSENP7SENSORS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", EnableCamsen__FP6CAMSEN5SENSM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", DisableCamsen__FP6CAMSEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", OnCamsenAlarmTriggered__FP6CAMSEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", SetCamsenSensors__FP6CAMSEN7SENSORS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", SetCamsenCsdts__FP6CAMSEN5CSDTS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", InitPrsen__FP5PRSEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", PostPrsenLoad__FP5PRSEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", UpdatePrsen__FP5PRSENf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", SensePrsen__FP5PRSENP7SENSORS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", EnablePrsen__FP5PRSEN5SENSM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", DisablePrsen__FP5PRSEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", OnPrsenAlarmTriggered__FP5PRSEN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", SetPrsenSensors__FP5PRSEN7SENSORS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sensor\", UpdatePrsenLoopShader__FP5PRSEN);\n"
  },
  {
    "path": "src/P2/shadow.c",
    "content": "#include <shadow.h>\n#include <shd.h>\n#include <gcc/math.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", InitShadow__FP6SHADOW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", PostShadowLoad__FP6SHADOW);\n\nvoid InvalidateShadowVifs(SHADOW *pshadow)\n{\n    pshadow->cqwVifs = 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", RebuildShadowRegion__FP6SHADOW);\n\nvoid SetShadowShader(SHADOW *pshadow, OID oidShdShadow)\n{\n    OID oid = (oidShdShadow != OID_Nil) ? oidShdShadow : OID_shd_stock_shadow;\n    pshadow->pshd = PshdFindShader(oid);\n    if (pshadow->pshd)\n    {\n        InvalidateShadowVifs(pshadow);\n    }\n}\n\nint FShadowRadiusSet(SHADOW *pshadow)\n{\n    return (pshadow->sNearRadius >= 0.0f && pshadow->sFarRadius >= 0.0f);\n}\n\nvoid SetShadowNearRadius(SHADOW *pshadow, float sNearRadius)\n{\n    pshadow->sNearRadius = sNearRadius;\n    if (pshadow->sFarRadius < 0.0f)\n    {\n        pshadow->sFarRadius = sNearRadius;\n    }\n\n    InvalidateShadowVifs(pshadow);\n}\n\nvoid SetShadowFarRadius(SHADOW *pshadow, float sFarRadius)\n{\n    pshadow->sFarRadius = sFarRadius;\n    if (pshadow->sNearRadius < 0.0f)\n    {\n        pshadow->sNearRadius = sFarRadius;\n    }\n\n    InvalidateShadowVifs(pshadow);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", SetShadowCastPosition__FP6SHADOWP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", SetShadowCastNormal__FP6SHADOWP6VECTOR);\n\nvoid SetShadowNearCast(SHADOW *pshadow, float sNearCast)\n{\n    pshadow->sNearCast = sNearCast;\n    RebuildShadowRegion(pshadow);\n    InvalidateShadowVifs(pshadow);\n}\n\nvoid SetShadowFarCast(SHADOW *pshadow, float sFarCast)\n{\n    pshadow->sFarCast = sFarCast;\n    RebuildShadowRegion(pshadow);\n    InvalidateShadowVifs(pshadow);\n}\n\nvoid SetShadowConeAngle(SHADOW *pshadow, float degConeAngle)\n{\n    float fAngleTan = tanf(degConeAngle * 0.008726647f);\n    pshadow->sNearRadius = fAngleTan * pshadow->sNearCast;\n    pshadow->sFarRadius = fAngleTan * pshadow->sFarCast;\n    InvalidateShadowVifs(pshadow);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", SetShadowFrustrumUp__FP6SHADOWP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", FShadowValid__FP6SHADOWi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", FFilterFastShadows__FPvP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", UpdateShadow__FP6SHADOWf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", RebuildShadowVifs__FP6SHADOW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", DrawShadow__FP6SHADOW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", FShadowIntersectsSphere__FP6SHADOWP6VECTORf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shadow\", FindSwShadows__FP2SWP6VECTORfiPiPP6SHADOW);\n"
  },
  {
    "path": "src/P2/shape.c",
    "content": "#include <shape.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shape\", LoadShapeFromBrx__FP5SHAPEP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shape\", SetShapeParent__FP5SHAPEP3ALO);\n"
  },
  {
    "path": "src/P2/shd.c",
    "content": "#include <shd.h>\n#include <gs.h>\n\nextern GRFZON g_grfzonShaders;\nextern byte *g_pbBulkData;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", Tex0FromTexIframeCtk__FP3TEXi3CTK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", PackTexGifs__FP3TEXi3CTK4SHDKP4GIFS);\n\nvoid LoadClutFromBrx(CBinaryInputStream *pbis, CLUT *pclut)\n{\n    pbis->Read(0xc, pclut);\n    pclut->prgba = (RGBA *)(g_pbBulkData + (uint)pclut->prgba);\n    pclut->cqwColors = (uint)pclut->crgba * 4 + 0xf >> 4;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", LoadColorTablesFromBrx__FP18CBinaryInputStream);\n\nvoid LoadBmpFromBrx(CBinaryInputStream *pbis, BMP *pbmp)\n{\n    pbis->Read(0x14, pbmp);\n    pbmp->pbPixels = (byte *)(g_pbBulkData + (int)pbmp->pbPixels);\n    pbmp->cqwPixels = pbmp->cbPixels + 0xf >> 4;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", LoadBitmapsFromBrx__FP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", LoadFontsFromBrx__FP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", LoadTexFromBrx__FP18CBinaryInputStreamP3TEX);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", LoadShadersFromBrx__FP18CBinaryInputStream);\n\nvoid UploadPermShaders()\n{\n    GSB gsbPerm;\n    InitGsb(&gsbPerm, 0x1e00, 0x4000);\n    UploadBitmaps(0x10000000, &gsbPerm);\n    g_grfzonShaders = 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", PropagateShaders__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", FillShaders__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", UnloadShaders__Fv);\n\nJUNK_WORD(0xE4A00008);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", ConvertRgbToHsv__FP6VECTORT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", ConvertHsvToRgb__FP6VECTORT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", ConvertUserHsvToUserRgb__FP6VECTORT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", ConvertUserRgbToUserHsv__FP6VECTORT0);\n\nJUNK_ADDIU(10);\nJUNK_NOP();\nJUNK_NOP();\nJUNK_ADDIU(50);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", PshdFindShader__F3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", SetSaiIframe__FP3SAIi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", SetSaiDuDv__FP3SAIff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", PropagateSais__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shd\", UpdateShaders__Ff);\n"
  },
  {
    "path": "src/P2/shdanim.c",
    "content": "#include <shdanim.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", CbFromSaak__F4SAAK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", PvtsaaFromSaak__F4SAAK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", PsaaLoadFromBrx__FP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", InitSaa__FP3SAAP4SAAF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", PostSaaLoad__FP3SAA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", FUpdatableSaa__FP3SAA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UCompleteSaa__FP3SAA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", PsaiFromSaaShd__FP3SAAP3SHD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", InitLoop__FP4LOOPP4SAAF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", PostLoopLoad__FP4LOOP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UpdateLoop__FP4LOOPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UCompleteLoop__FP4LOOP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", InitPingpong__FP8PINGPONGP4SAAF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", PostPingpongLoad__FP8PINGPONG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UpdatePingpong__FP8PINGPONGf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UCompletePingpong__FP8PINGPONG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", InitShuffle__FP7SHUFFLEP4SAAF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UpdateShuffle__FP7SHUFFLEf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", InitHologram__FP8HOLOGRAMP4SAAF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", PostHologramLoad__FP8HOLOGRAM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", NotifyHologramRender__FP8HOLOGRAMP3ALOP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", InitScroller__FP8SCROLLERP4SAAF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UpdateScroller__FP8SCROLLERf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UCompleteScroller__FP8SCROLLER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", SetScrollerMasterSpeeds__FP8SCROLLERff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", InitCircler__FP7CIRCLERP4SAAF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UpdateCircler__FP7CIRCLERf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", UCompleteCircler__FP7CIRCLER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", InitLooker__FP6LOOKERP4SAAF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", SetLookerSgvr__FP6LOOKERP4SGVRP7GLOBSETP4GLOBP7SUBGLOB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", SetVecPosad__FP6VECTORP5POSAD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", SetUvPuvqd__FP3UVFP3UVQ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", NotifyLookerRender__FP6LOOKERP3ALOP3RPL);\n\nJUNK_ADDIU(60);\nJUNK_WORD(0x0003100B);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", FUN_001b5b58);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/shdanim\", FUN_001b5c40);\n"
  },
  {
    "path": "src/P2/sky.c",
    "content": "#include <sky.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sky\", PostSkyLoad__FP3SKY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sky\", UpdateSky__FP3SKYf);\n"
  },
  {
    "path": "src/P2/slotheap.c",
    "content": "#include <slotheap.h>\n#include <memory.h>\n#include <sce/memset.h>\n\nvoid _InitSlotheap(SLOTHEAP *pslotheap, int cb, int c)\n{\n    byte *pbBase = pslotheap->ab;\n    pslotheap->cb = cb;\n    pslotheap->pslotFree = (SLOT *)pbBase;\n\n    for (int i = 1; i < c; i++)\n    {\n        SLOT *pslotPrev = (SLOT *)pbBase;\n        pbBase = &pslotheap->ab[i * pslotheap->cb];\n        pslotPrev->pslotNext = (SLOT *)pbBase;\n    }\n\n    ((SLOT *)pbBase)->pslotNext = NULL;\n}\n\nvoid CreateSlotheapSw(SLOTHEAP *pslotheap, int cb, int c)\n{\n    cb = (cb + 7) & -8;\n    pslotheap->ab = (byte *)PvAllocSwImpl(cb * c);\n    _InitSlotheap(pslotheap, cb, c);\n}\n\nvoid CreateSlotheapSwAlign64(SLOTHEAP *pslotheap, int cb, int c)\n{\n    byte *pb = (byte *)PvAllocSwImpl(cb * c + 0x30);\n    pslotheap->ab = (byte *)(((int)pb + 0x3f) & -0x40);\n    _InitSlotheap(pslotheap, cb, c);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(40);\n\nvoid *PvAllocSlotheapUnsafe(SLOTHEAP *pslotheap)\n{\n    SLOT *pslotFree = pslotheap->pslotFree;\n    if (pslotFree)\n    {\n        pslotheap->pslotFree = pslotFree->pslotNext;\n    }\n\n    return pslotFree;\n}\n\nvoid *PvAllocSlotheapImpl(SLOTHEAP *pslotheap)\n{\n    return PvAllocSlotheapUnsafe(pslotheap);\n}\n\nvoid *PvAllocSlotheapClearImpl(SLOTHEAP *pslotheap)\n{\n    void *pv = PvAllocSlotheapUnsafe(pslotheap);\n    memset(pv, 0, pslotheap->cb);\n    return pv;\n}\n\nvoid FreeSlotheapPv(SLOTHEAP *pslotheap, void *pv)\n{\n    if (!pv)\n    {\n        return;\n    }\n\n    SLOT *pslot = (SLOT *)pv;\n    pslot->pslotNext = pslotheap->pslotFree;\n    pslotheap->pslotFree = pslot;\n}\n\nJUNK_NOP();\nJUNK_WORD(0x00E0102D);\n"
  },
  {
    "path": "src/P2/sm.c",
    "content": "#include <sm.h>\n#include <sw.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", LoadSmFromBrx__FP2SMP18CBinaryInputStream);\n\nvoid PostSmLoad(SM *psm)\n{\n    PostLoLoad(psm);\n    if (psm->fDefault)\n    {\n        PostSwCallback(psm->psw, PostSmLoadCallback, psm, MSGID_callback, NULL);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", PostSmLoadCallback__FP2SM5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", PsmaApplySm__FP2SMP3ALO3OIDi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", PsmaFindSm__FP2SMP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", IsmsFindSmOptional__FP2SM3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", IsmsFindSmRequired__FP2SM3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", OidFromSmIsms__FP2SMi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", RetractSma__FP3SMA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", SetSmaGoal__FP3SMA3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", GetSmaGoal__FP3SMAP3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", GetSmaCur__FP3SMAP3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", GetSmaNext__FP3SMAP3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", SetSmaSvt__FP3SMAf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", SeekSma__FP3SMA3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", ChooseSmaTransition__FP3SMA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", EndSmaTransition__FP3SMA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", HandleSmaMessage__FP3SMA5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", SkipSma__FP3SMAf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", SendSmaMessage__FP3SMA5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", FUN_001b6df8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sm\", NotifySmaSpliceOnEnterState__FP3SMAii);\n"
  },
  {
    "path": "src/P2/smartguard.c",
    "content": "#include <smartguard.h>\n#include <freeze.h>\n#include <sound.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", InitSmartguard__FP10SMARTGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", PostSmartguardLoadFlashlight__FP10SMARTGUARD);\n\nvoid UseSmartguardFlashlightTarget(SMARTGUARD *psmartguard, SGS sgs, OID oidTarget)\n{\n    FValidSgs(sgs);\n    SGFT *mpsgssgft = &STRUCT_OFFSET(psmartguard, 0xc38, SGFT); // psmartguard->mpsgssgft[sgs]\n    mpsgssgft[sgs].oidTarget = oidTarget;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", FUN_001B7100__FP10SMARTGUARDi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", PostSmartguardLoad__FP10SMARTGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", FFilterSmartguardDetect__FP10SMARTGUARDP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", FDetectSmartguard__FP10SMARTGUARD);\n\nvoid UpdateSmartguard(SMARTGUARD *psmartguard, float dt)\n{\n    UpdateStepguard(psmartguard, dt);\n    UpdateSmartguardFlashlight(psmartguard);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", UpdateSmartguardFlashlight__FP10SMARTGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", OnSmartguardEnteringSgs__FP10SMARTGUARD3SGSP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", FCanSmartguardAttack__FP10SMARTGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/smartguard\", SgasGetSmartguard__FP10SMARTGUARD);\n\nvoid HandleSmartguardMessage(SMARTGUARD *psmartguard, MSGID msgid, void *pv)\n{\n    HandleStepguardMessage(psmartguard, msgid, pv);\n\n    // psmartguard->pasegaSgs\n    if (msgid == MSGID_asega_wrapped && (ASEGA *)pv == STRUCT_OFFSET(psmartguard, 0x7e0, ASEGA *))\n    {\n        STRUCT_OFFSET(psmartguard, 0xcc4, int)++; // psmartguard->cidleSearch\n    }\n}\n\nvoid FreezeSmartguard(SMARTGUARD *psmartguard, int fFreeze)\n{\n    FreezeSo(psmartguard, fFreeze);\n\n    if (fFreeze)\n    {\n        // psmartguard->pexcSneak\n        UnsetExcitement(STRUCT_OFFSET(psmartguard, 0xcc0, EXC *));\n        STRUCT_OFFSET(psmartguard, 0xcc0, EXC *) = NULL;\n    }\n}\n"
  },
  {
    "path": "src/P2/so.c",
    "content": "#include <so.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", InitSo__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", OnSoAdd__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", OnSoRemove__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", EnableSoPhys__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", DisplaceSo__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", ImpactSo__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", PivotSo__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", ExtendSoBounds__FP2SOP6VECTORf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", UpdateSoBounds__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", UpdateGeomWorld__FP4GEOMT0G9VU_VECTORP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", UpdateSoXfWorldHierarchy__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", UpdateSoXfWorld__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FIgnoreSoIntersection__FP2SOT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", UpdateSoImpacts__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", UProjectVector__FP6VECTORN20);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", AdjustSoXpLocal__FP2SOP2XPi);\n\nJUNK_WORD(0xF8C10000);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", CalculateSoAngularEffectWorld__FP2SOP6VECTORT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", AccelSoTowardPosSpring__FP2SOP6VECTORP3CLQT1T2f);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", AccelSoTowardMatSpring__FP2SOP7MATRIX3P3CLQP6VECTORT2f);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", PresetSoAccel__FP2SOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", RenderSoSelf__FP2SOP2CMP2RO);\n\nvoid UpdateSo(SO *pso, float dt)\n{\n    UpdateAlo(pso, dt);\n}\n\nvoid SetSoMass(SO *pso, float mass)\n{\n    float oldMass = STRUCT_OFFSET(pso, 0x368, float); // pso->mass\n    float massRatio = mass / oldMass;\n\n    // Redundant multiplication needed for match ¯\\_(ツ)_/¯\n    float newMass = oldMass * massRatio;\n\n    STRUCT_OFFSET(pso, 0x368, float) = newMass; // Should be pso->mass = mass\n    // Technically newMass != mass due to floating point precision errors\n\n    AdjustSoMomint(pso, massRatio);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", AdjustSoMomint__FP2SOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", DiscardSoXps__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", UpdateSoPosWorldPrev__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", TranslateSoToPos__FP2SOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", RotateSoToMat__FP2SOP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", TranslateSoToPosSafe__FP2SOP6VECTORT1);\n\nJUNK_ADDIU(40);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoVelocityVec__FP2SOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoAngularVelocityVec__FP2SOP6VECTOR);\n\nJUNK_ADDIU(20);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", AddSoAcceleration__FP2SOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", AddSoAngularAcceleration__FP2SOP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoConstraints__FP2SO2CTP6VECTORT1T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoParent__FP2SOP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", ApplySoProxy__FP2SOP5PROXY);\n\nJUNK_WORD(0x27BD0150);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", AccelSoTowardMatSmooth__FP2SOfP7MATRIX3P3SMP);\n\nJUNK_WORD(0x27BD01C0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", GetSoCpdefi__FP2SOfP6CPDEFI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FIsSoTouching__FP2SOT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", PsoFirstSoTouching__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", CloneSo__FP2SOT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", ApplySoConstraintWorld__FP2SOP6CONSTRP6VECTORN22);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", ApplyConstr__FP6CONSTRP6VECTORN21);\n\nvoid ApplySoConstraintLocal(SO *pso, CONSTR *pconstr, VECTOR *pvecLocal, VECTOR *pvecConstr, VECTOR *pvecRemain)\n{\n    ApplyConstr(pconstr, pvecLocal, pvecConstr, pvecRemain);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", AddSoXa__FP2SOP2XA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", RemoveSoXa__FP2SOP2XA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", AddSoWaterAcceleration__FP2SOP5WATERf);\n\nvoid AddSoExternalAccelerations(SO *pso, XA *pxa, float dt)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", LoadSoFromBrx__FP2SOP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoSphere__FP2SOf);\n\nvoid SetSoNoInteract(SO *pso, int fNoInteract)\n{\n    SetSoConstraints(pso, CT_Locked, NULL, CT_Locked, NULL);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", ConstrFromCnstr__F5CNSTRP2CTP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoCnstrForce__FP2SO5CNSTR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoCnstrTorque__FP2SO5CNSTR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoCameraStyle__FP2SO3CMK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoIgnoreLocked__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoIceable__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoMtlk__FP2SO4MTLK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoEdgeGrab__FP2SO3EGK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SendSoMessage__FP2SO5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", PxpFindSoGround__FP2SOT0Pi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoNoGravity__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoNoXpsAll__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoNoXpsSelf__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", SetSoNoXpsCenter__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", RebuildSoPhysHook__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", PsoFindSoPhysHook__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", RecalcSoLocked__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FGetSoContactList__FP2SOPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", GetSoContacts__FP2SOPiPPP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FSoInStsoList__FP4STSOP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", GenerateSoSpliceTouchingEvents__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FInflictSoZap__FP2SOP2XPP3ZPR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", EnsureSoLvo__FP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", ProjectSoLvo__FP2SOf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", ProjectSoTransform__FP2SOfi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", ApplySoImpulse__FP2SOP6VECTORT1f);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", CalculateSoTrajectoryApex__FP2SOP6VECTORfT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FAbsorbSoWkr__FP2SOP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", CloneSoPhys__FP2SOT0i);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FUN_001bc4d8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FUN_001bc670);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FUN_001bc710);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/so\", FUN_001bc748);\n"
  },
  {
    "path": "src/P2/solve.c",
    "content": "#include <solve.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", RenumberSo__FP2SOPiPP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", CalculateSoEffect__FP2SOP6VECTORP2FXT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", PropagateSoForce__FP2SOiP2XPiP2DZP2FX);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", DistributeSoEffects__FP2SOiiPP2SOP2FX);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", SolveSwGroup__FP2SWiPP2SOiPP2XPfi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", CpxpBuildXpArray__FiPP2SOiPP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", BuildContactGroup__FP2SOPiPP2SOT1T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", SplitSoFreeze__FP2SOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", SortSwGroup__FiPP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", SplitSwGroup__FP2SWiPP2SOfi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/solve\", SolveSw__FP2SWfi);\n"
  },
  {
    "path": "src/P2/sort.c",
    "content": "#include <sort.h>\n\nvoid SwapEntries(void *afoo, int cb, int i1, int i2)\n{\n    int *p1 = (int *)(i1 * cb + (int)afoo);\n    int *p2 = (int *)(i2 * cb + (int)afoo);\n\n    while (cb > 0)\n    {\n        int temp = *p1;\n        *p1 = *p2;\n        *p2 = temp;\n\n        p1++;\n        p2++;\n        cb -= sizeof(int);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sort\", HeapSort__FPviiPFPvPv_i);\n"
  },
  {
    "path": "src/P2/sound.c",
    "content": "#include <sound.h>\n#include <989snd.h>\n#include <sce/memset.h>\n\nextern uchar D_00604790[]; // temp\n\n/**\n * @brief Media volume float.\n * @todo Does this even exist?\n */\nstruct MVG\n{\n    float vol; // Current volume\n    MVGK mvgk; // Media volume float kind\n    undefined4 unk2;\n    undefined4 unk3;\n};\n\nextern float D_00274838[10][4]; // temp\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", UnloadMusic__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SbpEnsureBank__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SbpEnsureBank__F5SFXID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", NewSfx__FPP3SFX);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FContinuousSound__F5SFXID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001BE5D8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SetVagUnpaused__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PreloadVag__FPc2FK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001be708);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PreloadVag1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FPauseForVag__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", RefreshPambVolPan__FP3AMB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001be8f8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FVagPlaying__Fv);\n\nJUNK_WORD(0x0080102D);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", StopVag__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PauseVag__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", ContinueVag__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", KillMusic__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PreloadMusidSongComplete__FUiUl);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PreloadMusidSong__F5MUSID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", StartMusidSong__F5MUSID);\n\nvoid PauseMusic()\n{\n    SetMvgkRvol(2, MVGK_Music, 0.0f);\n}\n\nvoid ContinueMusic()\n{\n    SetMvgkRvol(2, MVGK_Music, 1.0f);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SfxhMusicUnknown1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SfxhMusicUnknown2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PexcAlloc__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", RemoveExc__FP3EXC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", KillExcitement__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PexcSetExcitement__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SetIexcCurHigh__FP3EXC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", UnsetExcitement__FP3EXC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", UnsetExcitementHyst__FP3EXC);\n\nvoid StartupSound()\n{\n    memset(D_00604790, 0, 0x1c);\n    snd_StartSoundSystem();\n    SbpEnsureBank(0);\n    snd_InitVAGStreamingEx(1, 0x2000, 1, 1);\n    snd_SetGlobalExcite(0x14);\n    MvgkUnknown2();\n    snd_SetMixerMode(0, 1);\n    snd_SetGroupVoiceRange(0, 0, 0x2f);\n    snd_SetGroupVoiceRange(1, 0x18, 0x2f);\n    snd_SetGroupVoiceRange(3, 0x18, 0x2f);\n    snd_SetGroupVoiceRange(2, 0x18, 0x2f);\n    snd_PreAllocReverbWorkArea(2, 4);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FAmbientsPaused__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", CalculateVolPan__FfP6VECTORPfT2fff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001BF2E0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001BF398);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PposEar__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SetDoppler__FP3AMB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PfneardistGet__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SDistEar__FP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", CalculateDistVolPan__FP6VECTORPfT1fff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PambAlloc__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", DropPamb__FPP3AMB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", RemoveAmb__FP3AMB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", StopSound__FP3AMBi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SetPambFrq__FP3AMBf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SetPambVol__FP3AMBf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FillPamb__FP3AMBPP3AMBiP3ALOP6VECTORfffffP2LMT10_);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", ActivatePamb__FP3AMB5SFXID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", ScheduleNextIntermittentSound__FP3AMB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", StartSound__F5SFXIDPP3AMBP3ALOP6VECTORfffffP2LMT9);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001BFFC8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", HandleWipeHandleWipeVolumes__FifVolumes);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", UpdateSounds__Fv);\n\nvoid SetMvgkUvol(float uvol)\n{\n    snd_SetMasterVolume(8, (int)(uvol * 1024.0f));\n}\n\nvoid MvgkUnknown1(MVGK mvgk)\n{\n    float v = 1.0f;\n    for (int i = 0; i < 11; ++i)\n    {\n        v *= D_00274838[i][mvgk];\n    }\n\n    float one = 1.0f;\n    float zero = 0.0f;\n    if (v < zero)\n    {\n        v = zero;\n    }\n    else if (v > one)\n    {\n        v = one;\n    }\n    \n    snd_SetMasterVolume(mvgk, (int)(v * 1024.0f));\n}\n\nvoid SetMvgkRvol(int channel, MVGK mvgk, float rvol)\n{\n    D_00274838[channel][mvgk] = rvol;\n    MvgkUnknown1(mvgk);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", MvgkUnknown2__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", MvgkUnknown3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", MvgkUnknown4);\n\n/**\n * @todo Figure out func_001c0cb0, and use enum values for params where applicable.\n */\nvoid KillSoundSystem()\n{\n    snd_StopAllStreams();\n    KillSounds(0);\n    KillExcitement();\n    FUN_001c0cb0();\n    while (snd_FlushSoundCommands()) {}\n    snd_StreamSafeCheckCDIdle(1);\n    snd_StreamSafeCdSync(0);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", KillSounds__Fi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PushSwReverb__FP2SW7REVERBKi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", PopSwReverb__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SetSwDefaultReverb__FP2SW7REVERBKi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001C0A50);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001C0AB8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001C0B08);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", StartSwIntermittentSounds__FP2SW);\n\n// TODO: Verify signature.\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", SetAMRegister__FiUc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001c0c50);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001c0c68);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", FUN_001c0cb0__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", HsNextFootFall__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sound\", NextSneakyFootstep__Fv);\n"
  },
  {
    "path": "src/P2/speaker.c",
    "content": "#include <speaker.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/speaker\", InitSpeaker__FP7SPEAKER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/speaker\", PostSpeakerLoad__FP7SPEAKER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/speaker\", SetSpeakerSmIdle__FP7SPEAKER3OID);\n"
  },
  {
    "path": "src/P2/spire.c",
    "content": "#include <spire.h>\n#include <sw.h>\n\n/**\n * @todo Rename.\n */\nextern float DAT_0024d3b4;\n\nvoid InitSpire(SPIRE *pspire)\n{\n    InitLo(pspire);\n    STRUCT_OFFSET(pspire, 0x58, float) = DAT_0024d3b4;\n}\n\nvoid OnSpireAdd(SPIRE *pspire)\n{\n    OnLoAdd(pspire);\n    AppendDlEntry(&pspire->psw->dlSpire, pspire);\n}\n\nvoid OnSpireRemove(SPIRE *pspire)\n{\n    OnLoRemove(pspire);\n    RemoveDlEntry(&pspire->psw->dlSpire, pspire);\n}\n\nvoid CloneSpire(SPIRE *pspire, SPIRE *pspireBase)\n{\n    // pspire->dleSpire\n    DLE dleSpire = STRUCT_OFFSET(pspire, 0x50, DLE); \n    CloneLo(pspire, pspireBase);\n    STRUCT_OFFSET(pspire, 0x50, DLE) = dleSpire;\n}\n"
  },
  {
    "path": "src/P2/splice/bif.cpp",
    "content": "#include <splice/bif.h>\n#include <splice/ref.h>\n#include <splice/frame.h>\n#include <po.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpAdd__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpSub__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMult__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpDiv__FiP4CRefP6CFrame);\n\nCRef RefOpPrint(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetTag(TAGK_Void);\n    return CRef(cref);\n}\n\nCRef RefOpPrintFrame(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetTag(TAGK_Void);\n    return CRef(cref);\n}\n\nCRef RefOpPrintSidebag(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetTag(TAGK_Void);\n    return CRef(cref);\n}\n\nCRef RefOpIntEqual(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref[0].m_tag.m_n == aref[1].m_tag.m_n);\n    return CRef(cref);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefCmp__FP4CRef4CMPK);\n\nCRef RefOpL(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefCmp(aref, CMPK_L);\n}\n\nCRef RefOpLE(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefCmp(aref, CMPK_LE);\n}\n\nCRef RefOpG(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefCmp(aref, CMPK_G);\n}\n\nCRef RefOpGE(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefCmp(aref, CMPK_GE);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpEqv__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefEqualHelper__FP4CRefT0);\n\nCRef RefOpEqual(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefEqualHelper(&aref[0], &aref[1]);\n}\n\nCRef RefOpIsBoolean(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Bool);\n    return CRef(cref);\n}\n\nCRef RefOpIsNum(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_S32 || aref->m_tagk == TAGK_F32);\n    return CRef(cref);\n}\n\nCRef RefOpIsFloat(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_F32);\n    return CRef(cref);\n}\n\nCRef RefOpIsInteger(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_S32);\n    return CRef(cref);\n}\n\nCRef RefOpIsSymbol(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Symid);\n    return CRef(cref);\n}\n\nCRef RefOpIsVector(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Vector);\n    return CRef(cref);\n}\n\nCRef RefOpIsMatrix(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Matrix);\n    return CRef(cref);\n}\n\nCRef RefOpIsClq(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Clq);\n    return CRef(cref);\n}\n\nCRef RefOpIsLm(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Lm);\n    return CRef(cref);\n}\n\nCRef RefOpIsSmp(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Smp);\n    return CRef(cref);\n}\n\nCRef RefOpIsList(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Pair || aref->m_tagk == TAGK_None);\n    return CRef(cref);\n}\n\nCRef RefOpIsNull(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_None);\n    return CRef(cref);\n}\n\nCRef RefOpIsObject(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Basic);\n    return CRef(cref);\n}\n\nCRef RefOpIsNullObj(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Basic && !aref->m_tag.m_pbasic);\n    return CRef(cref);\n}\n\nCRef RefOpIsMethod(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Method);\n    return CRef(cref);\n}\n\nCRef RefOpIsProcedure(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Proc || aref->m_tagk == TAGK_Bifk);\n    return CRef(cref);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpAreNear__FiP4CRefP6CFrame);\n\nCRef RefOpNot(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBool(aref->m_tagk == TAGK_Bool && !aref->m_tag.m_bool);\n    return CRef(cref);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpCons__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpCar__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpCdr__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpSetCadr__FiP4CRefP6CFrame4BIFK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpSetCar__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpSetCdr__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpLength__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpNth__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpIsMember__FiP4CRefP6CFrame);\n\nCRef RefOpList(int carg, CRef *aref, CFrame *pframe)\n{\n    return CRef(*aref);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpAppend__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMap__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpFilter__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpForEach__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpEval__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVector__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrix__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpSetMusicRegister__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpClq__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpLm__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpSmp__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpGetElement__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpRandomSeed__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpRandom__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefUfo__FP4CRef4UFOK);\n\nCRef RefOpSqrt(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefUfo(aref, UFOK_Sqrt);\n}\n\nCRef RefOpSin(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefUfo(aref, UFOK_Sin);\n}\n\nCRef RefOpCos(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefUfo(aref, UFOK_Cos);\n}\n\nCRef RefOpTan(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefUfo(aref, UFOK_Tan);\n}\n\nCRef RefOpAsin(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefUfo(aref, UFOK_Asin);\n}\n\nCRef RefOpAcos(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefUfo(aref, UFOK_Acos);\n}\n\nCRef RefOpAtan(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefUfo(aref, UFOK_Atan);\n}\n\nCRef RefOpRadNormalize(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefUfo(aref, UFOK_RadNormalize);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpAtan2__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorDotProduct__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorCrossProduct__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorLth__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorDistance__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorDistanceSquared__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorNormalize__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorProjectNormal__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorProjectTangent__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorBallisticVelocity__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpVectorRadianNormal__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixTranspose__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixInvert__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixCalculateDmat__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixInterpolateRotate__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixDecomposeToTranslate__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixDecomposeToRotate__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixDecomposeToEuler__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixDecomposeToRadianNormal__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixLookAt__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMatrixTiltUpright__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpClqEvaluate__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpClqEvaluateLm__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpClqFit__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpLmLimit__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpLmCheck__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpFloor__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpCeiling__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpRound__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpTruncate__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpAbs__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMaximum__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpMinimum__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpModulo__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpCurrentTime__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpScheduleCallback__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpDeferObjectUpdate__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpObjectOption__FiP4CRefP6CFrame4BIFK);\n\nCRef RefOpAddO(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefOpObjectOption(carg, aref, pframe, BIFK_AddO);\n}\n\nCRef RefOpEnsureO(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefOpObjectOption(carg, aref, pframe, BIFK_EnsureO);\n}\n\nCRef RefOpSetO(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefOpObjectOption(carg, aref, pframe, BIFK_SetO);\n}\n\nCRef RefOpGetO(int carg, CRef *aref, CFrame *pframe)\n{\n    return RefOpObjectOption(carg, aref, pframe, BIFK_GetO);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefPairFromAplo__FiPP2LO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpFindObject__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpFindObjects__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpFindNearestObject__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpFindNearestObjects__FiP4CRefP6CFrame);\n\nCRef RefOpFindPlayerObject(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBasic(PpoCur());\n    return CRef(cref);\n}\n\nCRef RefOpFindWorldObject(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBasic(g_psw);\n    return CRef(cref);\n}\n\nCRef RefOpFindCameraObject(int carg, CRef *aref, CFrame *pframe)\n{\n    CRef cref = CRef();\n    cref.SetBasic(g_pcm);\n    return CRef(cref);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpFindClassObjects__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpFindObjectsInBoundingBox__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpFindObjectsInBoundingSphere__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpHitTestObjectsImpl__F4BIFKiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpHitTestObjects__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpHitTestObjectsFirst__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpConvertObjectPosition__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpConvertObjectVector__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpConvertObjectMatrix__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpNearClipCenter__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpStartSound__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpStopSound__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpStartRumble__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpEmitSmokeCloud__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", RefOpPredictAnimationEffect__FiP4CRefP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", __8VU_FLOATf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", __9VU_VECTORRC6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", __as__6VECTORG9VU_VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/bif\", __ml__FG8VU_FLOATG9VU_VECTOR);\n"
  },
  {
    "path": "src/P2/splice/eval.cpp",
    "content": "#include <splice/eval.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalSymbol__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalSet__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalDefine__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalAssert__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalIf__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalOr__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalAnd__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalCond__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalCase__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalLet__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalWhile__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalLambda__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalLambdaBody__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalBegin__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalApply__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEvalImport__FP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/eval\", RefEval__FP5CPairP6CFrame);\n"
  },
  {
    "path": "src/P2/splice/frame.cpp",
    "content": "#include <splice/frame.h>\n#include <splice/splotheap.h>\n#include <sce/memset.h>\n\nvoid CFrame::SetSingleParent(CFrame *pframeParent)\n{\n    m_apframeParent[0] = pframeParent;\n    m_cpframeParent = 1;\n}\n\nvoid CFrame::AddParent(CFrame *pframeParent)\n{\n    m_apframeParent[m_cpframeParent++] = pframeParent;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/frame\", RefAddBinding__6CFrameUiP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/frame\", RefSetBinding__6CFrameUiP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/frame\", FFindBinding__6CFrameUiiP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/frame\", PrefFindBinding__6CFrameUii);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/frame\", CloneTo__6CFrameP6CFrame);\n\nCFrame *PframeNew()\n{\n    CFrame *pframe = (CFrame *)g_splotheapFrame.PvAllocClear();\n    memset(pframe, 0, 0x1c);\n    return pframe;\n}\n\nvoid DeleteFrame(CFrame *pframe)\n{\n    return;\n}\n"
  },
  {
    "path": "src/P2/splice/gc.cpp",
    "content": "#include <splice/gc.h>\n#include <splice/splotheap.h>\n#include <splice/spliceutils.h>\n\nCGc::CGc()\n{\n    return;\n}\n\nCGc::~CGc()\n{\n    return;\n}\n\nvoid CGc::Startup()\n{\n    m_cpframeRoot = 0;\n    m_cpsidebagRoot = 0;\n}\n\nvoid CGc::Shutdown() {}\n\nvoid CGc::AddRootFrame(CFrame *pframe)\n{\n    for (int i = 0; i < m_cpframeRoot; ++i)\n    {\n        if (m_apframeRoot[i] == pframe)\n        {\n            return;\n        }\n    }\n    m_apframeRoot[m_cpframeRoot++] = pframe;\n}\n\nvoid CGc::AddRootSidebag(CSidebag *psidebag)\n{\n    m_apsidebagRoot[m_cpsidebagRoot++] = psidebag;\n}\n\nvoid CGc::PushFrame(CFrame *pframe)\n{\n    m_apframeStack[m_cpframeStack++] = pframe;\n}\n\nCFrame *CGc::PframePop()\n{\n    if (m_cpframeStack >= 1)\n    {\n        return m_apframeStack[--m_cpframeStack];\n    }\n    return NULL;\n}\n\nvoid CGc::PushPair(CPair *ppair)\n{\n    m_appairStack[m_cppairStack++] = ppair;\n}\n\nCPair *CGc::PpairPop()\n{\n    if (m_cppairStack >= 1)\n    {\n        return m_appairStack[--m_cppairStack];\n    }\n    return NULL;\n}\n\nvoid CGc::PushProc(CProc *pproc)\n{\n    m_approcStack[m_cpprocStack++] = pproc;\n}\n\nCProc *CGc::PprocPop()\n{\n    if (m_cpprocStack >= 1)\n    {\n        return m_approcStack[--m_cpprocStack];\n    }\n    return NULL;\n}\n\nvoid CGc::UpdateRecyclable()\n{\n    g_splotheapPair.UpdateRecyclable();\n    g_splotheapFrame.UpdateRecyclable();\n    g_splotheapUnk1.UpdateRecyclable();\n    g_splotheapProc.UpdateRecyclable();\n    g_splotheapMethod.UpdateRecyclable();\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/gc\", MarkLiveObjects__3CGc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/gc\", Collect__3CGc);\n\n// The functions below are compiler generated and their INCLUDE_ASM can just be removed once g_gc is defined\n// Currently blocked until references to g_gc are resolved\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/gc\", gc__static_initialization_and_destruction_0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/gc\", _GLOBAL_$I$g_gc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/gc\", _GLOBAL_$D$g_gc);\n"
  },
  {
    "path": "src/P2/splice/method.cpp",
    "content": "#include <sce/memset.h>\n#include <splice/method.h>\n#include <splice/splotheap.h>\n\n// todo: matches but blocked by reference in 001c15d8\n// INCLUDE_ASM(\"asm/nonmatchings/P2/splice/method\", PmethodNew__Fv);\nCMethod *PmethodNew()\n{\n    CMethod *method = (CMethod *)g_splotheapMethod.PvAllocClear();\n    memset(method, 0, sizeof(CMethod));\n    return method;\n}\n"
  },
  {
    "path": "src/P2/splice/pair.cpp",
    "content": "#include <splice/pair.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/pair\", CloneTo__5CPairP5CPairP6CFrame);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/pair\", PpairNew__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/pair\", DeletePair__FP5CPair);\n"
  },
  {
    "path": "src/P2/splice/proc.cpp",
    "content": "#include <sce/memset.h>\n#include <splice/proc.h>\n#include <splice/splotheap.h>\n\nvoid CProc::CloneTo(CProc *pprocClone, CFrame *pframeClone)\n{\n    pprocClone->m_pframe = pframeClone ? pframeClone : m_pframe;\n    pprocClone->m_ppair = m_ppair;\n    pprocClone->m_crefReq = m_crefReq;\n    pprocClone->m_fVarArg = m_fVarArg;\n    pprocClone->m_ppairCodeExpr = m_ppairCodeExpr;\n}\n\nCProc *PprocNew()\n{\n    CProc *proc = (CProc *)g_splotheapProc.PvAllocClear();\n    memset(proc, 0, sizeof(CProc));\n    return proc;\n}\n"
  },
  {
    "path": "src/P2/splice/ref.cpp",
    "content": "#include <splice/ref.h>\n#include <splice/vecmat.h>\n\nCRef::CRef()\n{\n    m_tagk = TAGK_Nil;\n}\n\nCRef::CRef(const CRef &ref)\n{\n    const_cast<CRef &>(ref).Incref();\n    m_tagk = ref.m_tagk;\n    m_tag = ref.m_tag;\n}\n\nCRef::~CRef()\n{\n    Decref();\n}\n\nCRef &CRef::operator=(const CRef &ref)\n{\n    const_cast<CRef &>(ref).Incref();\n    Decref();\n    m_tagk = ref.m_tagk;\n    m_tag = ref.m_tag;\n    return *this;\n}\n\n/**\n * @todo fix misalignment\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/ref\", __eq__4CRefRC4CRef);\n#ifdef SKIP_ASM\nbool CRef::operator==(const CRef& ref)\n{\n  if (m_tagk != ref.m_tagk) {\n    return false;\n  }\n  switch(m_tagk) {\n    case TAGK_F32:\n        return m_tag.m_g == ref.m_tag.m_g;\n    case TAGK_S32:\n        return m_tag.m_n == ref.m_tag.m_n;\n    case TAGK_Symid:\n        return m_tag.m_symid == ref.m_tag.m_symid;\n    case TAGK_Bifk:\n        return m_tag.m_bifk == ref.m_tag.m_bifk;\n    case TAGK_Pair:\n        return m_tag.m_ppair == ref.m_tag.m_ppair;\n    case TAGK_Proc:\n        return m_tag.m_pproc == ref.m_tag.m_pproc;\n    case TAGK_Method:\n        return m_tag.m_pmethod == ref.m_tag.m_pmethod;\n    case TAGK_Basic:\n        return (!m_tag.m_pbasic && !ref.m_tag.m_pbasic) || (m_tag.m_pbasic && ref.m_tag.m_pbasic);\n    case TAGK_Matrix:\n        return memcmp(m_tag.m_pmatrix,ref.m_tag.m_pmatrix, 0x40) == 0;\n    case TAGK_Lm:\n        return (m_tag.m_plm->gMin == ref.m_tag.m_plm->gMin) &&\n               (m_tag.m_plm->gMax == ref.m_tag.m_plm->gMax);\n    case TAGK_Vector:\n        return (m_tag.m_pvector->x == ref.m_tag.m_pvector->x) &&\n               (m_tag.m_pvector->y == ref.m_tag.m_pvector->y) &&\n               (m_tag.m_pvector->z == ref.m_tag.m_pvector->z);\n    case TAGK_Clq:\n        return (m_tag.m_pclq->g0 == ref.m_tag.m_pclq->g0) &&\n               (m_tag.m_pclq->g1 == ref.m_tag.m_pclq->g1) &&\n               (m_tag.m_pclq->g2 == ref.m_tag.m_pclq->g2);\n    case TAGK_Smp:\n        return (m_tag.m_psmp->svFast == ref.m_tag.m_psmp->svFast) &&\n               (m_tag.m_psmp->svSlow == ref.m_tag.m_psmp->svSlow) &&\n               (m_tag.m_psmp->dtFast == ref.m_tag.m_psmp->dtFast);\n    case TAGK_Bool:\n        return m_tag.m_bool == ref.m_tag.m_bool;\n    default:\n        return true;\n  }\n}\n#endif // SKIP_ASM\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/ref\", CloneTo__4CRefP4CRefP6CFrame);\n\n/**\n * @todo match rodata\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/ref\", Decref__4CRef);\n#ifdef SKIP_ASM\nvoid CRef::Decref()\n{\n    switch(m_tagk)\n    {\n        case TAGK_Vector:\n            DecrefVector(m_tag.m_pvector);\n            break;\n        case TAGK_Matrix:\n            DecrefMatrix(m_tag.m_pmatrix);\n            break;\n        case TAGK_Clq:\n            DecrefClq(m_tag.m_pclq);\n            break;\n        case TAGK_Lm:\n            DecrefLm(m_tag.m_plm);\n            break;\n        case TAGK_Smp:\n            DecrefSmp(m_tag.m_psmp);\n            break;\n    }\n}\n#endif // SKIP_ASM\n\n/**\n * @todo match rodata\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/ref\", Incref__4CRef);\n#ifdef SKIP_ASM\nvoid CRef::Incref()\n{\n    switch(m_tagk)\n    {\n        case TAGK_Vector:\n            IncrefVector(m_tag.m_pvector);\n            break;\n        case TAGK_Matrix:\n            IncrefMatrix(m_tag.m_pmatrix);\n            break;\n        case TAGK_Clq:\n            IncrefClq(m_tag.m_pclq);\n            break;\n        case TAGK_Lm:\n            IncrefLm(m_tag.m_plm);\n            break;\n        case TAGK_Smp:\n            IncrefSmp(m_tag.m_psmp);\n            break;\n    }\n}\n#endif\n\nvoid CRef::SetTag(TAGK tagk)\n{\n    Decref();\n    m_tagk = tagk;\n}\n\nvoid CRef::SetS32(int n)\n{\n    Decref();\n    m_tag.m_n = n;\n    m_tagk = TAGK_S32;\n}\n\nvoid CRef::SetF32(float g)\n{\n    Decref();\n    m_tag.m_g = g;\n    m_tagk = TAGK_F32;\n}\n\nvoid CRef::SetBool(int fBool)\n{\n    Decref();\n    if (fBool)\n    {\n        m_tag.m_bool = 1;\n    }\n    else\n    {\n        m_tag.m_bool = 0;\n    }\n    m_tagk = TAGK_Bool;\n}\n\nvoid CRef::SetSymid(uint symid)\n{\n    Decref();\n    m_tag.m_symid = symid;\n    m_tagk = TAGK_Symid;\n}\n\nvoid CRef::SetBifk(BIFK bifk)\n{\n    Decref();\n    m_tag.m_bifk = bifk;\n    m_tagk = TAGK_Bifk;\n}\n\nvoid CRef::SetPair(CPair *ppair)\n{\n    Decref();\n    m_tag.m_ppair = ppair;\n    m_tagk = TAGK_Pair;\n}\n\nvoid CRef::SetProc(CProc *pproc)\n{\n    Decref();\n    m_tag.m_pproc = pproc;\n    m_tagk = TAGK_Proc;\n}\n\nvoid CRef::SetVector(VECTOR *pvector)\n{\n    IncrefVector(pvector);\n    Decref();\n    m_tag.m_pvector = pvector;\n    m_tagk = TAGK_Vector;\n}\n\nvoid CRef::SetMatrix(MATRIX4 *pmatrix)\n{\n    IncrefMatrix(pmatrix);\n    Decref();\n    m_tag.m_pmatrix = pmatrix;\n    m_tagk = TAGK_Matrix;\n}\n\nvoid CRef::SetClq(CLQ *pclq)\n{\n    IncrefClq(pclq);\n    Decref();\n    m_tag.m_pclq = pclq;\n    m_tagk = TAGK_Clq;\n}\n\nvoid CRef::SetLm(LM *plm)\n{\n    IncrefLm(plm);\n    Decref();\n    m_tag.m_plm = plm;\n    m_tagk = TAGK_Lm;\n}\n\nvoid CRef::SetSmp(SMP *psmp)\n{\n    IncrefSmp(psmp);\n    Decref();\n    m_tag.m_psmp = psmp;\n    m_tagk = TAGK_Smp;\n}\n\nvoid CRef::SetBasic(BASIC *pbasic)\n{\n    Decref();\n    m_tag.m_pbasic = pbasic;\n    m_tagk = TAGK_Basic;\n}\n\nvoid CRef::SetMethod(CMethod *pmethod)\n{\n    Decref();\n    m_tag.m_pmethod = pmethod;\n    m_tagk = TAGK_Method;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/ref\", RefCoerceS32__4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/ref\", RefCoerceF32__4CRef);\n"
  },
  {
    "path": "src/P2/splice/serialize.cpp",
    "content": "#include <splice/serialize.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/serialize\", PpairSerializeIn__FP18CBinaryInputStream);\n"
  },
  {
    "path": "src/P2/splice/sidebag.cpp",
    "content": "#include <splice/sidebag.h>\n#include <sce/memset.h>\n#include <memory.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/sidebag\", RefAddBinding__8CSidebagiP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/sidebag\", RefSetBinding__8CSidebagiP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/sidebag\", FFindBinding__8CSidebagiP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/sidebag\", CloneTo__8CSidebagP8CSidebag);\n\nCSidebag *PsidebagNew()\n{\n    CSidebag *psidebag = (CSidebag *)PvAllocSwClearImpl(4);\n    memset(psidebag, 0, 4);\n    return psidebag;\n}\n"
  },
  {
    "path": "src/P2/splice/spliceutils.cpp",
    "content": "#include <splice/spliceutils.h>\n#include <splice/frame.h>\n#include <splice/gc.h>\n#include <splice/pair.h>\n#include <splice/splotheap.h>\n#include <splice/vecmat.h>\n\nextern CGc g_gc;\n\n// todo: match and fix blocked references\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/spliceutils\", StartupSplice__Fv);\n#ifdef SKIP_ASM\nvoid StartupSplice()\n{\n    g_gc.Startup();\n\n    g_splotheapPair.Startup(0xc, 0x2000);\n    g_splotheapPair.m_pfndelete = reinterpret_cast<PFNDELETE>(DeletePair);\n\n    g_splotheapFrame.Startup(0x1c, 0x190);\n    g_splotheapFrame.m_pfndelete = reinterpret_cast<PFNDELETE>(DeleteFrame);\n\n    g_splotheapUnk1.Startup(0x10, 0x800);\n    g_splotheapUnk1.m_pfndelete = reinterpret_cast<PFNDELETE>(0x11C4E8);\n\n    g_splotheapProc.Startup(0x14, 0x800);\n    StartupSpliceStructuredTypeFactories();\n\n    g_splotheapMethod.Startup(0xc, 0x80);\n}\n#endif // SKIP_ASM\n\nvoid ShutdownSplice()\n{\n    g_splotheapPair.Shutdown();\n    g_splotheapFrame.Shutdown();\n    g_splotheapUnk1.Shutdown();\n    g_splotheapProc.Shutdown();\n    ShutdownSpliceStructuredTypeFactories();\n    g_splotheapMethod.Shutdown();\n    g_gc.Shutdown();\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/spliceutils\", spliceutils__static_initialization_and_destruction_0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/spliceutils\", _GLOBAL_$I$g_splotheapPair);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/spliceutils\", _GLOBAL_$D$g_splotheapPair);\n"
  },
  {
    "path": "src/P2/splice/splotheap.cpp",
    "content": "#include <splice/splotheap.h>\n#include <sce/memset.h>\n#include <splice/gc.h>\n#include <memory.h>\n\n/**\n * @todo 94.76% match.\n * https://decomp.me/scratch/3gv6F\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/splotheap\", Startup__10CSplotheapii);\n#ifdef SKIP_ASM\nvoid CSplotheap::Startup(int cb, int c)\n{\n    m_c = c;\n    m_cb = cb + 8;\n    m_ab = (byte *)PvAllocSwImpl(m_cb * m_c);\n\n    SPLOT *psplotCurr = PsplotLookup(0);\n    for (int i = 1; i < c; i++)\n    {\n        SPLOT *psplotPrev = psplotCurr;\n        psplotCurr = PsplotLookup(i);\n        psplotPrev->psplotNext = psplotCurr;\n    }\n\n    psplotCurr->psplotNext = NULL;\n\n    m_psplotAlloc = NULL;\n    m_psplotRecyclable = NULL;\n}\n#endif // SKIP_ASM\n\nvoid CSplotheap::Shutdown()\n{\n    return;\n}\n\nvoid *CSplotheap::PvAllocUnsafe()\n{\n    if (!m_psplotFree)\n    {\n        g_gc.Collect();\n    }\n\n    SPLOT *psplot = m_psplotFree;\n    if (psplot)\n    {\n        m_psplotFree = psplot->psplotNext;\n        psplot->psplotNext = m_psplotAlloc;\n        m_psplotAlloc = psplot;\n        return PvFromPsplot(psplot);\n    }\n\n    return NULL;\n}\n\nvoid *CSplotheap::PvAllocClear()\n{\n    void *pv = PvAllocUnsafe();\n    memset(pv, 0, m_cb - sizeof(SPLOT));\n    return pv;\n}\n\nSPLOT *CSplotheap::PsplotLookup(int i)\n{\n    return (SPLOT *)(m_ab + i * m_cb);\n}\n\nvoid CSplotheap::UpdateRecyclable()\n{\n    m_psplotRecyclable = m_psplotAlloc;\n}\n\nvoid CSplotheap::UnmarkAll()\n{\n    SPLOT *psplot = m_psplotAlloc;\n    while (psplot)\n    {\n        psplot->fAlive = 0;\n        psplot = psplot->psplotNext;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/splotheap\", FreeGarbage__10CSplotheap);\n\nstatic void *PvFromPsplot(SPLOT *psplot)\n{\n    return (byte *)psplot + sizeof(SPLOT);\n}\n\nstatic SPLOT *PsplotFromPv(void *pv)\n{\n    return (SPLOT *)((byte *)pv - sizeof(SPLOT));\n}\n\nbool FIsPvGarbage(void *pv)\n{\n    SPLOT *psplot = PsplotFromPv(pv);\n    return !psplot->fAlive;\n}\n\nvoid MarkPvAlive(void *pv)\n{\n    SPLOT *psplot = PsplotFromPv(pv);\n    psplot->fAlive = 1;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/splotheap\", FUN_0011C418);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/splotheap\", FUN_0011C498);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splice/splotheap\", FUN_0011C4E8);\n"
  },
  {
    "path": "src/P2/splice/vecmat.cpp",
    "content": "#include <splice/vecmat.h>\n#include <sce/memset.h>\n#include <splice/gc.h>\n#include <slotheap.h>\n#include <memory.h>\n\n/**\n * @todo Once the data for this TU is migrated the code can be made much simpler.\n */\n\nextern int _t18CStructTypeFactory1Z6VECTOR$s_cmax;\nextern int _t18CStructTypeFactory1Z7MATRIX4$s_cmax;\nextern int _t18CStructTypeFactory1Z3CLQ$s_cmax;\nextern int _t18CStructTypeFactory1Z2LM$s_cmax;\nextern int _t18CStructTypeFactory1Z3SMP$s_cmax;\n\nextern byte *_t18CStructTypeFactory1Z6VECTOR$s_acref;\nextern byte *_t18CStructTypeFactory1Z7MATRIX4$s_acref;\nextern byte *_t18CStructTypeFactory1Z3CLQ$s_acref;\nextern byte *_t18CStructTypeFactory1Z2LM$s_acref;\nextern byte *_t18CStructTypeFactory1Z3SMP$s_acref;\n\nextern SLOTHEAP _t18CStructTypeFactory1Z6VECTOR$s_slotheap;\nextern SLOTHEAP _t18CStructTypeFactory1Z7MATRIX4$s_slotheap;\nextern SLOTHEAP _t18CStructTypeFactory1Z3CLQ$s_slotheap;\nextern SLOTHEAP _t18CStructTypeFactory1Z2LM$s_slotheap;\nextern SLOTHEAP _t18CStructTypeFactory1Z3SMP$s_slotheap;\n\nVECTOR *PvectorNew()\n{\n    VECTOR *pvector = (VECTOR *)PvAllocSlotheapUnsafe(&_t18CStructTypeFactory1Z6VECTOR$s_slotheap);\n    if (pvector)\n    {\n        memset(pvector, 0, _t18CStructTypeFactory1Z6VECTOR$s_slotheap.cb);\n    }\n    else\n    {\n        g_gc.Collect();\n        pvector = (VECTOR *)PvAllocSlotheapClearImpl(&_t18CStructTypeFactory1Z6VECTOR$s_slotheap);\n    }\n\n    return pvector;\n}\n\nvoid IncrefVector(VECTOR *pvector)\n{\n    // TODO: Size of VECTOR should be 16 bytes.\n    _t18CStructTypeFactory1Z6VECTOR$s_acref[((uint)pvector - (uint)_t18CStructTypeFactory1Z6VECTOR$s_slotheap.ab) / 16]++;\n}\n\nvoid DecrefVector(VECTOR *pvector)\n{\n    // TODO: Size of VECTOR should be 16 bytes.\n    uint index = ((uint)pvector - (uint)_t18CStructTypeFactory1Z6VECTOR$s_slotheap.ab) / 16;\n\n    if (--_t18CStructTypeFactory1Z6VECTOR$s_acref[index])\n        return;\n\n    FreeSlotheapPv(&_t18CStructTypeFactory1Z6VECTOR$s_slotheap, pvector);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\n\nMATRIX4 *PmatrixNew()\n{\n    MATRIX4 *pmatrix = (MATRIX4 *)PvAllocSlotheapUnsafe(&_t18CStructTypeFactory1Z7MATRIX4$s_slotheap);\n    if (pmatrix)\n    {\n        memset(pmatrix, 0, _t18CStructTypeFactory1Z7MATRIX4$s_slotheap.cb);\n    }\n    else\n    {\n        g_gc.Collect();\n        pmatrix = (MATRIX4 *)PvAllocSlotheapClearImpl(&_t18CStructTypeFactory1Z7MATRIX4$s_slotheap);\n    }\n\n    return pmatrix;\n}\n\nvoid IncrefMatrix(MATRIX4 *pmatrix)\n{\n    uint index = ((uint)pmatrix - (uint)_t18CStructTypeFactory1Z7MATRIX4$s_slotheap.ab) / sizeof(MATRIX4);\n    _t18CStructTypeFactory1Z7MATRIX4$s_acref[index]++;\n}\n\nvoid DecrefMatrix(MATRIX4 *pmatrix)\n{\n    uint index = ((uint)pmatrix - (uint)_t18CStructTypeFactory1Z7MATRIX4$s_slotheap.ab) / sizeof(MATRIX4);\n\n    if (--_t18CStructTypeFactory1Z7MATRIX4$s_acref[index])\n        return;\n\n    FreeSlotheapPv(&_t18CStructTypeFactory1Z7MATRIX4$s_slotheap, pmatrix);\n}\n\nvoid DeleteMatrix(MATRIX4 *pmatrix)\n{\n    FreeSlotheapPv(&_t18CStructTypeFactory1Z7MATRIX4$s_slotheap, pmatrix);\n}\n \nCLQ *PclqNew()\n{\n    CLQ *pclq = (CLQ *)PvAllocSlotheapUnsafe(&_t18CStructTypeFactory1Z3CLQ$s_slotheap);\n    if (pclq)\n    {\n        memset(pclq, 0, _t18CStructTypeFactory1Z3CLQ$s_slotheap.cb);\n    }\n    else\n    {\n        g_gc.Collect();\n        pclq = (CLQ *)PvAllocSlotheapClearImpl(&_t18CStructTypeFactory1Z3CLQ$s_slotheap);\n    }\n\n    return pclq;\n}\n\nvoid IncrefClq(CLQ *pclq)\n{\n    uint index = ((uint)pclq - (uint)_t18CStructTypeFactory1Z3CLQ$s_slotheap.ab) / sizeof(CLQ);\n    _t18CStructTypeFactory1Z3CLQ$s_acref[index]++;\n}\n\nvoid DecrefClq(CLQ *pclq)\n{\n    uint index = ((uint)pclq - (uint)_t18CStructTypeFactory1Z3CLQ$s_slotheap.ab) / sizeof(CLQ);\n\n    if (--_t18CStructTypeFactory1Z3CLQ$s_acref[index])\n        return;\n\n    FreeSlotheapPv(&_t18CStructTypeFactory1Z3CLQ$s_slotheap, pclq);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\n\nLM *PlmNew()\n{\n    LM *plm = (LM *)PvAllocSlotheapUnsafe(&_t18CStructTypeFactory1Z2LM$s_slotheap);\n    if (plm)\n    {\n        memset(plm, 0, _t18CStructTypeFactory1Z2LM$s_slotheap.cb);\n    }\n    else\n    {\n        g_gc.Collect();\n        plm = (LM *)PvAllocSlotheapClearImpl(&_t18CStructTypeFactory1Z2LM$s_slotheap);\n    }\n\n    return plm;\n}\n\nvoid IncrefLm(LM *plm)\n{\n    uint index = ((uint)plm - (uint)_t18CStructTypeFactory1Z2LM$s_slotheap.ab) / sizeof(LM);\n    _t18CStructTypeFactory1Z2LM$s_acref[index]++;\n}\n\nvoid DecrefLm(LM *plm)\n{\n    uint index = ((uint)plm - (uint)_t18CStructTypeFactory1Z2LM$s_slotheap.ab) / sizeof(LM);\n\n    if (--_t18CStructTypeFactory1Z2LM$s_acref[index])\n        return;\n\n    FreeSlotheapPv(&_t18CStructTypeFactory1Z2LM$s_slotheap, plm);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\n\nSMP *PsmpNew()\n{\n    SMP *psmp = (SMP *)PvAllocSlotheapUnsafe(&_t18CStructTypeFactory1Z3SMP$s_slotheap);\n    if (psmp)\n    {\n        memset(psmp, 0, _t18CStructTypeFactory1Z3SMP$s_slotheap.cb);\n    }\n    else\n    {\n        g_gc.Collect();\n        psmp = (SMP *)PvAllocSlotheapClearImpl(&_t18CStructTypeFactory1Z3SMP$s_slotheap);\n    }\n\n    return psmp;\n}\n\nvoid IncrefSmp(SMP *psmp)\n{\n    uint index = ((uint)psmp - (uint)_t18CStructTypeFactory1Z3SMP$s_slotheap.ab) / sizeof(SMP);\n    _t18CStructTypeFactory1Z3SMP$s_acref[index]++;\n}\n\nvoid DecrefSmp(SMP *psmp)\n{\n    uint index = ((uint)psmp - (uint)_t18CStructTypeFactory1Z3SMP$s_slotheap.ab) / sizeof(SMP);\n\n    if (--_t18CStructTypeFactory1Z3SMP$s_acref[index])\n        return;\n\n    FreeSlotheapPv(&_t18CStructTypeFactory1Z3SMP$s_slotheap, psmp);\n}\n\nvoid StartupSpliceStructuredTypeFactories()\n{\n    // TODO: Size of VECTOR should be 16 bytes.\n    CreateSlotheapSw(&_t18CStructTypeFactory1Z6VECTOR$s_slotheap, 0x10, _t18CStructTypeFactory1Z6VECTOR$s_cmax);\n    _t18CStructTypeFactory1Z6VECTOR$s_acref = (byte *)PvAllocSwClearImpl(_t18CStructTypeFactory1Z6VECTOR$s_cmax);\n\n    CreateSlotheapSw(&_t18CStructTypeFactory1Z7MATRIX4$s_slotheap, sizeof(MATRIX4), _t18CStructTypeFactory1Z7MATRIX4$s_cmax);\n    _t18CStructTypeFactory1Z7MATRIX4$s_acref = (byte *)PvAllocSwClearImpl(_t18CStructTypeFactory1Z7MATRIX4$s_cmax);\n\n    CreateSlotheapSw(&_t18CStructTypeFactory1Z3CLQ$s_slotheap, sizeof(CLQ), _t18CStructTypeFactory1Z3CLQ$s_cmax);\n    _t18CStructTypeFactory1Z3CLQ$s_acref = (byte *)PvAllocSwClearImpl(_t18CStructTypeFactory1Z3CLQ$s_cmax);\n\n    CreateSlotheapSw(&_t18CStructTypeFactory1Z2LM$s_slotheap, sizeof(LM) ,_t18CStructTypeFactory1Z2LM$s_cmax);\n    _t18CStructTypeFactory1Z2LM$s_acref = (byte *)PvAllocSwClearImpl(_t18CStructTypeFactory1Z2LM$s_cmax);\n\n    CreateSlotheapSw(&_t18CStructTypeFactory1Z3SMP$s_slotheap, sizeof(SMP), _t18CStructTypeFactory1Z3SMP$s_cmax);\n    _t18CStructTypeFactory1Z3SMP$s_acref = (byte *)PvAllocSwClearImpl(_t18CStructTypeFactory1Z3SMP$s_cmax);\n}\n\nvoid ShutdownSpliceStructuredTypeFactories()\n{\n    return;\n}\n"
  },
  {
    "path": "src/P2/splicemap.c",
    "content": "#include <splicemap.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splicemap\", LoadSwSpliceFromBrx__FP2SWP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splicemap\", PframeFromIsplice__FiP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/splicemap\", RefEvalModule__FiP2SW);\n"
  },
  {
    "path": "src/P2/spliceobj.c",
    "content": "#include <spliceobj.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", PeopidFind__FP5BASICi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefGetObjectList__FP5BASIC4OTYPPFPv_v);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefGetPeopid__FP5BASICP5EOPID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", FAppendSpliceListElement__FPvT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", FSpliceListElementExists__FPvT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefSetPvsFromSplice__FiP4CRefP4OTYPPPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefSetArgListFromPvs__FiP4OTYPPPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefSetPeopid__FP5BASICP5EOPIDP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefGetOption__FP5BASICi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefSetOption__FP5BASICiP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefAddOption__FP5BASICiP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefEnsureOption__FP5BASICiP4CRef);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/spliceobj\", RefSetArgsFromSplice__FiP4CRefP4OTYPe);\n"
  },
  {
    "path": "src/P2/sprbuf.c",
    "content": "#include <sprbuf.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sprbuf\", LoadSprBuf__Fie);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sprbuf\", SaveSprBuf__FPve);\n\nJUNK_ADDIU(A0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sprbuf\", sprbuf__static_initialization_and_destruction_0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sprbuf\", _GLOBAL_$I$g_asprbuf);\n"
  },
  {
    "path": "src/P2/sqtr.c",
    "content": "#include <sqtr.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sqtr\", FUN_001c29e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sqtr\", UpdateSqtrm__FP5SQTRMP6VECTORP7MATRIX3ff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sqtr\", RenderSqtrm__FP5SQTRMP2CM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sqtr\", DrawSqtrm__FP3RPL);\n"
  },
  {
    "path": "src/P2/step.c",
    "content": "#include <step.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", InitStep__FP4STEP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", PostStepLoad__FP4STEP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", LimitStepHands__FP4STEPi);\n\n// TODO: This might be \"RetractStepExtremity\". Further research needed.\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", FUN_001c4618);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", FUN_001c4790);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", FUN_001c4848);\n\nvoid RenderStepSelf__FP4STEPP2CMP2RO(STEP *pstep, CM *pcm, RO *pro)\n{\n    RenderSoSelf(pstep, pcm, pro);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", ReadStepJoystick__FP4STEPP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", UpdateStepFootfall__FP4STEPfP3SFF);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", UpdateStepPhys__FP4STEP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", SetStepPhys__FP4STEPP2SOi);\n\nvoid UpdateStep(STEP *pstep, float dt)\n{\n    UpdatePo(pstep, dt);\n    UpdateStepPhys(pstep);\n}\n\nCT CtTorqueStep(STEP *pstep)\n{\n    return CT_Locked;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", PropagateStepForce__FP4STEPiP2XPiP2DZP2FX);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", RotateStepToMat__FP4STEPP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", CloneStepPhys__FP4STEPP2SOi);\n\nvoid PresetStepAccel(STEP *pstep, float dt)\n{\n    PresetSoAccel(pstep, dt);\n    PresetStepAccelBase(pstep);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", PresetStepAccelBase__FP4STEP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", FCheckStepXpBase__FP4STEPP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", AdjustStepNewXp__FP4STEPP2XPi);\n\nvoid AdjustStepDz(STEP *pstep, GRFADJ grfadj, DZ *pdz, int ixpd, float dt)\n{\n    AdjustStepDzBase(pstep, grfadj, pdz, ixpd);\n}\n\nvoid AdjustStepDzBase(STEP *pstep, GRFADJ grfadj, DZ *pdz, int ixpd)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", UpdateStepMatTarget__FP4STEP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", AdjustStepXpVelocity__FP4STEPP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", UpdateStepXfWorld__FP4STEP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", AdjustStepXpVelocityBase__FP4STEPP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", AdjustStepXps__FP4STEP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", AddStepCustomXps__FP4STEPP2SOiP3BSPT3PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", AddStepCustomXpsBase__FP4STEPP2SOP3BSPPP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", FixStepAngularVelocity__FP4STEP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", PredictStepRotation__FP4STEPfP7MATRIX3P6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", SetStepSpinRatio__FP4STEPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/step\", SetStepGravityRatio__FP4STEPf);\n"
  },
  {
    "path": "src/P2/stepact.c",
    "content": "#include <stepact.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepact\", GetActaddPositionGoal__FP6ACTADDfP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepact\", GetActaddRotationGoal__FP6ACTADDfP7MATRIX3P6VECTOR);\n"
  },
  {
    "path": "src/P2/stepcane.c",
    "content": "#include <stepcane.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepcane\", SetJtJtcs__FP2JT4JTCS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepcane\", UpdateJtCane__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepcane\", UpdateJtActiveCane__FP2JTP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepcane\", ChooseJtAttackTarget__FP2JTiP6VECTORffPP6TARGETT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepcane\", ChooseJtSweepTarget__FP2JTP2BLP6ASEGBL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepcane\", ChooseJtRushTarget__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepcane\", ChooseJtSmashTarget__FP2JT);\n"
  },
  {
    "path": "src/P2/stepguard.c",
    "content": "#include <stepguard.h>\n#include <asega.h>\n\nextern SNIP s_asnipStepguardLoad;\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", InitStepguard__FP9STEPGUARD);\n\nvoid LoadStepguardFromBrx(STEPGUARD *pstepguard, CBinaryInputStream *pbis)\n{\n    LoadSoFromBrx(pstepguard, pbis);\n    SnipAloObjects(pstepguard, 1, &s_asnipStepguardLoad);\n    LoadStepguardAnimations(pstepguard);\n    LoadStepguardPhys(pstepguard);\n}\n\nvoid CloneStepguard(STEPGUARD *pstepguard, STEPGUARD *pstepguardBase)\n{\n    int ichkDead = STRUCT_OFFSET(pstepguard, 0xb10, int); // pstepguard->ichkDead\n    SGG *psgg = STRUCT_OFFSET(pstepguard, 0x720, SGG *); // pstepguard->psgg\n    ClonePo(pstepguard, pstepguardBase);\n    STRUCT_OFFSET(pstepguard, 0xb10, int) = ichkDead; // pstepguard->ichkDead\n    STRUCT_OFFSET(pstepguard, 0x720, SGG *) = psgg; // pstepguard->psgg\n    STRUCT_OFFSET(pstepguard, 0xb74, STEPGUARD *) = pstepguardBase; // pstepguard->pstepguardBase\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", BindStepguard__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", PostStepguardLoadCallback__FP9STEPGUARD5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", PostStepguardLoad__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FIgnoreStepguardIntersection__FP9STEPGUARDP2SO);\n\nvoid OnStepguardAdd(STEPGUARD *pstepguard)\n{\n    OnPoAdd(pstepguard);\n\n    // pstepguard->psgg\n    if (STRUCT_OFFSET(pstepguard, 0x720, SGG *))\n    {\n        AddSggGuard(STRUCT_OFFSET(pstepguard, 0x720, SGG *), pstepguard);\n    }\n}\n\n/**\n * @todo 96.67% match.\n * https://decomp.me/scratch/HcoZ7\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", OnStepguardRemove__FP9STEPGUARD);\n#ifdef SKIP_ASM\nextern float D_0024D654;\n\nvoid OnStepguardRemove(STEPGUARD *pstepguard)\n{\n    OnPoRemove(pstepguard);\n\n    ASEGA *pasegaSgs = STRUCT_OFFSET(pstepguard, 0x7e0, ASEGA *);\n    if (pasegaSgs)\n    {\n        RetractAsega(pasegaSgs);\n        STRUCT_OFFSET(pstepguard, 0x7e0, ASEGA *) = 0;\n    }\n\n    ASEGA *pasegaPatrol = STRUCT_OFFSET(pstepguard, 0x754, ASEGA *);\n    if (pasegaPatrol)\n    {\n        RetractAsega(pasegaPatrol);\n        STRUCT_OFFSET(pstepguard, 0x754, ASEGA *) = 0;\n    }\n\n    SGG *psgg = STRUCT_OFFSET(pstepguard, 0x720, SGG *);\n    if (psgg)\n    {\n        RemoveSggGuard(psgg, pstepguard);\n    }\n\n    const float val = D_0024D654;\n    STRUCT_OFFSET(pstepguard, 0xa60, int) = 0;\n    STRUCT_OFFSET(pstepguard, 0x748, int) = 0;\n    STRUCT_OFFSET(pstepguard, 0xba4, int) = 0;\n\n    STRUCT_OFFSET(pstepguard, 0xbf4, float) = val;\n    STRUCT_OFFSET(pstepguard, 0xbf8, float) = val;\n    STRUCT_OFFSET(pstepguard, 0xbfc, float) = val;\n    STRUCT_OFFSET(pstepguard, 0x72c, int) = 0;\n    STRUCT_OFFSET(pstepguard, 0xc00, float) = val;\n}\n#endif // SKIP_ASM\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", PresetStepguardAccel__FP9STEPGUARDf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", DradEnemyStepguard__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SetStepguardTargetHeading__FP9STEPGUARDff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001c7b60);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UpdateStepguardDrive__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UpdateStepguard__FP9STEPGUARDf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SgsNextStepguardAI__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SetStepguardGoal__FP9STEPGUARDP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FReachedStepguardGoal__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FFilterStepguardJump__FP9STEPGUARDP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", MoveStepguardToGoal__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001c8920);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", LookStepguardAtGoal__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UpdateStepguardGoal__FP9STEPGUARDi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001c8d40);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", OnStepguardWaypointActive__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UpdateStepguardSgs__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SetStepguardSgs__FP9STEPGUARD3SGSP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SetStepguardSgsExternal__FP9STEPGUARD3SGSP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", OnStepguardExitingSgs__FP9STEPGUARD3SGS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", OnStepguardEnteringSgs__FP9STEPGUARD3SGSP4ASEG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SggsGetStepguard__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FAbsorbStepguardWkr__FP9STEPGUARDP3WKR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FTakeStepguardDamage__FP9STEPGUARDP3ZPR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001c9a48);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", HandleStepguardGrfsgsc__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", DoStepguardFreefallJump__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", DoStepguardFreefallLanding__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001c9d50);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", HandleStepguardMessage__FP9STEPGUARD5MSGIDPv);\n\nSGAS SgasGetStepguard(STEPGUARD *pstepguard)\n{\n    return SGAS_Force;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FCanStepguardAttack__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", RenderStepguardSelf__FP9STEPGUARDP2CMP2RO);\n\nint FValidSgs(SGS sgs)\n{\n    return ((uint)sgs < 0x11);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UseStepguardAnimation__FP9STEPGUARD3SGS3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UseStepguardAnimationImmediate__FP9STEPGUARD3SGS3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001ca6d0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UseStepguardDeathAnimation__FP9STEPGUARDi3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", PasegFindStepguard__FP9STEPGUARD3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", LoadStepguardAnimations__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UseStepguardExpl__FP9STEPGUARD3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UseStepguardRwm__FP9STEPGUARD3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UseStepguardPhys__FP9STEPGUARD3SGS3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", LoadStepguardPhys__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", AddStepguardEffect__FP9STEPGUARD3OID3ZPK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SetStepguardPathzone__FP9STEPGUARD3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", PsoEnemyStepguard__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001caad0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SetStepguardEnemyObject__FP9STEPGUARDP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", RebindStepguardEnemy__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001cac28__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001cac30);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", AdjustStepguardDz__FP9STEPGUARDiP2DZif);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SetStepguardAttackAngleMax__FP9STEPGUARDf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", AddStepguardAlarm__FP9STEPGUARDP5ALARM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", MatchStepguardAnimationPhase__FP9STEPGUARD3OIDN31);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", AddStepguardCustomXps__FP9STEPGUARDP2SOiP3BSPT3PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001caee0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UpdateStepguardEffect__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SetStepguardPatrolAnimation__FP9STEPGUARDP4ASEG);\n\nint FInflictStepguardZap(STEPGUARD *pstepguard, XP *pxp, ZPR *pzpr)\n{\n    return 1;\n}\n\nint FDetectStepguard(STEPGUARD *pstepguard)\n{\n    return 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FCheckStepguardEnemyHidden__FP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FUN_001cb578);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", PsggNew__FP2SW);\n\nvoid InitSgg(SGG *psgg)\n{\n    InitLo(psgg);\n    STRUCT_OFFSET(psgg, 0x180, OID) = OID_Nil; // psgg->oidSync\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", AddSggGuard__FP3SGGP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", AddSggGuardName__FP3SGG3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", AddSggSearchXfmName__FP3SGG3OID);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", RemoveSggGuard__FP3SGGP9STEPGUARD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", BindSgg__FP3SGG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", PostSggLoadCallback__FP3SGG5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", EnsureSggCallback__FP3SGG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", PsoEnemySgg__FP3SGG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", UpdateSggCallback__FP3SGG5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SggsNextSgg__FP3SGG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FDetectSgg__FP3SGG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", FAbandonSggSearch__FP3SGG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", EnsureSggAlarm__FP3SGGP5ALARM);\n\nvoid TriggerSggAlarms(SGG *psgg, ALTK altk)\n{\n    for (int i = 0; i < STRUCT_OFFSET(psgg, 0x168, int); i++) // psgg->calarms\n    {\n        TriggerAlarm(STRUCT_OFFSET_INDEX(psgg, 0x16c, ALARM *, i), altk); // psgg->palarms[i]\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", SetSggSggs__FP3SGG4SGGS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepguard\", AssignSggSearchPoints__FP3SGG);\n\n// junk_001CC3F8\nJUNK_ADDIU(10);\nJUNK_WORD(0x7c450000);\nJUNK_WORD(0x48220800);\n"
  },
  {
    "path": "src/P2/stephang.c",
    "content": "#include <stephang.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", PostJtLoadSwing__FP2JTP2BLPP6ASEGBL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", AnticipateJtForce__FP2JTP2SOP6VECTORT2P2FX);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", CalculateJtHangAccel__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", PresetJtAccelHang__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", AddJtExternalAccelerations__FP2JTP2XAf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", UpdateJtActiveHang__FP2JTP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", CheckJtUnhook__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", UpdateJtHookOx__FP2JTP2LOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", AddJtHookXps__FP2JTiP2LOP6VECTORN23);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", GetJtHangHeading__FP2JTPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", UpdateJtIkHang__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", FUN_001cdd98);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephang\", FUN_001cdf78);\n"
  },
  {
    "path": "src/P2/stephide.c",
    "content": "#include <stephide.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", JtbsChooseJtHide__FP2JTP2LOP4JTHK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", MeasureJtJumpToTarget__FP2JTP6VECTORP3ALOT1T1PfT5T1T1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", GetJtRailLanding__FP2JTP4RAILfP6VECTORT3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", GMeasureJumpRail__FP3MJRf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", FUN_001cea58);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", GMeasureJumpHshape__FP3MJHf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", FUN_001ceb18);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", FUN_001cedf8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", FUN_001cee30);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", FUN_001ceec8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", FUN_001cf138);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", FUN_001cf158);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", UpdateJtActiveHide__FP2JTP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", MatchJtXmgRail__FP2JTP3XMGP6ACTADJ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", UpdateJtHide__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", UpdateJtInternalXpsHide__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", SetJtHfdk__FP2JT4HFDK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", ResetJtDynamicTunnel__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", PresetJtAccelHide__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stephide\", FUN_001d1478);\n"
  },
  {
    "path": "src/P2/steppipe.c",
    "content": "#include <steppipe.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steppipe\", PostJtLoadPipe__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steppipe\", GetJtPipeGoalMat__FP2JTP4PIPEfP7MATRIX3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steppipe\", PresetJtAccelPipe__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steppipe\", UpdateJtActivePipe__FP2JTP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steppipe\", UpdateJtInternalXpsPipe__FP2JT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steppipe\", SetJtJtpdk__FP2JT5JTPDK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steppipe\", PlaceJtOnPipe__FP2JTP4PIPE);\n"
  },
  {
    "path": "src/P2/steppower.c",
    "content": "#include <steppower.h>\n#include <game.h>\n#include <jt.h>\n#include <screen.h>\n#include <clock.h>\n#include <steprail.h>\n\n// GRFVAULT s_mpfspgrfvault[7];\nextern BLOT g_binoc;   // todo: find where this belongs.\nextern int D_00270458; // temp\n// SMP SMP_00274f78; // initialized with { 2.0f, 0.0f, 0.1f }\n\nvoid SetFsp(FSP fsp)\n{\n    // Cleanup current powerup.\n    switch (g_fsp)\n    {\n        case FSP_Ball:\n        {\n            // If current powerup is roll, reset JT's body state.\n            if (g_pjt && g_pjt->jts == (JTS)13)\n            {\n                SetJtJts(g_pjt, JTS_Stand, JTBS_Nil);\n            }\n            break;\n        }\n        case FSP_Mine:\n        {\n            // If current powerup is mine, fade out the mine.\n            if (g_pjt && g_pjt->paloMine_0x1518 && FIsLoInWorld(g_pjt->paloMine_0x1518))\n            {\n                FadeAloOut(g_pjt->paloMine_0x1518, 0.5f);\n            }\n            break;\n        }\n        default:\n        {\n            break;\n        }\n    }\n\n    if (g_pjt)\n    {\n        g_rtClockPowerUp = 1.0f;\n        if (g_pjt->unk_0x2750 && FIsLoInWorld((JT *)g_pjt->unk_0x2750))\n        {\n            func_001D32D8(g_pjt->unk_0x2750, g_pjt, 1);\n        }\n\n        func_001D31D0(g_pjt, 0);\n        if (g_pjt && g_pjt == PpoCur())\n        {\n            g_fsp = fsp;\n        }\n    }\n\n    // If fsp is unchanged or invalid, return.\n    if (fsp == g_pgsCur->fspLast || fsp >= (uint)FSP_Max)\n    {\n        return;\n    }\n\n    // Show note.\n    SetBlotDtVisible((NOTE *)&g_note.unk278, (g_pjt && g_pjt == PpoCur()) ? 3.0f : 8.0f);\n    SetBlotFontScale(0.6f, (NOTE *)&g_note.unk278);\n    ((NOTE *)&g_note.unk278)->pvtnote->pfnSetNoteAchzDraw((NOTE *)&g_note.unk278, s_mpfspachz[fsp]);\n    ((NOTE *)&g_note.unk278)->pvtnote->pfnShowBlot((NOTE *)&g_note.unk278);\n\n    // Update last fsp in game state.\n    g_pgsCur->fspLast = fsp;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steppower\", UpdateJtActivePowerUp__FP2JTP3JOY);\n// #ifdef SKIP_ASM\n/**\n * @todo 46.12% match.\n */\n/*\nvoid UpdateJtActivePowerUp(JT *pjt, JOY *pjoy)\n{\n    if (g_fsp > FSP_Nil)\n    {\n        // Some powerup is active, so get the grfvault.\n        GRFVAULT grfvault = GetGrfvault_unknown();\n        if (s_mpfspgrfvault[(uint)g_fsp] & (uint)grfvault == 0)\n        {\n            // Disable powerup if grfvault didn't match a valid powerup.\n            SetFsp(FSP_Nil);\n            g_pgsCur->fspLast = FSP_Nil;\n        }\n    }\n\n    // Check whether jt is in a state where rotating powerups is allowed.\n    bool fcanRotate;\n    uint jtsval;\n    switch (g_fsp)\n    {\n    case FSP_Dive:\n        // Only rotate if JT is rushing or ledge grabbing.\n        if (g_pjt == NULL\n            || g_pjt->jts != JTS_Rush\n            || !g_pjt->jts == JTS_Jump && g_pjt->jtbs == (JTBS)0x8)\n        {\n            fcanRotate = true;\n        }\n        else\n        {\n            fcanRotate = false;\n        }\n        break;\n    case FSP_Ball:\n        // Only rotate if JT is not rolling.\n        if (g_pjt != NULL\n            && !(g_pjt->jts == JTS_Ball && g_pjt->jtbs == (JTBS)0xd))\n            {\n                fcanRotate = true;\n            }\n            else\n            {\n                fcanRotate = false;\n            }\n        break;\n    case FSP_SlowDownClock:\n    case FSP_SpeedUpClock:\n        // Only rotate when clock rate is close enough to 1.0.\n        fcanRotate = FFloatsNear(g_rtClockPowerUp, 1.0, 0.0001);\n        break;\n    case FSP_Mine:\n        // Only rotate if Xor of current jts with 0x10 != 0.\n        jtsval = g_pjt->jts ^ 0x10;\n        fcanRotate = (uint)(jtsval != 0);\n        break;\n    case FSP_Decoy:\n        // Only rotate if Xor of current jts with 0xe != 0.\n        jtsval = g_pjt->jts ^ 0xE;\n        fcanRotate = (uint)(jtsval != 0);\n        break;\n    case FSP_Stun:\n        // Only rotate if ???\n        fcanRotate = 0;\n        if (g_pjt->jts != (JTS)0xF)\n        {\n            fcanRotate = STRUCT_OFFSET(g_pjt, 0x275c, uint) == 0;\n        }\n        break;\n    case FSP_Nil:\n        // Always rotate is no powerup is selected.\n        fcanRotate = 1;\n        break;\n    default:\n        break;\n    }\n\n    // Disallow rotating if JT status is Zap or binoc is showing.\n    if (g_pjt != NULL && g_pjt->jts == JTS_Zap)\n        fcanRotate = false;\n\n    if (g_binoc.blots != BLOTS_Hidden)\n        fcanRotate = false;\n\n    // Rotate the selected powerup flags if allowed to and L2/R2 pressed.\n    if (fcanRotate && JOY_BUTTON_PRESSED(pjoy, PAD_L2|PAD_R2))\n    {\n        FSP newFsp = (FSP)IRotatePowerUp(pjoy, (int)g_fsp, (int)FSP_Max, s_mpfspgrfvault);\n        g_pgsCur->fspLast = FSP_Nil;\n        SetFsp(newFsp);\n    }\n\n    // Powerup activation logic (how the sausage is actually made).\n    switch (g_fsp)\n    {\n    case FSP_Ball:\n        if (pjt->jts > JTS_Nil && pjt->jts < (JTS)3\n            && JOY_BUTTON_PRESSED(pjoy, PAD_TRIANGLE))\n        {\n            SetJoyBtnHandled(pjoy, PAD_TRIANGLE);\n\n            // Two different animations based on 0x690 offset(?).\n            if (STRUCT_OFFSET(g_pjt, 0x690, float) = 0.0f)\n            {\n                SetJtJts(pjt, (JTS)13, (JTBS)0x36);\n            }\n            else\n            {\n                SetJtJts(pjt, (JTS)13, (JTBS)0x37);\n            }\n        }\n        break;\n    case FSP_SlowDownClock:\n        if (g_grfusr & (FUSR_Menu|FUSR_HandsOff) == 0)\n        {\n            if (D_00270458 == 3)\n            {\n                // LAB_001d2ef0:\n                STRUCT_OFFSET(pjt, 0x2744, float) = 0.0f;\n            }\n            else if (pjt->jts == (JTS)2)\n            {\n                if (JOY_BUTTON_PRESSED(pjoy, PAD_TRIANGLE))\n                {\n                    SetJoyBtnHandled(pjoy, PAD_TRIANGLE);\n                    // goto lab_001d2ee8;\n                }\n            }\n            else if (pjoy->grfbtn & 0x10 == 0)\n            {\n                STRUCT_OFFSET(pjt, 0x2744, int) = 0;\n            }\n            else\n            {\n                GRFVAULT grfvault = GetGrfvault_unknown();\n                if ((grfvault & 0x1000) == 0)\n                {\n                    // goto LAB_001d2ef0;\n                    // LAB_001d2ee8:\n                    STRUCT_OFFSET(pjt, 0x2744, int) = 1;\n                }\n            }\n        }\n        else\n        {\n            STRUCT_OFFSET(pjt, 0x2744, int) = 0;\n        }\n\n        if (STRUCT_OFFSET(pjt, 0x2744, int) == 0)\n        {\n            g_rtClockPowerUp = 1.0f;\n        }\n        else\n        {\n            g_rtClockPowerUp = RT_JtSlowDownClock;\n        }\n        break;\n    case FSP_Mine:\n        if (pjt->jts < (JTS)2\n            && JOY_BUTTON_PRESSED(pjoy, PAD_TRIANGLE)\n            && STRUCT_OFFSET(pjt, 0x1518, LO *) != NULL)\n        {\n            SetJoyBtnHandled(pjoy, PAD_TRIANGLE);\n            LO *ploMine = STRUCT_OFFSET(pjt, 0x1518, LO *);\n            if (FIsLoInWorld(ploMine))\n            {\n                // Compute vector from JT pos to mine\n                VECTOR posMine = ploMine->pos;\n                VECTOR posJt = pjt->pos;\n                VECTOR3 dir = RadNormalize(posMine - posJt);\n                float angle = atan2f(dir.y, dir.x);\n                STRUCT_OFFSET(pjt, 0x01010, float) = angle;\n                // FUN_001c5d58(pjt) // Spawns the mine?\n                SetJtJts(pjt, (JTS)0x10, (JTBS)0x3a);\n            }\n            else\n            {\n                SetJtJts(pjt, (JTS)0x10, (JTBS)0x39);\n            }\n        }\n        break;\n    case FSP_SpeedUpClock:\n        if (D_00270458 == 3)\n        {\n            STRUCT_OFFSET(pjt, 0x2748, float) = 0.0f;\n        }\n        else if (pjoy->grfbtn & 0x10 == 0)\n        {\n            STRUCT_OFFSET(pjt, 0x2748, float) = GSmooth(STRUCT_OFFSET(pjt, 0x2748, float), 0.0f, g_clock.dtReal, &SMP_00274f78, 0);\n        }\n        break;\n    case FSP_Decoy:\n        if (pjt->jts < (JTS)2\n            && JOY_BUTTON_PRESSED(pjoy, PAD_TRIANGLE)\n            && STRUCT_OFFSET(pjt, 0x2750, float) != 0.0f)\n        {\n             SetJoyBtnHandled(pjoy, PAD_TRIANGLE);\n             SetJtJts(pjt, (JTS)0xE, JTBS_Nil);\n        }\n        break;\n    case FSP_Stun:\n        int stunVar;\n        if (pjt->jts < (JTS)2)\n        {\n            if (JOY_BUTTON_PRESSED(pjoy, PAD_TRIANGLE))\n            {\n                SetJoyBtnHandled(pjoy, PAD_TRIANGLE);\n                SetJtJts(pjt, (JTS)0xf, JTBS_Nil);\n            }\n            stunVar = STRUCT_OFFSET(pjt, 0x275c, int);\n        }\n        else\n        {\n            stunVar = STRUCT_OFFSET(pjt, 0x275c, int);\n        }\n\n        if (stunVar && (3.0 < g_clock.t - STRUCT_OFFSET(pjt, 0x2758, float)))\n        {\n            // FUN_002d31d0(pjt, 0);\n        }\n        break;\n    default:\n        break;\n    }\n}\n    */\n// #endif\n\nint IRotatePowerUp(JOY *pjoy, int iCur, int iMax, int *mpigrfvault)\n{\n    // If L2 or R2 not pressed, powerup is unchanged.\n    if ((pjoy->grfbtnPressed & (PAD_L2 | PAD_R2)) == _NOT_PRESSED)\n    {\n        return iCur;\n    }\n\n    // Default to next powerup (assume R2 pressed).\n    int direction = 1;\n    if ((pjoy->grfbtnPressed & PAD_L2) != _NOT_PRESSED)\n    {\n        // L2 pressed, previous powerup.\n        direction = -1;\n    }\n\n    SetJoyBtnHandled(pjoy, (ushort)(PAD_L2 | PAD_R2));\n\n    uint grfValue;\n    int iNew = iCur;\n    int attemptsLeft = iMax;\n    do\n    {\n        attemptsLeft--;\n        iNew += direction;\n        if (attemptsLeft < 0)\n        {\n            return iCur;\n        }\n        if (iNew < 0)\n        {\n            iNew = iMax - 1;\n        }\n        else if (iMax <= iNew)\n        {\n            iNew = 0;\n        }\n        grfValue = GetGrfvault_unknown();\n    } while ((grfValue & mpigrfvault[iNew]) == 0);\n\n    // Return the new powerup index.\n    return iNew;\n}\n"
  },
  {
    "path": "src/P2/steprail.c",
    "content": "#include <steprail.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprail\", func_001D31D0__FP2LOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprail\", post_load_steprail);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprail\", func_001D32D8__FiP2JTl);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprail\", update_steprail);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprail\", preset_steprail_accel);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprail\", FUN_001d34e0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprail\", FUN_001d3500);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprail\", FUN_001d35a8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprail\", update_steprail_message);\n"
  },
  {
    "path": "src/P2/steprun.c",
    "content": "#include <steprun.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprun\", PostStepLoadRun__FP4STEPP5BLRUNPP6ASEGBL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprun\", CalculateBlrunV__FiP5BLRUNP4MRSGP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprun\", ProjectStepRunPlant__FP4STEPP5BLRUNffiiP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprun\", FIntersectStepRunPlant__FP4STEPP6VECTORT1Pf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprun\", FReblendAbl2D__FiiiP2BLe);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprun\", AdjustStepRun__FP4STEPP5BLRUNP6ASEGBLP5ASEGA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/steprun\", SetStepRunTarget__FP4STEPffP5BLRUNP6ASEGBL);\n"
  },
  {
    "path": "src/P2/stepside.c",
    "content": "#include <stepside.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepside\", PostJtLoadSidestep__FP2JTP4BLSSPP6ASEGBL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepside\", AdjustJtSidestep__FP2JTP4BLSSP6ASEGBL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stepside\", SetJtSidestepTarget__FP2JTP4BLSSP6ASEGBLff);\n"
  },
  {
    "path": "src/P2/stream.c",
    "content": "#include <stream.h>\n\nOSTRM::OSTRM(int fd)\n{\n    m_fd = fd;\n    m_abDest = 0;\n    m_cbDest = 0;\n    m_ibCur = 0;\n    m_cbWritten = 0;\n    m_cbBuffered = 0;\n}\n\nOSTRM::OSTRM(void *abDest, int cbDest)\n{\n    m_abDest = (uchar *)abDest;\n    m_cbDest = cbDest;\n    m_fd = -1;\n    m_ibCur = 0;\n    m_cbWritten = 0;\n    m_cbBuffered = 0;\n}\n\nOSTRM::~OSTRM()\n{\n    Flush();\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stream\", CbWrite__5OSTRMPvi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/stream\", Flush__5OSTRM);\n"
  },
  {
    "path": "src/P2/suv.c",
    "content": "#include <suv.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", InitSuv__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", PostSuvLoad__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", PresetSuvAccel__FP3SUVf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", GExcludeAlm__FiP2LMf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvBalance__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", DsGetTrackRelative__Ffff);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", FIsSuvAheadOf__FP3SUVT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvLine__FP3SUVPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvHeading__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvWheels__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvExpls__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", BoostSuv__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", FUN_001d9338);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvVolumes__FP3SUVi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvSounds__FP3SUVf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvPuncher__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuv__FP3SUVf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvActive__FP3SUVP3JOYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", FUN_001da170);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvInternalXps__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", AddSuvCustomXps__FP3SUVP2SOiP3BSPT3PP2XP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", AdjustSuvNewXp__FP3SUVP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvInfluences__FP3SUVP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", RenderSuvSelf__FP3SUVP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvBounds__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", CollectSuvPrize__FP3SUV3PCKP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvShapes__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", UpdateSuvXfWorld__FP3SUV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", GetSuvCpdefi__FP3SUVfP6CPDEFI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", OnSuvActive__FP3SUViP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", HandleSuvMessage__FP3SUV5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", SetSuvTrack__FP3SUVP5SHAPE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", SetSuvLine__FP3SUVP5SHAPE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", AddSuvCheckPoint__FP3SUVP3VOL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", AddSuvFeature__FP3SUVP3VOLffP4EXPLT4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", SetSuvSuvs__FP3SUV4SUVS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", ResetSuv__FP3SUV);\n\nJUNK_ADDIU(10);\nJUNK_WORD(0x7C450000);\nJUNK_WORD(0x48220800);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/suv\", VecCombo__FG8VU_FLOATG9VU_VECTORT0T1);\n"
  },
  {
    "path": "src/P2/sw.c",
    "content": "#include <sw.h>\n#include <ui.h>\n#include <frm.h>\n#include <util.h>\n#include <sound.h>\n#include <dialog.h>\n#include <989snd.h>\n#include <sce/memset.h>\n\nextern SW *g_psw;\nextern int g_fLoadDebugInfo;\nextern byte *g_pbBulkData;\nextern int g_fLoadBulkData;\nextern int g_cbBulkData;\nextern int g_nBulkDataSig;\nextern int g_cbBulkDataReadAdjustment;\n\nvoid InitSwDlHash(SW *psw)\n{\n    DL *pdl = psw->adlHash;\n\n    for (uint i = 0; i < 512; i++)\n    {\n        InitDl(pdl, sizeof(DL));\n        pdl++;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", InitSw__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", DeleteSw__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", SetupBulkDataFromBrx__FiP18CBinaryInputStream);\n\nvoid LoadBulkDataFromBrx(CBinaryInputStream *pbis)\n{\n    if (g_fLoadBulkData)\n    {\n        g_cbBulkDataReadAdjustment = pbis->m_cbRemaining;\n        pbis->Align(16);\n        pbis->Read(g_cbBulkData, g_pbBulkData);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", SetSwGravity__FP2SWf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dbac0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dbae0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dbb00);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FOverflowSwLo__FP2SWP2LOi);\n\nXA *PxaAllocSw(SW *psw)\n{\n    XA *pxa = (XA *)PvAllocSlotheapImpl(&psw->slotheapXa);\n    memset(pxa, 0, sizeof(XA));\n    return pxa;\n}\n\nvoid FreeSwXaList(SW *psw, XA *pxaFirst)\n{\n    while (pxaFirst)\n    {\n        XA *pxa = pxaFirst->pxaNextTarget;\n        FreeSlotheapPv(&psw->slotheapXa, pxaFirst);\n        pxaFirst = pxa;\n    }\n}\n\nMQ *PmqAllocSw(SW *psw)\n{\n    MQ *pmq = (MQ *)PvAllocSlotheapImpl(&psw->slotheapMq);\n    memset(pmq, 0, sizeof(MQ));\n    return pmq;\n}\n\nvoid FreeSwMqList(SW *psw, MQ *pmqFirst)\n{\n    while (pmqFirst)\n    {\n        MQ *pmq = pmqFirst->pmqNext;\n        FreeSlotheapPv(&psw->slotheapMq, pmqFirst);\n        pmqFirst = pmq;\n    }\n}\n\nvoid EnsureSwCallback(SW *psw, PFNMQ pfnmq, void *pvContext, MSGID msgid, void *pvCallbackData)\n{\n    MQ *pmq = psw->pmqCallbackFirst;\n\n    while (pmq)\n    {\n        if (pmq->pfnmq == pfnmq && pmq->pvContext == pvContext &&\n            pmq->msgid == msgid && pmq->pvCallbackData == pvCallbackData)\n        {\n            return;\n        }\n\n        pmq = pmq->pmqNext;\n    }\n\n    PostSwCallback(psw, pfnmq, pvContext, msgid, pvCallbackData);\n}\n\nvoid PostSwCallback(SW *psw, PFNMQ pfnmq, void *pvContext, MSGID msgid, void *pvCallbackData)\n{\n    MQ *pmq = PmqAllocSw(psw);\n    pmq->pfnmq = pfnmq;\n    pmq->pvContext = pvContext;\n    pmq->msgid = msgid;\n    pmq->pvCallbackData = pvCallbackData;\n\n    if (psw->pmqCallbackLast)\n    {\n        psw->pmqCallbackLast->pmqNext = pmq;\n    }\n    else\n    {\n        psw->pmqCallbackFirst = pmq;\n    }\n\n    psw->pmqCallbackLast = pmq;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", ClearSwCallbacks__FP2SWiPFPv5MSGIDPv_vPv5MSGIDT3);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", ProcessSwCallbacks__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", ProcessSwSpliceScheduledCallbacks__FP2SWf);\n\nSTSO *PstsoAllocSw(SW *psw)\n{\n    STSO *pstso = (STSO *)PvAllocSlotheapImpl(&psw->slotheapStso);\n    memset(pstso, 0, sizeof(STSO));\n    return pstso;\n}\n\nvoid FreeSwStsoList(SW *psw, STSO *pstsoFirst)\n{\n    while (pstsoFirst)\n    {\n        STSO *pstso = pstsoFirst->pstsoNext;\n        FreeSlotheapPv(&psw->slotheapStso, pstsoFirst);\n        pstsoFirst = pstso;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", AddSwProxySource__FP2SWP2LOi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", PloGetSwProxySource__FP2SWi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", IntersectSwBoundingBox__FP2SWP2SOP6VECTORT2PFPvP2SO_iPvPiPPP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", IntersectSwBoundingSphere__FP2SWP2SOP6VECTORfPFPvP2SO_iPvPiPPP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", RemoveOxa__FP3OXAPP3OXA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", InitSwAoxa__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", AddOxa__FP3OXAPP3OXA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", PoxaAllocSw__FP2SWP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FreeSwPoxa__FP2SWP3OXA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", CreateSwDefaultLights__FP2SW);\n\n/**\n * @todo Rename.\n */\nvoid FUN_001dccc0(CBinaryInputStream *pbis)\n{\n    int count = pbis->U32Read();\n    \n    if (g_fLoadDebugInfo == 0)\n        return;\n\n    for (int i = 1; i < count; i++)\n    {\n        pbis->Unknown1();\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", CreateSwPrizes__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", LoadSwFromBrx__FP2SWP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FClipLineHomogeneous__FP7VECTOR4);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", DrawLineWorld__FP6VECTORT0G4RGBAP2CMi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", DrawAxesWorld__FP6VECTORP7MATRIX3fP2CMi);\n\nvoid SetSwIllum(SW *psw, float uMidtone)\n{\n    psw->lsmDefault.uMidtone = uMidtone;\n    g_cframeStaticLightsInvalid = g_cframe;\n}\n\nvoid SetSwIllumShadow(SW *psw, float uShadow)\n{\n    psw->lsmDefault.uShadow = uShadow;\n    g_cframeStaticLightsInvalid = g_cframe;\n}\n\nvoid SetSwExcitement(SW *psw, float gexcMenu)\n{\n    psw->gexcMenu = gexcMenu;\n    g_iexcHyst = -100;\n    SetMvgkRvol(7, MVGK_Music, 1.0f);\n    snd_SetGlobalExcite((int)(psw->gexcMenu + 0.5f));\n}\n\nint FLevelSwVisited(SW *psw, WID wid)\n{\n    return GrflsFromWid(wid) & 1;\n}\n\nint FLevelSwPrimary(SW *psw, WID wid)\n{\n    return GrflsFromWid(wid) & 2;\n}\n\nint FLevelSwSecondary(SW *psw, WID wid)\n{\n    return GrflsFromWid(wid) & 4;\n}\n\nint FLevelSwTertiary(SW *psw, WID wid)\n{\n    return GrflsFromWid(wid) & 8;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd710);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd758);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd7a0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd7e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd888);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd8e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd908);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd928);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd950);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd9a0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001dd9c0);\n\nvoid SetSwPlayerSuck(SW *psw, float uSuck)\n{\n    g_plsCur->unk_suck_0x10 = GLimitLm(&g_lmZeroOne, uSuck);\n}\n\nvoid GetSwPlayerSuck(SW *psw, float *puSuck)\n{\n    // TODO: This should be \"uSuck\"?\n    *puSuck = g_plsCur->unk_suck_0x10;\n}\n\nvoid IncrementSwHandsOff(SW *psw)\n{\n    if (++psw->cHandsOff == 1)\n    {\n        AddGrfusr(2);\n    }\n}\n\nvoid DecrementSwHandsOff(SW *psw)\n{\n    if (psw->cHandsOff-- == 1)\n    {\n        RemoveGrfusr(2);\n    }\n}\n\nint IsSwHandsOff(SW *psw)\n{\n    return psw->cHandsOff > 0;\n}\n\nvoid IsSwVagPlaying(SW *psw, int *pfPlaying)\n{\n    *pfPlaying = FVagPlaying();\n}\n\nvoid SetSwDarken(SW *psw, float rDarken)\n{\n    psw->rDarkenSmooth = rDarken;\n    psw->rDarken = rDarken;\n}\n\nvoid SetSwDarkenSmooth(SW *psw, float rDarkenSmooth)\n{\n    psw->rDarkenSmooth = rDarkenSmooth;\n}\n\nvoid CancelSwDialogPlaying(SW *psw)\n{\n    if (g_pdialogPlaying && STRUCT_OFFSET(g_pdialogPlaying, 0x2d4, DIALOGS) != 4 &&\n       (STRUCT_OFFSET(g_pdialogPlaying, 0x2d0, DIALOGK) - 1u) < 2)\n    {\n        PopUiActiveBlot(&g_ui);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddb20);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddb58);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddbb8);\nJUNK_WORD(0x0002102a);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddbf8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddc18);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddc38);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddc40);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddc78);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddc90);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddcb0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/sw\", FUN_001ddcc8);\n"
  },
  {
    "path": "src/P2/tail.c",
    "content": "#include <tail.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tail\", InitTail__FP4TAIL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tail\", PostTailLoad__FP4TAIL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tail\", UpdateTailConstraints__FP4TAIL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tail\", MatchTailOtherObject__FP4TAILP3ALO);\n"
  },
  {
    "path": "src/P2/tank.c",
    "content": "#include <tank.h>\n#include <po.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", InitTank__FP4TANK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", PostTankLoad__FP4TANK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", UpdateTank__FP4TANKf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", FUN_001deb30);\n\nvoid UseTankCharm(TANK *ptank)\n{\n    UsePoCharm(ptank);\n    SetTankTanks(ptank, TANKS_Active);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", UpdateTankActive__FP4TANKP3JOYf);\n\nvoid OnTankActive(TANK *ptank, int fActive, PO *ppoOther)\n{\n    OnPoActive(ptank, fActive, ppoOther);\n    if (!fActive)\n    {\n        STRUCT_OFFSET(ptank, 0x728, int) = 0; // ptank->fFlash\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", RenderTankAll__FP4TANKP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", ImpactTank__FP4TANKi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", FInvulnerableTank__FP4TANK3ZPK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", ApplyTankThrow__FP4TANKP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", FTakeTankDamage__FP4TANKP3ZPR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", FUN_001dfa10);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", AdjustTankNewXp__FP4TANKP2XPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", HandleTankMessage__FP4TANK5MSGIDPv);\n\nJTHS JthsCurrentTank(TANK *ptank)\n{\n    return (JTHS)(STRUCT_OFFSET(ptank, 0x728, int) != 0); // ptank->fFlash\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tank\", SetTankTanks__FP4TANK5TANKS);\n"
  },
  {
    "path": "src/P2/target.c",
    "content": "#include <target.h>\n\nextern DL g_dlTarget;\n\nvoid StartupTarget()\n{\n    InitDl(&g_dlTarget, 0x80);\n}\n\nvoid ResetTargetList()\n{\n    ClearDl(&g_dlTarget);\n}\n\nvoid InitTarget(TARGET *ptarget)\n{\n    InitXfm(ptarget);\n    STRUCT_OFFSET(ptarget, 0x88, int) = 0x1e; // ptarget->grftak\n    STRUCT_OFFSET(ptarget, 0x8c, float) = 25.0f; // ptarget->sRadiusTarget\n}\n\nvoid OnTargetAdd(TARGET *ptarget)\n{\n    OnLoAdd(ptarget);\n    AppendDlEntry(&g_dlTarget, ptarget);\n}\n\nvoid OnTargetRemove(TARGET *ptarget)\n{\n    OnLoRemove(ptarget);\n    RemoveDlEntry(&g_dlTarget, ptarget);\n}\n\nvoid CloneTarget(TARGET *ptarget, TARGET *ptargetBase)\n{\n    DLE dleTarget = STRUCT_OFFSET(ptarget, 0x80, DLE); // ptarget->dleTarget\n    CloneLo(ptarget, ptargetBase);\n    STRUCT_OFFSET(ptarget, 0x80, DLE) = dleTarget; // ptarget->dleTarget\n}\n"
  },
  {
    "path": "src/P2/text.c",
    "content": "#include <text.h>\n#include <memory.h>\n#include <stdarg.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", CchParsePchzInt__FPcPi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", CchParsePchzTft__FPcP3TFTPPc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", WriteTftPchz__FP3TFTP5OSTRMPc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", FNegTftUl__FP3TFTP2UL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", UnRadixFromChConversion__Fc);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", CchAchFromUl__FPciUlUi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", WriteTftUl__FP3TFTP5OSTRMUl);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", ExpFirstFromG__Fd);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", ChDigitFromG__Fdii);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", CchAchFromDouble__FPciP3TFTd);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", WriteTftDouble__FP3TFTP5OSTRMd);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", WriteTft__FP3TFTP5OSTRMPPcPci);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", CchOstrmPrintf__FP5OSTRMPcT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", vprintf);\n\nextern \"C\" int printf(char *pchzFormat, ...)\n{\n    va_list arg;\n    va_start(arg, pchzFormat);\n    int ret = vprintf(pchzFormat, arg);\n    va_end(arg);\n    return ret;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", vsprintf);\n\nextern \"C\" int sprintf(char *pchzDest, char *pchzFormat, ...)\n{\n    va_list arg;\n    va_start(arg, pchzFormat);\n    int ret = vsprintf(pchzDest, pchzFormat, arg);\n    va_end(arg);\n    return ret;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", _vsnprintf);\n\nJUNK_ADDIU(10);\n\nint _snprintf(char *pchzDest, int cchDest, char *pchzFormat, ...)\n{\n    va_list arg;\n    va_start(arg, pchzFormat);\n    int ret = _vsnprintf(pchzDest, cchDest, pchzFormat, arg);\n    va_end(arg);\n    return ret;\n}\n\nJUNK_WORD(0x27BD0450);\n\nextern \"C\" uint strlen(const char *pchz)\n{\n    uint len = 0;\n\n    while (*pchz != '\\0')\n    {\n        pchz++;\n        len++;\n    }\n\n    return len;\n}\n\nextern \"C\" char *strcpy(char *pchzDst, const char *pchzSrc)\n{\n    CopyAb(pchzDst, (char *)pchzSrc, strlen(pchzSrc) + 1);\n    return pchzDst;\n}\n\nextern \"C\" char *strcpy1(char *pchzDst, char *pchzSrc)\n{\n    uint dstLength = strlen(pchzDst);\n    uint srcLength = strlen(pchzSrc);\n    CopyAb(pchzDst + dstLength, pchzSrc, srcLength + 1);\n    return pchzDst;\n}\n\nextern \"C\" char *strchr(char *pchz, int ch)\n{\n    while (*pchz != '\\0')\n    {\n        if (*pchz == ch)\n        {\n            return pchz;\n        }\n        pchz++;\n    }\n    return NULL;\n}\n\nJUNK_NOP();\nJUNK_ADDIU(30);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/text\", UpperizePchz__FPc);\n"
  },
  {
    "path": "src/P2/thread.c",
    "content": "#include <sdk/ee/eekernel.h>\n#include <sce/memset.h>\n#include <thread.h>\n#include <frm.h>\n\nint SemaCreate(int initCount, int maxCount)\n{\n    SemaParam sp;\n\n    memset(&sp, 0, sizeof(SemaParam));\n    sp.initCount = initCount;\n    sp.maxCount = maxCount;\n    return CreateSema(&sp);\n}\n\nJUNK_NOP();\nJUNK_ADDIU(50);\n\nvoid InitCritSect(CRITSECT *pcritsect)\n{\n    pcritsect->thread = -1;\n    pcritsect->sema = SemaCreate(1, 1);\n}\n\nvoid EnterCritSect(CRITSECT *pcritsect)\n{\n    int threadId = GetThreadId();\n\n    if (threadId != pcritsect->thread)\n    {\n        WaitSema(pcritsect->sema);\n        pcritsect->thread = threadId;\n        pcritsect->cEnter = 1;\n    }\n    else\n    {\n        pcritsect->cEnter++;\n    }\n}\n\nvoid LeaveCritSect(CRITSECT *pcritsect)\n{\n    int critSects = pcritsect->cEnter - 1;\n    pcritsect->cEnter = critSects;\n\n    if (critSects == 0) {\n        pcritsect->thread = -1;\n        SignalSema(pcritsect->sema);\n    }\n}\n\nJUNK_ADDIU(30);\n\nvoid StartupThread()\n{\n    ThreadParam tp;\n\n    g_athread.cEnter = GetThreadId();\n    ChangeThreadPriority(g_athread.cEnter, 4);\n    memset(&tp, 0, sizeof(ThreadParam));\n\n    tp.stackSize = 0x20000;\n    tp.stack = g_abRenderLoopStack;\n    tp.initPriority = 2;\n    tp.gpReg = &_gpReg;\n    tp.entry = FrameRenderLoop;\n\n    g_athread.thread = CreateThread(&tp);\n}\n"
  },
  {
    "path": "src/P2/tn.c",
    "content": "#include <tn.h>\n#include <sw.h>\n#include <freeze.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", PtnfnFromTn__FP2TN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", GetTnfnNose__FP4TNFNP6CPDEFIP6VECTORP2TN);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", InitTn__FP2TN);\n\nvoid OnTnRemove(TN *ptn)\n{\n    OnAloRemove(ptn);\n    SetTnTns(ptn, TNS_Out);\n    ClearSwCallbacks(ptn->psw, 2, NULL, ptn, MSGID_Nil, NULL);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", LoadTnFromBrx__FP2TNP18CBinaryInputStream);\n\nvoid PostTnLoad(TN *ptn)\n{\n    PostAloLoad(ptn);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", SetTnTns__FP2TN3TNS);\n\n/**\n * @todo Rename.\n */\nvoid FUN_001e2840(TN *ptn, TNS tns)\n{\n    // NOTE: Doesn't match if this is the other way around.\n    if (tns == STRUCT_OFFSET(ptn, 0x398, TNS))\n    {\n        return;\n    }\n\n    STRUCT_OFFSET(ptn, 0x398, TNS) = tns;\n    UpdateTnCallback(ptn, MSGID_callback, NULL);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", UpdateTnCallback__FP2TN5MSGIDPv);\n\nvoid UpdateTn(TN *ptn, float dt)\n{\n    UpdateAlo(ptn, dt);\n    if (STRUCT_OFFSET(ptn, 0x398, TNS) != TNS_Out) // ptn->tns\n    {\n        PostSwCallback(ptn->psw, UpdateTnCallback, ptn, MSGID_callback, NULL);\n    }\n}\n\nvoid RenderTnSelf(TN *ptn, CM *pcm, RO *pro)\n{\n    RenderAloSelf(ptn, pcm, pro);\n}\n\nvoid FreezeTn(TN *ptn, int fFreeze)\n{\n    FreezeAlo(ptn, fFreeze);\n    if (fFreeze)\n    {\n        SetTnTns(ptn, TNS_Out);\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", FUN_001e29e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", CalculateTnCrv__FP2TNP6VECTORN21);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", CalculateTnPos__FP2TNP6VECTORffP3CLQP2LM4FTNDT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", ActivateCptn__FP4CPTNPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", DeactivateCptn__FP4CPTNPv);\n\nvoid SetCptn(CPTN *pcptn, void *pv)\n{\n    return;\n}\n\nvoid RevokeCptn(CPTN *pcptn, void *pv)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", FUN_001e30e8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", UpdateCptn__FP4CPTNP6CPDEFIP3JOYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", FUN_001e4578);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", FUN_001e4880);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", FUN_001e4888);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", LoadTbspFromBrx__FP18CBinaryInputStreamPiPP5TSURFT1PP4TBSP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tn\", FCheckTbspPoint__FP4TBSPP6VECTOR);\n"
  },
  {
    "path": "src/P2/transition.c",
    "content": "#include <sce/memset.h>\n#include <transition.h>\n#include <chkpnt.h>\n#include <phasemem.h>\n#include <sw.h>\n#include <joy.h>\n#include <brx.h>\n#include <sound.h>\n\nCTransition::CTransition()\n{\n    m_pchzWorld = NULL;\n    grftrans = FTRANS_None;\n    m_oidWarp = OID_Nil;\n    m_oidWarpContext = OID_Nil;\n    memset(m_achzWorldCur, 0, 0x20);\n}\n\nvoid CTransition::Set(char *pchzWorld, OID oidWarp, OID oidWarpContext, GRFTRANS grftrans)\n{\n    if (m_fPending == false)\n    {\n        this->m_fPending = true;\n        this->m_pchzWorld = pchzWorld;\n        this->m_oidWarp = oidWarp;\n        this->m_oidWarpContext = oidWarpContext;\n        this->grftrans = grftrans;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/transition\", Execute__11CTransition);\n#ifdef SKIP_ASM\n/**\n * @todo 15.60% matched.\n *\n * Some functions called in this function are not implemented yet.\n */\nvoid CTransition::Execute()\n{\n    CFileLocation fileLocation;\n    LevelTableStruct levelInfo = {};\n\n    SetPhase(PHASE_Load);\n    // func_0018d410();\n\n    if (levelInfo.fileLocation.m_fcl.cb != 0)\n    {\n        // fileLocation.Clear();\n\n        // Decrypting the sector offsets and file size\n        uint cb = levelInfo.fileLocation.m_fcl.cb ^ levelInfo.level_name;\n        uint isector = levelInfo.fileLocation.m_fcl.isector ^ levelInfo.for_size;\n        fileLocation.m_fcl.cb = cb;\n        fileLocation.m_fcl.isector = isector;\n\n        // Set up progress bar (temp, this was copied from Startup)\n        int nRemain = cb;\n        int rgbaComplete = 0x007f0000; // blue\n        int rgbaRemain = 0x003f3f3f; // gray\n        int rgbaWarning = 0x00003f3f; // yellow\n        int rgbaTrouble = 0x0000003f; // red\n        CProg prog = CProg((RGBA *)&rgbaComplete, (RGBA *)&rgbaRemain, (RGBA *)&rgbaWarning, (RGBA *)&rgbaTrouble);\n\n        if (cb == 0)\n        {\n            MvgkUnknown1(MVGK_Music);\n            SetMvgkRvol(0, MVGK_Music, 1.0f);\n            ClearPhase(PHASE_None);\n            levelInfo.fileLocation.m_fcl.isector = 0;\n            return;\n        }\n\n        DeleteSw(g_psw);\n        g_psw = 0;\n        // SetupBulkDataFromBrx()\n        ResetClock(&g_clock, 0.0);\n        AddGrfusr(0x80);\n        // SetupGame(levelInfo.level_id);\n        g_psw = (SW *)PloNew(CID_SW, 0, 0, OID__WORLD, -1);\n    }\n}\n#endif // SKIP_ASM\n\nvoid ResetWorld(FTRANS ftrans)\n{\n    SetMvgkUvol(0.0f);\n\n    GRFTRANS grftrans;\n    switch (ftrans)\n    {\n    case FTRANS_None:\n        grftrans = FTRANS_None;\n        break;\n    case FTRANS_Checkpoint:\n        ReturnChkmgrToCheckpoint(&g_chkmgr);\n        return;\n    case FTRANS_RetryWorld:\n        grftrans = FTRANS_RetryWorld;\n        break;\n    case (FTRANS_Checkpoint | FTRANS_RetryWorld):\n        // Transitions with the Sly Cooper logo wipe\n        grftrans = 4;\n        break;\n    }\n\n    g_transition.Set(g_transition.m_achzWorldCur, OID_Nil, OID_Nil, grftrans);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/transition\", transition__static_initialization_and_destruction_0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/transition\", _GLOBAL_$I$g_transition);\n"
  },
  {
    "path": "src/P2/turret.c",
    "content": "#include <turret.h>\n#include <dialog.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", InitTurret__FP6TURRET);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", FUN_001e53f8);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", PostTurretLoad__FP6TURRET);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", UpdateTurret__FP6TURRETf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", UpdateTurretActive__FP6TURRETP3JOYf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", OnTurretActive__FP6TURRETiP2PO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", FFilterTurret__FP6TURRETP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", UpdateTurretAim__FP6TURRET);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", FireTurret__FP6TURRET);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", HandleTurretMessage__FP6TURRET5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", FIgnoreTurretIntersection__FP6TURRETP2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", CollectTurretPrize__FP6TURRET3PCKP3ALO);\n\nvoid GetTurretDiapi(TURRET *pturret, DIALOG *pdialog, DIAPI *pdiapi)\n{\n    pdiapi->fCallable = 0;\n    pdiapi->fPlayable = 0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/turret\", FUN_001e5e60);\n"
  },
  {
    "path": "src/P2/tv.c",
    "content": "#include <tv.h>\n#include <clock.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", InitTv__FP2TV5BLOTK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", PostTvLoad__FP2TV);\n\nvoid GetTvItvbMinMax(TV *ptv, int *pitvbDrawMin, int *pitvbDrawMax)\n{\n    // ptv->uUnwind\n    int max = (int)(STRUCT_OFFSET(ptv, 0xc70, float) * 57.0f);\n    *pitvbDrawMin = (0x39 - max) / 2;\n    *pitvbDrawMax = *pitvbDrawMin + max;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", DrawTvArea__FP2TVR4GIFSi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", DrawTvBands__FP2TVR4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", DrawTvOutline__FP2TVR4GIFS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", DrawTv__FP2TV);\n\nvoid SetTvTvs(TV *ptv, TVS tvs)\n{\n    // ptv->tvs\n    if (tvs == STRUCT_OFFSET(ptv, 0x260, TVS))\n    {\n        return;\n    }\n\n    STRUCT_OFFSET(ptv, 0x260, TVS) = tvs; // ptv->tvs\n    STRUCT_OFFSET(ptv, 0x264, float) = g_clock.tReal; // ptv->tTvs\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", AcceptTvSpeaker__FP2TV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", SetTvTvgs__FP2TV4TVGS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", SetTvBlots__FP2TV5BLOTS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", UpdateTv__FP2TV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", RenderTv__FP2TV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", PreTvContext__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", PostTvContext__FP3RPL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", SetTvSpeaker__FP2TVP7SPEAKER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", SetTvReplace__FP2TVP3ALO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", OnTvReset__FP2TV);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", tv__static_initialization_and_destruction_0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/tv\", _GLOBAL_$I$RGBA_Distortion);\n"
  },
  {
    "path": "src/P2/ub.c",
    "content": "#include <ub.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ub\", InitUbg__FP3UBG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ub\", PostUbgLoad__FP3UBG);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ub\", PsoPadUbgClosest__FP3UBGP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ub\", OnUbgEnteringSgs__FP3UBG3SGSP4ASEG);\n\nSGS SgsNextUbgAI(UBG *pubg)\n{\n    if (STRUCT_OFFSET(pubg, 0xc5c, SGS) < 1) // pubg->cJump\n    {\n        STRUCT_OFFSET(pubg, 0xbfc, float) = 3.4028235e+38f; // pubg->tTaunt\n    }\n\n    SGS sgs = STRUCT_OFFSET(pubg, 0x724, SGS); // pubg->sgs\n    if (sgs == SGS_Taunt)\n    {\n        if (!STRUCT_OFFSET(pubg, 0x7e0, ASEGA *)) // pubg->pasegaSgs\n        {\n            sgs = SGS_LostPlayer;\n        }\n    }\n    else\n    {\n        sgs = SgsNextStepguardAI(pubg);\n    }\n\n    return sgs;\n}\n\nint FDetectUbg(UBG *pubg)\n{\n    // pubg->fAbandonExternal\n    if (STRUCT_OFFSET(pubg, 0xc40, int) != 0)\n        return 0;\n\n    // pubg->cJump\n    return (STRUCT_OFFSET(pubg, 0xc5c, int)) != 0;\n}\n\nint FCanUbgAttack(UBG *pubg)\n{\n    // pubg->oidPatrolGoal\n    if(STRUCT_OFFSET(pubg, 0xc58, OID) != OID_state_ubb_round_3)\n        return 0;\n\n    // pubg->cJump\n    if(STRUCT_OFFSET(pubg, 0xc5c, int) == 5 || STRUCT_OFFSET(pubg, 0xc5c, int) == 0)\n        return 0;\n\n    return 1;\n}\n\nvoid DoUbgFreefallJump(UBG *pubg)\n{\n    // pubg->oidPatrolGoal\n    if (STRUCT_OFFSET(pubg, 0xc58, OID) != OID_state_ubb_round_2)\n    {\n        // pubg->cJump\n        int cJump = STRUCT_OFFSET(pubg, 0xc5c, int) - 1;\n        if (cJump < 1) cJump = 0;\n        STRUCT_OFFSET(pubg, 0xc5c, int) = cJump;\n    }\n\n    DoStepguardFreefallJump(pubg);\n}\n\n/**\n * @todo 100% match. Check if cleanup possible.\n */\nvoid DoUbgFreefallLanding(UBG *pubg)\n{\n    // pubg->oidPatrolGoal & pubg->sgs\n    if (STRUCT_OFFSET(pubg, 0xc58, OID) == OID_state_ubb_round_2 &&\n        STRUCT_OFFSET(pubg, 0x724, SGS) == SGS_Pursue &&\n        PxpFindSoGround(pubg, NULL, NULL))\n    {\n        SO *pso = PsoPadUbgClosest(pubg, &STRUCT_OFFSET(pubg, 0x140, VECTOR));\n\n        if (pso != STRUCT_OFFSET(pubg, 0xc7c, SO *)) // pubg->psoLastDunk\n        {\n            // pubg->cJump\n            int cJump = STRUCT_OFFSET(pubg, 0xc5c, int) - 1;\n            if (cJump < 1) cJump = 0;\n            STRUCT_OFFSET(pubg, 0xc5c, int) = cJump;\n\n            if (cJump > 0)\n            {\n                SMA *psma = PsmaFindAlo(pso, OID_Nil);\n                if (psma) SetSmaGoal(psma, OID_state_ubb_dunk);\n                STRUCT_OFFSET(pubg, 0xc7c, SO *) = pso; // pubg->psoLastDunk\n            }\n        }\n    }\n\n    DoStepguardFreefallLanding(pubg);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ub\", UpdateUbgGoal__FP3UBGi);\n\nvoid UpdateUbgSgs(UBG *pubg)\n{\n    // pubg->sgs\n    if (STRUCT_OFFSET(pubg, 0x724, SGS) == SGS_LostPlayer)\n    {\n        LookStepguardAtGoal(pubg);\n        return;\n    }\n\n    UpdateStepguardSgs(pubg);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ub\", FUN_001e8fe8);\n\nint FIgnoreUbgIntersection(UBG *pubg, SO *psoOther)\n{\n    for (uint i = 0; i < 6; i++)\n    {\n        // pubg->apsoPads\n        SO **apsoPads = &STRUCT_OFFSET(pubg, 0xc64, SO *);\n        if ((SO *)psoOther->paloRoot == apsoPads[i])\n            return 0;\n    }\n\n    return FIgnoreStepguardIntersection(pubg, psoOther);\n}\n"
  },
  {
    "path": "src/P2/ui.c",
    "content": "#include <ui.h>\n#include <clock.h>\n#include <sound.h>\n#include <screen.h>\n\nvoid StartupUi()\n{\n    InitUi(&g_ui);\n}\n\nvoid InitUi(UI *pui)\n{\n    pui->unk6 = -1;\n    pui->tUis = -1;\n    SetUiUis(pui, UIS_Pausing);\n    pui->cpblotActive = 0;\n    pui->unk5 = 1;\n}\n\nvoid PostUiLoad(UI *pui)\n{\n    SetUiUis(pui, UIS_Pausing);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ui\", UpdateUi__FP2UI);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ui\", PushUiActiveBlot__FP2UIP4BLOT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ui\", PopUiActiveBlot__FP2UI);\n\nvoid DrawUi()\n{\n    DrawBlots();\n}\n\nvoid RenderUi()\n{\n    RenderBlots();\n}\n\nvoid ResetUi(UI *pui)\n{\n    while (pui->unk5 >= 2)\n    {\n        PopUiActiveBlot(pui);\n    }\n\n    pui->unk5 = 1;\n    pui->cpblotActive = 0;\n    pui->unk6 = -1;\n\n    SetRumbleRums(g_joy.prumble, RUMS_Stop);\n    ResetBlots();\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ui\", SetUiUis__FP2UI3UIS);\n\nvoid SetUiUPause(UI *pui, float uPause)\n{\n    if (g_clock.t > 0.0f)\n    {\n        float vol = (1.0f - uPause) * 0.6f + uPause;\n        SetMvgkRvol(4, MVGK_Music, vol);\n        SetMvgkRvol(4, MVGK_Effects, vol);\n    }\n\n    SetClockRate(uPause);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ui\", FUN_001e9970__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ui\", FUN_001e9a10__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ui\", FUN_001e9a68__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ui\", FUN_001e9ad8__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/ui\", check_anticrack_collectibles_Fv);\n"
  },
  {
    "path": "src/P2/update.c",
    "content": "#include <update.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/update\", UpdateSwObjects__FP2SWf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/update\", UpdateSwPosWorldPrev__FP2SW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/update\", UpdateSwRealClock__FP2SWf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/update\", UpdateSwDarkening__FP2SWf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/update\", UpdateSw__FP2SWf);\n"
  },
  {
    "path": "src/P2/util.c",
    "content": "#include <gcc/math.h>\n#include <sce/rand.h>\n#include <util.h>\n#include <vec.h>\n\nstatic const float PI = 3.14159265359f;\nconst int PRIME_MOD = 0x95675;\n\n#ifdef SKIP_ASM\nLM g_lmZeroOne = {0.0f, 1.0f};\n#endif\n\nfloat RadNormalize(float rad)\n{\n    if (rad < -PI || PI < rad)\n    {\n        float modpos = GModPositive(rad + PI, 2 * PI);\n        rad = modpos - PI;\n    }\n    return rad;\n}\n\nfloat GLimitAbs(float g, float absLimit)\n{\n    if (g > absLimit)\n    {\n        g = absLimit;\n    }\n    else if (g < -absLimit)\n    {\n        g = -absLimit;\n    }\n    return g;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", GSmooth__FfffP3SMPPf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", GSmoothA__FffffP4SMPAPf);\n\nJUNK_ADDIU(40);\n\nfloat RadSmooth(float radCur, float radTarget, float dt, SMP *psmp, float *pdradNext)\n{\n    float rad;\n    rad = RadNormalize(radTarget - radCur);\n    rad = GSmooth(0.0f, rad, dt, psmp, pdradNext);\n    rad = RadNormalize(radCur + rad);\n    return rad;\n}\n\nfloat RadSmoothA(float radCur, float dradCur, float radTarget, float dt, SMPA *psmpa, float *pdradNext)\n{\n    float rad;\n    rad = RadNormalize(radTarget - radCur);\n    rad = GSmoothA(0.0f, dradCur, rad, dt, psmpa, pdradNext);\n    rad = RadNormalize(radCur + rad);\n    return rad;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", PosSmooth);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", SmoothMatrix);\n\n// Generates a random integer in the range [nLow, nHi]\nint NRandInRange(int nLow, int nHi)\n{\n    if (nLow == nHi)\n    {\n        return nLow;\n    }\n\n    int randVal = rand();\n    randVal %= PRIME_MOD;\n\n    // Return a value within the range [nLow, nHi]\n    int range = (nHi - nLow) + 1;\n    return nLow + (randVal % range);\n}\n\nfloat GRandInRange(float gHi, float gLow)\n{\n    if (gHi == gLow)\n    {\n        return gHi;\n    }\n\n    int nRand = rand();\n    return gHi + (gLow - gHi) * (float)nRand * 4.656613e-10f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", GRandGaussian__Ffff);\n#ifdef SKIP_ASM\n/**\n * @todo 64.35% matched.\n * log function needs to be defined. Does it use sce math lib?\n */\nfloat GRandGaussian(float param_1, float param_2, float param_3)\n{\n    float fVar1;\n    float fVar2;\n    float fVar3;\n    float fVar4;\n\n    fVar3 = -1.0f;\n    fVar4 = 0.0f;\n    do\n    {\n        do\n        {\n            fVar1 = (float)GRandInRange(fVar3, 1.0f);\n            fVar2 = (float)GRandInRange(fVar3, 1.0f);\n            fVar1 = fVar1 * fVar1 + fVar2 * fVar2;\n        } while (1.0f < fVar1);\n    } while (fVar1 == fVar4);\n    // fVar3 = logf(fVar1);\n    fVar4 = param_1 + param_2 * fVar2 * sqrtf((fVar3 * -2.0f) / fVar1);\n    fVar3 = fVar4;\n    if (param_3 != 0.0f)\n    {\n        fVar3 = param_1 - param_3;\n        if ((param_1 - param_3 <= fVar4) && (fVar3 = fVar4, param_1 + param_3 < fVar4))\n            fVar3 = param_1 + param_3;\n    }\n    return fVar3;\n}\n#endif // SKIP_ASM\n\nint FFloatsNear(float g1, float g2, float gEpsilon)\n{\n    g2 = g1 - g2;\n    g1 = g1 > 0.0f ? g1 : -g1;\n    g2 = g2 > 0.0f ? g2 : -g2;\n\n    float x = 1.0f;\n    x = g1 > x ? g1 : x;\n\n    return (g2 / x) < gEpsilon;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", CSolveQuadratic__FfffPf);\n#ifdef SKIP_ASM\n/**\n * @todo 95.96% matched.\n *\n * Compiler is using bc1f instead of bc1fl for (alpha < 0.0f) branch.\n *\n * https://decomp.me/scratch/A4VOu\n */\nint CSolveQuadratic(float a, float b, float c, float *ax)\n{\n    float alpha;\n    float beta;\n\n    alpha = b * b - 4.f * a * c;\n    a = a * 2;\n\n    if (alpha < 0.0f)\n    {\n        return 0;\n    }\n    else\n    {\n        beta = b / a;\n        alpha = sqrtf(alpha) / a;\n        if (fabsf(alpha) < 0.0001f)\n        {\n            *ax = -beta;\n            return 1;\n        }\n\n        *ax = -beta + alpha;\n        ax[1] = -beta - alpha;\n        return 2;\n    }\n}\n#endif // SKIP_ASM\n\nvoid PrescaleClq(CLQ *pclqSrc, float ru, float du, CLQ *pclqDst)\n{\n    pclqDst->g2 = pclqSrc->g2 * ru * ru;\n    pclqDst->g1 = (pclqSrc->g2 + pclqSrc->g2) * ru * du + pclqSrc->g1 * ru;\n    pclqDst->g0 = pclqSrc->g2 * du * du + pclqSrc->g1 * du + pclqSrc->g0;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", CalculateSinCos__FfPfT1);\n#ifdef SKIP_ASM\n/**\n * @tod 86.55% matched.\n */\nvoid CalculateSinCos(float angle, float *sin, float *cos)\n{\n    // Constants from the assembly (hex to float)\n    const float PI_OVER_2 = 1.57079637051f; // 0x3FC90FDB\n    const float INV_PI = 0.31830987334f;    // 0x3EA2F983\n    const float PI = 3.14159274101f;        // 0x40490FDB\n\n    // Polynomial coefficients (from hex in asm)\n    const float C1 = -0.1666666279f;   // 0xBE2AAAA4\n    const float C2 = 0.00833302546f;   // 0x3C08873E\n    const float C3 = -0.000198074187f; // 0xB94FB21F\n    const float C4 = 2.601887e-06f;    // 0x362E9C14\n\n    float x = (angle + PI_OVER_2) * INV_PI;\n    int n = (int)x;\n    if (x < 0.0f)\n        n -= 1;\n    int odd = n & 1;\n    float xn = (float)n;\n    float theta = angle - xn * PI;\n    if (odd)\n        theta = -theta;\n\n    float theta2 = theta * theta;\n    float s = theta;\n    float t = theta2 * theta;\n    float u = t * theta2;\n    float v = u * theta2;\n    float w = v * theta2;\n\n    float result = s + t * C1 + u * C2 + v * C3 + w * C4;\n\n    float result2 = 1.0f - result * result;\n    if (odd)\n        result2 = -result2;\n\n    *sin = result;\n    *cos = result2;\n}\n#endif // SKIP_ASM\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", GTrunc__Fd); // double version\n#ifdef SKIP_ASM\n/**\n * @todo 34.18% matched.\n */\ndouble GTrunc(double param_1)\n{\n    union\n    {\n        double d;\n        ulong u;\n    } conv;\n    conv.d = param_1;\n\n    int exp = (int)((conv.u >> 52) & 0x7FF) - 0x3FF;\n    if (exp < 0)\n        return 0.0;\n    if (exp >= 52)\n        return param_1;\n\n    ulong mask = (1ULL << (52 - exp)) - 1;\n    ulong frac = conv.u & 0xFFFFFFFFFFFFF;\n    ulong intpart = conv.u & ~mask;\n\n    if ((frac & mask) == mask)\n    {\n        // Special case: all masked bits set, round up\n        intpart += (1ULL << (52 - exp));\n        // Clear fraction bits\n        intpart &= ~mask;\n    }\n\n    conv.u = intpart;\n    return conv.d;\n}\n#endif\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", GTrunc__Ff); // float version\n#ifdef SKIP_ASM\n/**\n * @todo 36.07% matched.\n */\nfloat GTrunc(float param_1)\n{\n    union\n    {\n        float f;\n        uint u;\n    } conv;\n    conv.f = param_1;\n\n    int exp = ((conv.u >> 23) & 0xFF) - 0x7F;\n    if (exp < 0)\n        return 0.0f;\n    if (exp >= 0x17)\n        return param_1;\n\n    uint mask = (1u << (0x17 - exp)) - 1;\n    uint frac = conv.u & 0x7FFFFF;\n    if ((frac & mask) == mask)\n    {\n        // All masked bits set, round up\n        conv.u = (conv.u & 0xFF800000) | (frac & ~mask);\n        conv.f += 1.0f;\n        return conv.f;\n    }\n    else\n    {\n        conv.u = (conv.u & 0xFF800000) | (frac & ~mask);\n        return conv.f;\n    }\n}\n#endif // SKIP_ASM\n\nfloat GModPositive(float gDividend, float gDivisor)\n{\n    float result = fmodf(gDividend, gDivisor);\n    if (result < 0.0f)\n    {\n        result += gDivisor;\n    }\n    return result;\n}\n\nvoid FitClq(float g0, float g1, float u, float gU, CLQ *pclq)\n{\n    pclq->g0 = g0;\n    pclq->g2 = ((gU - g0) / u - (g1 - g0)) / (u - 1.0f);\n    pclq->g1 = (g1 - g0) - pclq->g2;\n}\n\nint FCheckLm(LM *plm, float g)\n{\n    return (plm->gMin < g) && (g < plm->gMax);\n}\n\nbool FCheckAlm(int clm, LM *alm, float g)\n{\n    for (int i = 0; i < clm; i++)\n    {\n        if (FCheckLm(&alm[i], g))\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\nfloat GLimitLm(LM *plm, float g)\n{\n    if (g < plm->gMin)\n    {\n        return plm->gMin;\n    }\n    if (g > plm->gMax)\n    {\n        return plm->gMax;\n    }\n    return g;\n}\n\nint SgnCompareG(float *pg1, float *pg2)\n{\n    if (*pg1 > *pg2)\n    {\n        return 1;\n    }\n    else if (*pg2 > *pg1)\n    {\n        return -1;\n    }\n    return 0;\n}\n\nvoid Force(void *pv)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/util\", MinimizeRange);\n\nJUNK_ADDIU(C0);\n"
  },
  {
    "path": "src/P2/vec.c",
    "content": "#include <intrinsics.h>\n#include <math.h>\n#include <util.h>\n#include <vec.h>\n\nvoid SetVectorCylind(VECTOR *pvec, float rad, float sXY, float sZ)\n{\n    float gSin, gCos;\n    CalculateSinCos(rad, &gSin, &gCos);\n\n    pvec->z = sZ;\n    pvec->x = gCos * sXY;\n    pvec->y = gSin * sXY;\n}\n\nvoid SetVectorSphere(VECTOR *pvec, float radPan, float radTilt, float s)\n{\n    float gSinPan, gCosPan, gSinTilt, gCosTilt;\n    CalculateSinCos(radPan,&gSinPan, &gCosPan);\n    CalculateSinCos(radTilt, &gSinTilt, &gCosTilt);\n\n    pvec->z = gSinTilt * s;\n    pvec->x = gCosTilt * gCosPan * s;\n    pvec->y = gCosTilt * gSinPan * s;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vec\", SProjectVector__FP6VECTORT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vec\", GetNormalVectors__FP6VECTORN30);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vec\", GetNormalVector__FP6VECTORT0);\n\nJUNK_ADDIU(A0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vec\", RadBetweenVectors__FP6VECTORN20);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vec\", FindClosestPointBetweenLines__FP6VECTORN30PfT4T0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vec\", FindClosestPointBetweenLineSegments__FP6VECTORN40PfT0);\n\nvoid CalculateVectorPanTilt(VECTOR *pvec, float *pradPan, float *pradTilt)\n{\n    if (pradPan)\n    {\n        *pradPan = RadNormalize(atan2f(pvec->y, pvec->x));\n    }\n    if (pradTilt)\n    {\n        float dXYDist = SQRTF(pvec->x * pvec->x + pvec->y * pvec->y);\n        *pradTilt = RadNormalize(atan2f(pvec->z, dXYDist));\n    }\n}\n\nvoid ConvertDeulToW(VECTOR *peul, VECTOR *pdeul, VECTOR *pw)\n{\n    float ySin, yCos, zSin, zCos;\n    CalculateSinCos(peul->y, &ySin, &yCos);\n    CalculateSinCos(peul->z, &zSin, &zCos);\n\n    pw->x = yCos * zCos * pdeul->x - zSin * pdeul->y;\n    pw->y = yCos * zSin * pdeul->x + zCos * pdeul->y;\n    pw->z = -ySin * pdeul->x + pdeul->z;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vec\", FCalculateMuzzleVelocity__FP6VECTORT0fT0P2SO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vec\", FCalculateMuzzleVelocity1);\n\nint FCalculateMuzzleVelocityAngle(VECTOR *pposLaunch, VECTOR *pposTarget, float radTilt, VECTOR *pvecMuzzle, SO *psoLaunch)\n{\n    return FCalculateMuzzleVelocity(pposLaunch, pposTarget, radTilt, pvecMuzzle, psoLaunch);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vec\", LimitVectorLength);\n"
  },
  {
    "path": "src/P2/vifs.c",
    "content": "#include <vifs.h>\n\nVIFS::VIFS()\n{\n    m_fPad = 1;\n    m_unMask = 0;\n    m_fCheckCnt = 0;\n}\n\nJUNK_NOP();\nJUNK_ADDIU(10);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vifs\", Align__4VIFSi);\n\nvoid VIFS::AddVifBaseOffset(int iqwBase, int diqwOffset)\n{\n    AddDmaInt(this, iqwBase | 0x03000000);\n    AddDmaInt(this, diqwOffset | 0x02000000);\n}\n\n/**\n * @todo Figure out why using the inlined function doesn't work here.\n */\nvoid VIFS::AddVifMscal(void *pv)\n{\n    int i = (int)pv < 0 ? (int)pv + 7 : (int)pv;\n    uchar *p = m_pb;\n    m_pb = p + 4;\n    *(int *)p = (i >> 3) | 0x14000000;\n}\n\n/**\n * @todo Figure out why using the inlined function doesn't work here.\n */\nvoid VIFS::AddVifMscalf(void *pv)\n{\n    int i = (int)pv < 0 ? (int)pv + 7 : (int)pv;\n    uchar *p = m_pb;\n    m_pb = p + 4;\n    *(int *)p = (i >> 3) | 0x15000000;\n}\n\nvoid VIFS::AddVifFlush()\n{\n    AddDmaInt(this, 0x11000000);\n}\n\nvoid VIFS::AddVifFlusha()\n{\n    AddDmaInt(this, 0x13000000);\n}\n\nvoid VIFS::AddVifFlushe()\n{\n    AddDmaInt(this, 0x10000000);\n}\n\nvoid VIFS::AddVifStcycl(int wl, int cl)\n{\n    AddDmaInt(this, cl | (wl << 8) | 0x1000000);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vifs\", AddVifStrow__4VIFSP2QW);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vifs\", AddVifStmask__4VIFSUi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vifs\", CbUnpackSetup__4VIFS3UPKii);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vifs\", UnpackHelper__4VIFS3UPKiiPiPPUi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vifs\", AddVifUnpack__4VIFS3UPKiPvi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vifs\", AddVifUnpackRefs__4VIFS3UPKiPviPPPv);\n\n/**\n * @todo Figure out why using the inlined function doesn't work here.\n */\nvoid VIFS::AddVifDirect(int cqw, QW *aqw, int fInt)\n{\n    Align(3);\n    \n    uchar *p = m_pb;\n    m_pb = p + 4;\n    *(int *)p = cqw | 0x50000000 | (fInt << 31);\n    \n    AddDmaBulk(cqw, aqw);\n}\n\n/**\n * @todo Figure out why using the inlined function doesn't work here.\n */\nvoid VIFS::AddVifDirectRefs(int cqw, QW *aqw, int fInt)\n{\n    Align(3);\n    \n    uchar *p = m_pb;\n    m_pb = p + 4;\n    *(int *)p = cqw | 0x50000000 | (fInt << 31);\n    \n    AddDmaRefs(cqw, aqw);\n}\n\nvoid VIFS::AddVifGifs(GIFS *pgifs)\n{\n    AddVifDirect((uint)(pgifs->m_pb - pgifs->m_ab) >> 4, (QW *)pgifs->m_ab, 0);\n}\n"
  },
  {
    "path": "src/P2/vis.c",
    "content": "#include <vis.h>\n#include <sw.h>\n#include <brx.h>\n#include <memory.h>\n\nvoid InitVismap(VISMAP *pvismap)\n{\n    InitLo(pvismap);\n    pvismap->psw->pvismap = pvismap;\n}\n\nvoid LoadVismapFromBrx(VISMAP *pvismap, CBinaryInputStream *pbis)\n{\n    pbis->ReadVbsp(&pvismap->cvbsp, &pvismap->avbsp);\n\n    pvismap->cgrfzon = pbis->U16Read();\n    pvismap->agrfzonOneHop = (GRFZON *)PvAllocSwImpl(pvismap->cgrfzon * sizeof(GRFZON));\n\n    for (int i = 0; i < pvismap->cgrfzon; i++)\n    {\n        pvismap->agrfzonOneHop[i] = pbis->U32Read();\n    }\n\n    LoadOptionsFromBrx(pvismap, pbis);\n}\n\nGRFZON GrfzonOneHop(VISMAP *pvismap, VBSP *pvbsp)\n{\n    int bits = (int)((uint)pvbsp & 0x7fffffff);\n    if (bits == 0)\n        return 0;\n\n    int acc = -1;\n    for (int i = 0; i < pvismap->cgrfzon; i++)\n    {\n        int shifted = bits >> i;\n        if ((shifted & 1) != 0)\n        {\n            acc &= pvismap->agrfzonOneHop[i];\n        }\n    }\n\n    return acc | (uint)bits;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vis\", ClipVbspSphereOneHop__FP6VISMAPP4VBSPG9VU_VECTORfPi);\n\n/**\n * @brief 89.47% match. Single load instruction mismatch. VU_VECTOR implemented wrong?\n * https://decomp.me/scratch/5lzfX\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/vis\", ClipVismapSphereOneHop__FP6VISMAPP6VECTORfPi);\n#ifdef SKIP_ASM\nvoid ClipVismapSphereOneHop(VISMAP *pvismap, VECTOR *ppos, float sRadius, GRFZON *pgrfzon)\n{\n    if (pvismap && pvismap->avbsp)\n    {\n        VU_VECTOR vuvector = *(VU_VECTOR *)ppos;\n        *pgrfzon = 0;\n        ClipVbspSphereOneHop(pvismap, pvismap->avbsp, vuvector, sRadius, pgrfzon);\n        return;\n    }\n\n    *pgrfzon = 0xfffffff;\n}\n#endif // SKIP_ASM\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/vis\", ClipVismapPointNoHop__FP6VISMAPP6VECTORPi);\n"
  },
  {
    "path": "src/P2/water.c",
    "content": "#include <water.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", InitWater__FP5WATER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", PostWaterLoad__FP5WATER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", CalculateWaterCurrent__FP5WATERP6VECTORN21);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", UpdateSwXaList__FP2SWPP2XA);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", UpdateWater__FP5WATERf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", AddWaterExternalAccelerations__FP5WATERP2XAf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", HandleWaterMessage__FP5WATER5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", UpdateWaterMergeGroup__FP5WATER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", UGetWaterSubmerged__FP5WATERP2SOP6VECTORT2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", UpdateWaterBounds__FP5WATER);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", FInflictWaterZap__FP5WATERP2XPP3ZPR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", PzpdEnsureWater__FP5WATER4ENSK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/water\", FUN_001ef830);\n"
  },
  {
    "path": "src/P2/waypoint.c",
    "content": "#include <waypoint.h>\n#include <button.h>\n#include <memory.h>\n#include <sw.h>\n\nextern SNIP s_asnipPostWaypointLoad;\nextern VTWPSG g_vtwpsg;\n\nvoid InitWaypoint(WAYPOINT *pwaypoint)\n{\n    InitAlo(pwaypoint);\n    STRUCT_OFFSET(pwaypoint, 0x2d0, int) = -1; // pwaypoint->oidSync\n    STRUCT_OFFSET(pwaypoint, 0x2e0, int) = -1; // pwaypoint->wps\n}\n\nvoid PostWaypointLoad(WAYPOINT *pwaypoint)\n{\n    PostAloLoad(pwaypoint);\n    SnipAloObjects(pwaypoint, 1, &s_asnipPostWaypointLoad);\n    SetWaypointWps(pwaypoint, WPS_Passive);\n    pwaypoint->pvtlo->pfnRemoveLo(pwaypoint);\n}\n\nvoid SetWaypointRsmg(WAYPOINT *pwaypoint, int fOnTrigger, OID oidRoot, OID oidSm, OID oidGoal)\n{\n    // pwaypoint->arsmgSet & pwaypoint->crsmgSet\n    FAddRsmg(&STRUCT_OFFSET(pwaypoint, 0x2e8, RSMG), 4, &STRUCT_OFFSET(pwaypoint, 0x2e4, int), fOnTrigger, oidRoot, oidSm, oidGoal);\n}\n\nvoid UpdateWaypoint(WAYPOINT *pwaypoint, float dt)\n{\n    return;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/waypoint\", SetWaypointWps__FP8WAYPOINT3WPS);\n\nvoid HandleWaypointMessage(WAYPOINT *pwaypoint, MSGID msgid, void *pv)\n{\n    HandleAloMessage(pwaypoint, msgid, pv);\n\n    // pwaypoint->paseg\n    if (msgid == MSGID_asega_limit && STRUCT_OFFSET(pv, 0x08, ASEG *) == STRUCT_OFFSET(pwaypoint, 0x2dc, ASEG *))\n    {\n        SetWaypointWps(pwaypoint, WPS_Passive);\n    }\n}\n\nWPSG *PwpsgNew()\n{\n    WPSG *pwpsg = (WPSG *)PvAllocSwClearImpl(sizeof(WPSG));\n    pwpsg->pvtwpsg = &g_vtwpsg;\n    return pwpsg;\n}\n\nvoid AddWpsgWaypoint(WPSG *pwpsg, WAYPOINT *pwaypoint)\n{\n    if (pwpsg->cpwaypoint < 8)\n    {\n        pwpsg->apwaypoint[pwpsg->cpwaypoint++] = pwaypoint;\n    }\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/waypoint\", RemoveWpsgWaypoint__FP4WPSGP8WAYPOINT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/waypoint\", UpdateWpsgCallback__FP4WPSG5MSGIDPv);\n\nvoid EnsureWpsgCallback(WPSG *pwpsg)\n{\n    if (!pwpsg->fCallback)\n    {\n        pwpsg->fCallback = 1;\n        PostSwCallback(g_psw, UpdateWpsgCallback, pwpsg, MSGID_Nil, NULL);\n    }\n}\n\nJUNK_ADDIU(40);\n"
  },
  {
    "path": "src/P2/wipe.c",
    "content": "#include <wipe.h>\n\nvoid InitWipe(WIPE *pwipe)\n{\n    pwipe->wipes = WIPES_Nil;\n    SetWipeWipes(pwipe, WIPES_Idle);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wipe\", UpdateWipe__FP4WIPEP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wipe\", DrawWipe__FP4WIPE);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wipe\", ActivateWipe__FP4WIPEP5TRANS5WIPEK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wipe\", SetWipeButtonTrans__FP4WIPEP5TRANS5WIPEK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wipe\", FCatchWipeButtonTrans__FP4WIPEP3JOY5WIPES);\n\nJUNK_WORD(0x00A0102D);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wipe\", SetWipeWipes__FP4WIPE5WIPES);\n\nvoid WipeToWorldWarp(const void *pchzWorld, OID oidWarp, WIPEK wipek)\n{\n    TRANS trans;\n    trans.fSet = 1;\n    trans.grftrans = 0;\n    trans.pchzWorld = (LevelTableStruct *)pchzWorld;\n    trans.oidWarp = oidWarp;\n    ActivateWipe(&g_wipe, &trans, wipek);\n}\n"
  },
  {
    "path": "src/P2/wm.c",
    "content": "#include <wm.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", FUN_001f0468);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", FUN_001f0490);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", FUN_001f0580);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", PostWmLoad__FP2WM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", BindWm__FP2WM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", RefreshWmMoveStats__FP2WM10WORLDLEVEL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", ThrowWmDisplayState__FP2WM10WORLDLEVELi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", CatchWmDisplayState__FP2WM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", UpdateWm__FP2WMf);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", RenderWmAll__FP2WMP2CMP2RO);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", HandleWmMessage__FP2WM5MSGIDPv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", SetWmWms__FP2WM3WMS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", ShowWm__FP2WM10WORLDLEVEL3WMS);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", HideWm__FP2WM);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", MoveWm__FP2WM3WMD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", GetWmWorldPosScreen__FP2WM10WORLDLEVELP6VECTOR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", SetWmCursor__FP2WM10WORLDLEVEL);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", PostWmcLoad__FP3WMC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", UpdateWmcActive__FP3WMCP3JOY);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", OnWmcActive__FP3WMCi);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", DrawWmFan__FffffiG4RGBAT5i);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", DrawWmc__FP3WMC);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", wm__static_initialization_and_destruction_0);\n\nJUNK_WORD(0xE48C0000);\nJUNK_WORD(0xE48C0008);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wm\", _GLOBAL_$I$U_WmFadedLevels);\n"
  },
  {
    "path": "src/P2/wr.c",
    "content": "#include <wr.h>\n\nvoid InitWr(WR *pwr)\n{\n    InitLo(pwr);\n    pwr->tLastUpdate = -1.0f;\n    pwr->imatHalf = -1;\n    pwr->iwreCur = -1;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wr\", ApplyWrGlob__FP2WRP3ALOP4GLOB);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wr\", UpdateWrStateVectors__FP2WR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wr\", WarpWrTransform__FP2WRfP6VECTORP7MATRIX3T2T3T2);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wr\", GetWrBounds__FP2WRP6VECTOR);\n\nfloat UNoise(int n)\n{\n    int x = (n << 13) ^ n;\n    int y = x * x * 0x3d73 + 0xc0ae5;\n    int z = x * y + 0x5208dd0d;\n    x = z & 0x7fffffff;\n    return (float)x / 2147483648.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wr\", UNoise__Ffff);\n\nfloat UBias(float u, float v)\n{\n    return u / ((1.0f / v - 2.0f) * (1.0f - u) + 1.0f);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wr\", GFromOnz__FP3ONZ);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wr\", UpdateWrMatrixes__FP2WR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wr\", AddWrCircleWarp__FP2WR);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/wr\", AddWrBendWarp__FP2WR);\n\nWRE *PwreGetWrCur(WR *pwr, ENSK ensk, WREK wrek)\n{\n    if (pwr->cwre == 0)\n    {\n        return NULL;\n    }\n    if (ensk == ENSK_Set)\n    {\n        pwr->fValuesChanged = 1;\n    }\n    \n    return &pwr->awre[pwr->iwreCur];\n}\n\nWRE *PwreGetWrCircle(WR *pwr, ENSK ensk)\n{\n    return PwreGetWrCur(pwr, ensk, WREK_Circle);\n}\n\nWRE *PwreGetWrBend(WR *pwr, ENSK ensk)\n{\n    return PwreGetWrCur(pwr, ensk, WREK_Bend);\n}\n\nvoid SetWrWavelength(WR *pwr, float sWavelength)\n{\n    WRE *pwre = PwreGetWrCircle(pwr, ENSK_Set);\n    if (sWavelength == 0.0f)\n    {\n        STRUCT_OFFSET(pwre, 0x64, float) = 0.0f;\n    }\n    else\n    {\n        STRUCT_OFFSET(pwre, 0x64, float) = 1.0f / sWavelength;\n    }\n}\n\nvoid GetWrWavelength(WR *pwr, float *psWavelength)\n{\n    WRE *pwre = PwreGetWrCircle(pwr, ENSK_Set);\n    if (STRUCT_OFFSET(pwre, 0x64, float) == 0.0f)\n    {\n        *psWavelength = 0.0f;\n    }\n    else\n    {\n        *psWavelength = 1.0f / STRUCT_OFFSET(pwre, 0x64, float);\n    }\n}\n\nvoid AddOnzOnze(ONZ *ponz, float uAmpl, float gFreq, float gPhase, float uRandom)\n{\n    uint conze = ponz->conze;\n    if (conze < 4)\n    {\n        ONZE *ponze = ponz->aonze + conze;\n        ponz->conze++;\n\n        ponze->uAmpl = uAmpl;\n        ponze->gFreq = gFreq;\n        ponze->gPhase = gPhase;\n        ponze->uRandom = uRandom;\n    }\n}\n\nvoid AddWrBendNoise(WR *pwr, float uAmpl, float gFreq, float gPhase, float uRandom)\n{\n    WRE *pwre = PwreGetWrBend(pwr, ENSK_Set);\n    AddOnzOnze(&STRUCT_OFFSET(pwre, 0x30, ONZ), uAmpl, gFreq, gPhase, uRandom);\n}\n\nvoid AddWrSwivelNoise(WR *pwr, float uAmpl, float gFreq, float gPhase, float uRandom)\n{\n    WRE *pwre = PwreGetWrBend(pwr, ENSK_Set);\n    AddOnzOnze(&STRUCT_OFFSET(pwre, 0x80, ONZ), uAmpl, gFreq, gPhase, uRandom);\n}\n"
  },
  {
    "path": "src/P2/xform.c",
    "content": "#include <xform.h>\n#include <button.h>\n#include <brx.h>\n#include <sw.h>\n#include <cm.h>\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", InitXfm__FP3XFM);\n\nvoid LoadXfmFromBrx(XFM *pxfm, CBinaryInputStream *pbis)\n{\n    pbis->ReadMatrix(&pxfm->matLocal);\n    pbis->ReadVector(&pxfm->posLocal);\n    LoadOptionsFromBrx(pxfm, pbis);\n}\n\nvoid SetXfmParent(XFM *pxfm, ALO *paloParent)\n{\n    ConvertAloPos(pxfm->paloParent, paloParent, &pxfm->posLocal, &pxfm->posLocal);\n    ConvertAloMat(pxfm->paloParent, paloParent, &pxfm->matLocal, &pxfm->matLocal);\n    SetLoParent(pxfm, paloParent);\n}\n\nvoid ApplyXfmProxy(XFM *pxfm, PROXY *pproxyApply)\n{\n    ConvertAloPos(pproxyApply, NULL, &pxfm->posLocal, &pxfm->posLocal);\n    ConvertAloMat(pproxyApply, NULL, &pxfm->matLocal, &pxfm->matLocal);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", ConvertXfmLocalToWorld__FP3XFMP6VECTORT1);\n\nvoid GetXfmPos(XFM *pxfm, VECTOR *ppos)\n{\n    ConvertAloPos(pxfm->paloParent, NULL, &pxfm->posLocal, ppos);\n}\n\nvoid GetXfmMat(XFM *pxfm, MATRIX3 *pmat)\n{\n    ConvertAloMat(pxfm->paloParent, NULL, &pxfm->matLocal, pmat);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", PwarpFromOid__F3OIDT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", LoadWarpFromBrx__FP4WARPP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", CloneWarp__FP4WARPT0);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", PostWarpLoad__FP4WARP);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", TriggerWarp__FP4WARP);\n\nvoid SetWarpRsmg(WARP *pwarp, int fOnTrigger, OID oidRoot, OID oidSM, OID oidGoal)\n{\n    // pwarp->arsmg & pwarp->crsmg\u001c\n    FAddRsmg(&STRUCT_OFFSET(pwarp, 0xb8, RSMG), 4, &STRUCT_OFFSET(pwarp, 0xb4, int), fOnTrigger, oidRoot, oidSM, oidGoal);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", FUN_001F4308);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", TeleportSwPlayer__FP2SW3OIDT1);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", PexitDefault__Fv);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", TriggerDefaultExit__Fi5WIPEK);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", LoadExitFromBrx__FP4EXITP18CBinaryInputStream);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", PostExitLoad__FP4EXIT);\n\nvoid SetExitExits(EXIT *pexit, EXITS exits)\n{\n    if (exits == STRUCT_OFFSET(pexit, 0x2e4, EXITS)) // pexit->exits\n    {\n        return;\n    }\n\n    // pexit->exits\n    if (STRUCT_OFFSET(pexit, 0x2e4, EXITS) == EXITS_Totals && exits != EXITS_Exiting)\n    {\n        g_totals.pvttotals->pfnHideBlot(&g_totals);\n    }\n\n    if (exits != EXITS_Exiting)\n    {\n        STRUCT_OFFSET(pexit, 0x2e4, EXITS) = exits; // pexit->exits\n        STRUCT_OFFSET(pexit, 0x2e8, float) = g_clock.t; // pexit->tExits\n        return;\n    }\n\n    uint64_t tmp = STRUCT_OFFSET(pexit, 0x2c8, uint64_t);\n    STRUCT_OFFSET(pexit, 0x2c8, uint64_t) = (tmp & ~0x30000000000ULL) | (0x8000ULL << 0x19);\n\n    IncrementSwHandsOff(pexit->psw);\n\n    STRUCT_OFFSET(pexit, 0x2e4, EXITS) = exits; // pexit->exits\n    STRUCT_OFFSET(pexit, 0x2e8, float) = g_clock.t; // pexit->tExits\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", TriggerExit__FP4EXIT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", WipeExit__FP4EXIT);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", UpdateExit__FfP4EXIT);\n\nvoid InitCamera(CAMERA *pcamera)\n{\n    InitAlo(pcamera);\n    STRUCT_OFFSET(pcamera, 0x2d0, OID) = OID_Nil; // pcamera->oidTarget\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/xform\", PostCameraLoad__FP6CAMERA);\n\nvoid EnableCamera(CAMERA *pcamera)\n{\n    if (STRUCT_OFFSET(pcamera, 0x310, int) == 0) // pcamera->fSetCplcy\n    {\n        // g_pcm->cpaseg\n        SetCmPolicy(g_pcm, CPP_Animated, &STRUCT_OFFSET(g_pcm, 0x510, CPLCY), NULL, pcamera);\n        STRUCT_OFFSET(pcamera, 0x310, int) = 1; // pcamera->fSetCplcy\n    }\n}\n\nvoid DisableCamera(CAMERA *pcamera)\n{\n    if (STRUCT_OFFSET(pcamera, 0x310, int) != 0) // pcamera->fSetCplcy\n    {\n        // g_pcm->cpaseg\n        RevokeCmPolicy(g_pcm, 0x0b, CPP_Animated, &STRUCT_OFFSET(g_pcm, 0x510, CPLCY), NULL, pcamera);\n        STRUCT_OFFSET(pcamera, 0x310, int) = 0; // pcamera->fSetCplcy\n    }\n}\n"
  },
  {
    "path": "src/P2/zap.c",
    "content": "#include <zap.h>\n#include <memory.h>\n#include <po.h>\n\nvoid InitTzp(TZP *ptzp)\n{\n    InitSo(ptzp);\n    InitZpd(&STRUCT_OFFSET(ptzp, 0x550, ZPD), ptzp);\n    STRUCT_OFFSET(ptzp, 0x4e0, ZOK) = ZOK_Zap;\n    STRUCT_OFFSET(ptzp, 0x538, ulong) &= 0xffffff0fffffffff; // ptzp->bspcCamera.absp\n    STRUCT_OFFSET(ptzp, 0x538, ulong) |= 0x2000000000;\n}\n\nvoid PostTzpLoad(TZP *ptzp)\n{\n    PostAloLoad(ptzp);\n    PostZpdLoad(&STRUCT_OFFSET(ptzp, 0x550, ZPD)); // ptzp->zpd\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/zap\", UpdateTzp__FP3TZPf);\n\nvoid CloneTzp(TZP *ptzp, TZP *ptzpBase)\n{\n    CloneSo(ptzp, ptzpBase);\n    STRUCT_OFFSET(ptzp, 0x550, ZPD).pso = ptzp; // ptzp->zpd\n}\n\nvoid RenderTzpAll(TZP *ptzp, CM *pcm, RO *pro)\n{\n    RenderAloAll(ptzp, pcm, pro);\n}\n\nint FInflictTzpZap(TZP *ptzp, XP *pxp, ZPR *pzpr)\n{\n    InflictZpdZap(&STRUCT_OFFSET(ptzp, 0x550, ZPD), pxp, pzpr); // ptzp->zpd\n    return 1;\n}\n\nZPD *PzpdEnsureTzp(TZP *ptzp, ENSK ensk)\n{\n    return &STRUCT_OFFSET(ptzp, 0x550, ZPD); // ptzp->zpd\n}\n\n/**\n * @todo Rename function and figure out what does it actually do.\n */\nvoid FUN_001F5210(TZP *ptzp)\n{\n    STRUCT_OFFSET(ptzp, 0x5e4, int) = 0;\n}\n\nvoid InitVolzp(VOLZP *pvolzp)\n{\n    InitTzp(pvolzp);\n    STRUCT_OFFSET(pvolzp, 0x538, ulong) |= 0x80000000000; // ptzp->bspcCamera.absp\n    SetSoConstraints(pvolzp, CT_Locked, NULL, CT_Locked, NULL);\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/zap\", UpdateVolzp__FP5VOLZPf);\n\nvoid InitZpd(ZPD *pzpd, SO *pso)\n{\n    pzpd->pso = pso;\n    pzpd->zpk = ZPK_Blunt;\n    pzpd->dzThrow = 150.0f;\n}\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/zap\", PostZpdLoad__FP3ZPD);\n\nINCLUDE_ASM(\"asm/nonmatchings/P2/zap\", ApplyZpdThrow__FP3ZPDP2PO);\n\nvoid InflictZpdZap(ZPD *pzpd, XP *pxp, ZPR *pzpr)\n{\n    PpoCur();\n    pzpr->zpk = pzpd->zpk;\n    pzpr->pv = pzpd;\n    pzpr->pfnzap = ApplyZpdThrow;\n    HandleLoSpliceEvent(pzpd->pso, 2, 0, NULL);\n}\n\nvoid AddZpdZapObject(ZPD *pzpd, OID oid)\n{\n    if ((uint)pzpd->coidThrow >= 32)\n        return;\n\n    pzpd->aoidThrow[pzpd->coidThrow++] = oid;\n}\n\nvoid AddZpdZapLo(ZPD *pzpd, LO *plo)\n{\n    if ((uint)pzpd->cploThrow >= 32)\n        return;\n\n    // TODO: Figure out the CIDs.\n    if (!FIsBasicDerivedFrom(plo, (CID)0x7e) && !FIsBasicDerivedFrom(plo, (CID)0x6e) &&\n        !FIsBasicDerivedFrom(plo, (CID)0x76) && !FIsBasicDerivedFrom(plo, (CID)0x70) &&\n        !FIsBasicDerivedFrom(plo, (CID)0x71) && !FIsBasicDerivedFrom(plo, (CID)0x81))\n        return;\n\n    pzpd->aploThrow[pzpd->cploThrow++] = plo;\n}\n\n/**\n * @todo 100% match. NOP bytes get added after this function\n * which makes the sce/libs TU not aligned properly.\n */\nINCLUDE_ASM(\"asm/nonmatchings/P2/zap\", RemoveZpdZapLo__FP3ZPDP2LO);\n#ifdef SKIP_ASM\nvoid RemoveZpdZapLo(ZPD *pzpd, LO *plo)\n{\n    int i;\n    for (i = 0; i < pzpd->cploThrow; i++)\n    {\n        if (pzpd->aploThrow[i] == plo)\n        {\n            break;\n        }\n    }\n\n    if (i < pzpd->cploThrow)\n    {\n        CopyAb(&pzpd->aploThrow[i], &pzpd->aploThrow[i] + 1, (pzpd->cploThrow - i - 1) * sizeof(*pzpd->aploThrow));\n        pzpd->cploThrow--;\n    }\n}\n#endif // SKIP_ASM\n"
  },
  {
    "path": "src/readme.md",
    "content": "# Source Files\n\nThis directory contains the source code for the game engine, P2. Source code for the scripting engine, Splice, are in the `splice/` subdirectory.\n\nThe following is a list of all known source code file names from a **prototype build** of the game. Note that it may be missing some files from the final build, and some files listed may not actually exist in the final build.\n\n```txt\nsplice/bif.cpp\nsplice/callstack.cpp\nsplice/error.cpp\nsplice/eval.cpp\nsplice/frame.cpp\nsplice/gc.cpp\nsplice/method.cpp\nsplice/pair.cpp\nsplice/proc.cpp\nsplice/ref.cpp\nsplice/serialize.cpp\nsplice/sidebag.cpp\nsplice/spliceutils.cpp\nsplice/splotheap.cpp\nsplice/vecmat.cpp\nac.c\nact.c\nactseg.c\nalarm.c\nalo.c\naseg.c\nasega.c\nbarrier.c\nbas.c\nbasic.c\nbbmark.c\nbez.c\nbinoc.c\nbis.c\nblend.c\nblip.c\nbomb.c\nbone.c\nbq.c\nbreak.c\nbrx.c\nbsp.c\nbutton.c\ncan.c\ncat.c\ncd.c\nchkpnt.c\nclip.c\nclock.c\ncm.c\ncnvo.c\ncoin.c\ncplcy.c\ncredit.c\ncrout.c\ncrusher.c\ncrv.c\ncycle.c\ndart.c\ndartgun.c\ndbg.c\ndialog.c\ndifficulty.c\ndl.c\ndmas.c\ndsp.c\ndysh.c\ndzg.c\nemitter.c\neyes.c\nfader.c\nfind.c\nflash.c\nfly.c\nfont.c\nfreeze.c\nfrm.c\nfrzg.c\ngame.c\ngeom.c\ngifs.c\nglbs.c\nglob.c\ngomer.c\ngs.c\nhg.c\nhide.c\nhnd.c\nhull.c\nik.c\njack.c\njlo.c\njoy.c\njp.c\njsg.c\njt.c\njump.c\nkeyhole.c\nlanding.c\nletters.c\nlgn.c\nlight.c\nlo.c\nlookat.c\nmain.c\nmap2d.c\nmap3d.c\nmark.c\nmat.c\nmb.c\nmecha.c\nmemcard.c\nmemory.c\nmenu.c\nmissile.c\nmouthgame.c\nmpeg.c\nmrkv.c\nms.c\nmurray.c\npath.c\nperf.c\nphasemem.c\npipe.c\npnt.c\npo.c\npose.c\nprog.c\nprompt.c\nproxy.c\nps2t/buildver.c\nps2t/spaprops.ic\npuffer.c\npzo.c\nrail.c\nrat.c\nrchm.c\nrender.c\nrip.c\nrog.c\nrope.c\nrumble.c\nrwm.c\nsampler.c\nsc.c\nscreen.c\nsensor.c\nshadow.c\nshape.c\nshd.c\nshdanim.c\nsky.c\nslotheap.c\nsm.c\nsmartguard.c\nso.c\nsolve.c\nsort.c\nsound.c\nspeaker.c\nspire.c\nsplicemap.c\nspliceobj.c\nsprbuf.c\nsqtr.c\nsquish.c\nstep.c\nstepact.c\nstepcane.c\nstepguard.c\nstephang.c\nstephide.c\nsteppipe.c\nsteppower.c\nsteprun.c\nstepside.c\nstepski.c\nstepzap.c\nstream.c\nsuv.c\nsw.c\ntail.c\ntank.c\ntarget.c\ntext.c\ntexture.c\nthread.c\ntn.c\ntransition.c\nturret.c\ntv.c\nub.c\nui.c\nunzip.c\nupdate.c\nutil.c\nvec.c\nvife.c\nvifs.c\nvis.c\nwater.c\nwaypoint.c\nwibu_ee.c\nwipe.c\nwm.c\nwr.c\nxform.c\nzap.c\n```\n\nLibrary sources in the prototype (not exhaustive):\n```txt\nbit.c\ncache.c\nclasses.c\ncsc.c\ndeci2.c\ndefhandler.c\ndiei.c\ndp-bit.c\neeloadfile.c\nevtwalk.c\nexit.c\nfilestub.c\nfp-bit.c\nglue.c\ngraphdev.c\ninit.c\ninitsys.c\ninl.c\nintr.c\niopreset.c\nipuinit.c\nklib.s\nkprintf.c\nlibdma.c\nlibipu.c\nlibosd.c\nlibpad.c\nlibscedemo.c\nmpc.c\npack.c\nshiftjis.c\nsifcmd.c\nsifrpc.c\ntlbfunc.c\ntlbtrap.s\ntty.c\nvar.c\nversion.h\nvu/vu.c\n```\n"
  },
  {
    "path": "tools/codematcher/LICENSE.txt",
    "content": "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n+ License for CodeMatcher\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\nMIT License\n\nCopyright (c) 2022 felinis\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "tools/codematcher/README.md",
    "content": "# Code Matching Guide\n\nThis guide will walk you through the process of matching your code against the Sly 1 May Prototype.\n\n## 1. Clone the repository\n\n```sh\ngit clone https://github.com/TheOnlyZac/sly1.git\n```\n\n## 2. Run the setup script\n\nThe setup script will download and install the compiler needed to compile the code and run CodeMatcher.\n\n### Linux\n```sh\ncd sly1/scripts\n./setup-progd-linux.sh\n```\n\n### Windows\n```powershell\ncd sly1\\scripts\n.\\setup-progd-windows.bat\n```\n\n## 3. Get the Sly 1 May Prototype ELF\n\nYou will need the Sly 1 May 2002 Prototype ELF for code matching. Download and and extract the ELF to the `tools/codematcher` folder (alongside `CodeMatcher.exe`). Rename it from `SCUS971.98` to `sly_proto.elf`.\n\n## 4. Match your code\n\nAfter you have written your code, you can use the scripts in the `scripts` folder to compile the code and match functions.\n\n* `match_all.sh` will compile the complete source tree and match all functions.\n* `match_file.sh <file>` will compile a single file and match all functions in that file.\n* `match_function_live.sh <file> <function>` will compile a single file and match a single function in that file.\n  * It will continuously dump the function bytes and print the disassembly to the console so you can compare it against the original.\n\nThese scripts will only work on Linux or WSL. If you are on Windows, you will have to run CodeMatcher manually from the command line.\n\n**Good luck, and have fun!**\n"
  },
  {
    "path": "tools/codematcher/ghidra_tips.txt",
    "content": "Useful tips when decompiling with Ghidra:\n- Never, ever use floating-point numbers without the 'f' as it will produce a code that is more than twice as bigger.\n  (example: write 1.0f, not 1.0 like Ghidra's decompiler likes to output)"
  },
  {
    "path": "tools/codematcher/match_all.cmd",
    "content": "@echo off\nCodeMatcher.exe sly_proto.elf -compile ../src/P2"
  },
  {
    "path": "tools/codematcher/match_single.cmd",
    "content": "@echo off\nREM use this script to quickly match one source file, just drag it on this CMD file...\nC:\\usr\\local\\sce\\ee\\gcc\\bin\\ee-gcc.exe -IC:\\usr\\local\\sce\\common\\include -IC:\\usr\\local\\sce\\ee\\gcc\\include\\g++-2 -g -O2 -x c++ -c %1 -o temp\\%1.o"
  },
  {
    "path": "tools/objdiff/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2022 Luke Street.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  }
]