## 1. Project Overview & Quickstart (zeldaret/oot)

## File: README.md

# The Legend of Zelda: Ocarina of Time

[![Build Status][gha-badge]][gha] [![Decompilation Progress][progress-badge]][progress] [![Contributors][contributors-badge]][contributors] [![Discord Channel][discord-badge]][discord]

[gha]: https://github.com/zeldaret/oot/actions/workflows/ci.yml?query=branch%3Amain+event%3Apush
[gha-badge]: https://img.shields.io/github/actions/workflow/status/zeldaret/oot/ci.yml

[progress]: https://zelda.deco.mp/games/oot
[progress-badge]: https://img.shields.io/endpoint?url=https://zelda.deco.mp/assets/csv/progress-oot-shield.json

[contributors]: https://github.com/zeldaret/oot/graphs/contributors
[contributors-badge]: https://img.shields.io/github/contributors/zeldaret/oot

[discord]: https://discord.zelda.deco.mp
[discord-badge]: https://img.shields.io/discord/688807550715560050?color=%237289DA&logo=discord&logoColor=%23FFFFFF

```diff
- WARNING! -

This repository is a work in progress, and while it can be used to make certain changes, it's still
constantly evolving. If you use it for modding purposes in its current state, please be aware that
the codebase can drastically change at any time. Also note that some parts of the ROM may not be
'shiftable' yet, so modifying them could be difficult at this point.
```

This is a WIP **decompilation** of ***The Legend of Zelda: Ocarina of Time***. The purpose of the project is to recreate a source code base for the game from scratch, using information found inside the game along with static and/or dynamic analysis. **It is not producing a PC port.** For more information you can get in touch with the team on our [Discord server][discord].

It builds the following versions:

| Name         | Build timestamp   | Description                               | MD5 hash of input ROM(s) |
|--------------|-------------------|-------------------------------------------|--------------------------|
| ntsc-1.0     | 98-10-21 04:56:31 | NTSC 1.0 (Japan/US)                       | `9f04c8e68534b870f707c247fa4b50fc``5bd1fe107bf8106b2ab6650abecd54d6` |
| ntsc-1.1     | 98-10-26 10:58:45 | NTSC 1.1 (Japan/US)                       | `1bf5f42b98c3e97948f01155f12e2d88``721fdcc6f5f34be55c43a807f2a16af4` |
| pal-1.0      | 98-11-10 14:34:22 | PAL 1.0 (Europe)                          | `e040de91a74b61e3201db0e2323f768a` |
| ntsc-1.2     | 98-11-12 18:17:03 | NTSC 1.2 (Japan/US)                       | `2258052847bdd056c8406a9ef6427f13``57a9719ad547c516342e1a15d5c28c3d` |
| pal-1.1      | 98-11-18 17:36:49 | PAL 1.1 (Europe)                          | `d714580dd74c2c033f5e1b6dc0aeac77` |
| gc-jp        | 02-10-29 23:49:53 | GameCube Japan                            | `33fb7852c180b18ea0b9620b630f413f` |
| gc-jp-mq     | 02-10-30 00:15:15 | GameCube Japan Master Quest               | `69895c5c78442260f6eafb2506dc482a` |
| gc-us        | 02-12-19 13:28:09 | GameCube US                               | `cd09029edcfb7c097ac01986a0f83d3f` |
| gc-us-mq     | 02-12-19 14:05:42 | GameCube US Master Quest                  | `da35577fe54579f6a266931cc75f512d` |
| gc-eu-dbg-2  | 03-02-13 19:46:49 | GameCube Europe/PAL Debug (earlier build) | `ab1ca59d0039e3b34d82db650b54d7b9``2814fde8d6cfe23a220de6be955b4196` |
| gc-eu-mq-dbg | 03-02-21 00:16:31 | GameCube Europe/PAL Master Quest Debug    | `75e344f41c26ec2ec5ad92caa9e25629``8ca71e87de4ce5e9f6ec916202a623e9``f751d1a097764e2337b1ac9ba1e27699``dde376d47187b931820d5b2957cded14` |
| gc-eu-dbg    | 03-02-21 00:49:18 | GameCube Europe/PAL Debug                 | `3c10b67a76616ae2c162def7528724cf``382dc484e317d6522745c95387e7d5b9` |
| gc-eu        | 03-02-21 20:12:23 | GameCube Europe/PAL                       | `2c27b4e000e85fd78dbca551f1b1c965` |
| gc-eu-mq     | 03-02-21 20:37:19 | GameCube Europe/PAL Master Quest          | `1618403427e4344a57833043db5ce3c3` |
| gc-jp-ce     | 03-10-08 21:53:00 | GameCube Japan (Collector's Edition Disc) | `0c13e0449a28ea5b925cdb8af8d29768` |
| ique-cn      | 03-10-22 16:23:19 | iQue Player (Simplified Chinese)          | `0ab48b2d44a74b3bb2d384f6170c2742` |

The default version is `gc-eu-mq-dbg`, i.e. the GameCube Europe/PAL Master Quest Debug ROM.

**Note: This repository does not include any of the assets necessary to build the ROM. A prior copy of the game is required to extract the needed assets.**

**Website:** <https://zelda.deco.mp>

**Discord:** <https://discord.zelda.deco.mp>

## Installation

We recommend using WSL on Windows, or native Linux, which the rest of this readme describes. We currently have instructions for

* [Windows](#Windows), with and without WSL
* [macOS](docs/BUILDING_MACOS.md)
* [Linux](#Linux-Native-or-under-WSL--VM), natively or using WSL / VM
* [Docker](docs/BUILDING_DOCKER.md)

(These will also depend on the Linux instructions.)
Some of these may also be out of date or unmaintained; usually our contributors use WSL, Linux, and macOS, so these instructions should be up to date.

### Windows

For Windows 10 or 11, install WSL and a distribution by following this
[WSL Installation Guide](https://learn.microsoft.com/en-us/windows/wsl/install).
We recommend using Ubuntu as the Linux distribution.

For older versions of Windows, install a Linux VM or refer to [Docker](docs/BUILDING_DOCKER.md) instructions.


### Linux (Native or under WSL / VM)

#### 1. Install build dependencies

The build process has the following package requirements:

* git
* build-essential
* curl
* python3
* python3-pip
* python3-venv
* libxml2-dev

Python 3.10+ is required.

Under Debian / Ubuntu (which we recommend using), you can install them with the following commands:

```bash
sudo apt-get update
sudo apt-get install git build-essential curl python3 python3-pip python3-venv libxml2-dev
```

In addition to these packages, a MIPS binutils installation is required. The project aims to support a couple of commonly-encountered MIPS toolchains out-of-the-box, only one is required and is automatically detected:

* mips64-ultra-elf- or mips64- from the [practicerom toolchain](https://github.com/PracticeROM/packages)
* mips64-elf- from the [libdragon n64 homebrew library](https://github.com/DragonMinded/libdragon/releases/tag/toolchain-continuous-prerelease)
* mips-linux-gnu- or mips64-linux-gnu- found in common distribution package managers as e.g. `binutils-mips-linux-gnu`

If none of these are available to install, the makefile exposes `MIPS_BINUTILS_PREFIX` as a means to set your own toolchain prefix. Otherwise, consider building one of the first two options from source.

If you are using GCC as the compiler for Ocarina of Time, you will also need the corresponding gcc compiler for the chosen toolchain. For the first two options above, gcc is included automatically. For mips-linux-gnu- or mips64-linux-gnu- it is often a separate package, e.g. `gcc-mips-linux-gnu`.

#### 2. Clone the repository

**N.B.** If using WSL, we strongly encourage you to clone into WSL's Linux filesystem using Linux's `git`.
Cloning into the Windows filesystem will result in much slower read/write speeds, and often causes issues when Windows copies the files with the wrong line endings, which the compiler IDO cannot handle correctly.

Clone `https://github.com/zeldaret/oot.git` where you wish to have the project, with a command such as:

```bash
git clone https://github.com/zeldaret/oot.git
```

This will copy the GitHub repository contents into a new folder in the current directory called `oot`. Change into this directory before doing anything else:

```bash
cd oot
```

#### 3. Prepare a base ROM

First, pick the version of the game you want to build.
The supported versions and ROM checksums can be found in the table above.
As an example, the `ntsc-1.0` version will be used in these instructions.

Place a copy of the ROM inside the `baseroms//` folder for your version of choice.
For example for `ntsc-1.0`, inside the `baseroms/ntsc-1.0/` folder.
If you are under WSL, you can run the command `explorer.exe .` to open the current directory in the Windows file explorer.

Rename the file to `baserom.z64`, `baserom.n64` or `baserom.v64`, depending on the original extension.

#### 4. Setup the ROM and build process

Setup and extract everything from your ROM with the following command:

```bash
make setup VERSION=
```

For example for `ntsc-1.0`, run `make setup VERSION=ntsc-1.0`.

This downloads some dependencies (from pip), and compiles tools for the build process.
Then it generates a new ROM `baseroms//baserom-decompressed.z64`.
For retail (non-debug) versions, that ROM will be the decompressed equivalent of the ROM.
For the `gc-eu-mq-dbg` version, that ROM will have the overdump removed and the header patched.
The other debug ROMs `gc-eu-dbg-2` and `gc-eu-dbg` will also have the overdump removed.
It will also extract the individual assets from the ROM.

#### 5. Build the ROM

Run make to build the ROM.
Make sure your path to the project is not too long, otherwise this process may error.

```bash
make VERSION=
```

For example for `ntsc-1.0`, run `make VERSION=ntsc-1.0`

If all goes well, a new ROM should be built at `build//oot-.z64` (for example `build/ntsc-1.0/oot-ntsc-1.0.z64`), and the following text printed:

```
build//oot-.z64: OK
```

If you instead see the following:

```
build//oot-.z64: FAILED
md5sum: WARNING: 1 computed checksum did NOT match
```

This means that the built ROM isn't the same as the base one, so something went wrong or some part of the code doesn't match.

**NOTE:** to speed up the build, you can either:

* pass `-jN` to `make setup` and `make`, where N is the number of threads to use in the build. The generally-accepted wisdom is to use the number of virtual cores your computer has.
* pass `-j` to `make setup` and `make`, to use as many threads as possible, but beware that this can use too much memory on lower-end systems.

Both of these have the disadvantage that the ordering of the terminal output is scrambled, so for debugging it is best to stick to one thread (i.e. not pass `-j` or `-jN`).

## Changing build options

By default, if you don't specify a version to build with `VERSION=` in the make commands, the `gc-eu-mq-dbg` version is used.
This default can be changed in the Makefile.

The project Makefile is fairly configurable and can also be used to prepare the repo for modding.
See the options outlined at the top of the Makefile for more information.

## Contributing

All contributions are welcome. This is a group effort, and even small contributions can make a difference.
Some tasks also don't require much knowledge to get started.

Most discussions happen on our [Discord Server][discord], where you are welcome to ask if you need help getting started, or if you have any questions regarding this project and other decompilation projects.

---

## File: docs/audio/Samplebank_XML.md

# Samplebank XML Format Specification

Samplebank XMLs describe a samplebank file that contains compressed waveform data. It specifies which sample files to include as well as certain global properties such as the index of this samplebank.

---

```xml
<SampleBank
    Name="<C Indentifier>"
    Index=""
    Medium="<Medium>"
    CachePolicy="<CachePolicy>"
    BufferBug="[bool]"
>
```
Begins a new samplebank.

**Attributes**

- **Name**: The name of the samplebank.
- **Index**: The index of the samplebank for the samplebank table. Must be a unique index for all samplebanks and pointers.
- **Medium**: The storage medium, from the `SampleMedium` enum.
- **CachePolicy**: The cache policy, from the `AudioCacheLoadType` enum.
- [Optional] **BufferBug**: Whether this samplebank suffers from a buffer clearing bug present in the original audio tools. For matching only.

**Tags**

-
    ```xml
    "
    />
    ```
    Create an alternate index that refers to this samplebank.

    **Attributes**

    - **Index**: The alternative index, must be unique among all samplebanks and pointers.

    ---

-
    ```xml
    <Sample
        Name="<C Identifier>"
        Path=""
    />
    ```
    Adds a **compressed** sample file to the samplebank. The sample should be single-channel and big-endian, in a format that is recognizable by the audio driver such as: pcm16, vadpcm, or half-frame vadpcm.

    **Attributes**

    - **Name**: Name of this sample. Must be a valid C language identifier.
    - **Path**: Path to aifc file relative to the project root (typically in `$(BUILD_DIR)/assets/audio/samples/`)

    ---

-
    ```xml
    "
        Path=""
    />
    ```
    Adds a binary blob to the samplebank. Intended for matching only when data cannot be identified.

    **Attributes**

    - **Name**: Name of this blob. Must be a valid C language identifier.
    - **Path**: Path to binary file, relative to the project root (typically in `$(BUILD_DIR)/assets/audio/samples/`)

    ---

```xml
</SampleBank>
```
---

---

## File: docs/audio/Soundfont_XML.md

# Soundfont XML Format Specification

Soundfont XMLs describe the layout of a single soundfont. These package raw samples together into instruments, of which there are three kinds:
- **Effects**: These are simple sound effects that just play a single sample without any modulation.
- **Drums**: These define a MIDI-style percussion key map.
- **Instruments**: These are instruments that may be played at any key with up to three voices and may be modulated by an envelope.

In the specification, `Note Name`s can be either a MIDI note name e.g. `C4` or it may be a **Zelda64** note number, which are related to MIDI note numbers ($n$) by $(n - 21) \mod 128$.

---

```xml
<Soundfont
    Name="<C Identifier>"
    Index=""
    Medium="<Medium>"
    CachePolicy="<CachePolicy>"
    SampleBank=""
    Indirect="[uint]"
    SampleBankDD="[Path]"
    IndirectDD="[uint]"
    LoopsHaveFrames="[bool]"
    PadToSize="[uint]"
    NumInstruments="[uint]"
>
```
Begins a new soundfont.

**Attributes**
- **Name**: Soundfont symbol name. Must be a valid C identifier.
- **Index**: Soundfont index. Must be an integer.
- **Medium**: Storage medium. Must be an enum name from `SampleMedium`.
- **CachePolicy**: Cache policy. Must be an enum name from `AudioCacheLoadType`.
- **SampleBank**: Path to samplebank xml used by this soundfont.
- [Optional] **Indirect**: Pointer index if the samplebank is referenced indirectly.
- [Optional] **SampleBankDD**: Path to samplebank xml used for DD medium.
- [Optional] **IndirectDD**: Pointer index if the DD samplebank is referenced indirectly.
- [Optional] **LoopsHaveFrames**: Whether loops in this soundfont store the total frame count of the sample. Must be a boolean.
- [Optional] **PadToSize**: For matching only. Specifies the total file size the result output should be padded to.
- [Optional] **NumInstruments**: For matching only. Specifies the total number of instrument pointers. Usually this is automatically assigned based on `max(program_number) + 1` but some vanilla banks don't match this way.

**Tags**

-
    ```xml
    <Envelopes>
    ```
    Lists envelopes defined in this soundfont.

    **Attributes**

    N/A

    **Tags**

    -
        ```xml
        <Envelope
            Name="<C Identifier>"
            Release=""
        >
        ```
        Starts a new envelope.

        **Attributes**

        - **Name**: Unique name for this envelope. Must be a valid C identifier.
        - **Release**: Release rate index (into `gAudioCtx.adsrDecayTable`) for this envelope

        **Tags**

        -
            ```xml
            "
                Arg="<s16>"
            />
            ```
            Add a point to the envelope at (delay, arg)

            **Attributes**

            - **Delay**: Duration until the next point
            - **Arg**: Value of the envelope at this point

            ---

        -
            ```xml
            <Disable/>
            ```
            Insert a ADSR_DISABLE command

            ---

        -
            ```xml
            <Hang/>
            ```
            Insert a ADSR_HANG command

            ---

        -
            ```xml
            <Goto
                Index=""
            />
            ```
            Insert a ADSR_GOTO command

            **Attributes**

            - **Index**: Index of the envelope point to jump to

            ---

        ```xml
        </Envelope>
        ```
        ---

    ```xml
    </Envelopes>
    ```
    ---

-
    ```xml
    <Samples
        IsDD="[Bool]"
        Cached="[Bool]"
    >
    ```
    Begins a list of samples used in this Soundfont.

    **Attributes**

    - [Optional] **IsDD**: Whether all the samples in the list are on the Disk Drive. The sample data will come from the samplebank `SampleBankDD`. **Default is `false`.** **NOTE this is not fully implemented, it should always be `false`.**
    - [Optional] **Cached**: Whether all the samples in the list should be added to the `usedSamples` cache. **Default is `false`.**

    **Tags**

    -
        ```xml
        <Sample
            Name="<C Identifier>"
            SampleRate="[Sample Rate]"
            BaseNote="[Note Name]"
            FineTune="[Fine Tune]"
            IsDD="[Bool]"
            Cached="[Bool]"
        />
        ```
        Declares a sample used in this soundfont.

        **Attributes**

        - **Name**: The name of this sample. A sample with this name must be present in the samplebank used by the soundfont.
        - [Optional] **SampleRate**: An overriding sample rate for this sample. **Default comes from the sample file.**
        - [Optional] **BaseNote**: An overriding root key for this sample. **Default comes from the sample file.**
        - [Optional] **FineTune**: An overriding fine tuning for this sample, in cents, in the range [-100, 100]. **Default comes from the sample file.**
        - [Optional] **IsDD**: Whether this sample is on the Disk Drive. The sample data will come from the samplebank `SampleBankDD`. **Default is `false`.** **NOTE this is not fully implemented, it should always be `false`.**
        - [Optional] **Cached**: Whether this sample should be added to the `usedSamples` cache. **Default is `false`.**

        ---

    ```xml
    </Samples>
    ```
    ---

-
    ```xml
    <Effects>
    ```
    Begins a list of sound effects to define for this soundfont. Sound effects correspond to simple sounds that cannot be played at different keys.

    **Attributes**

    N/A

    **Tags**

    -
        ```xml
        <Effect
            Name="<C Identifier>"
            Sample="<Sample Name>"
            SampleRate="[Sample Rate]"
            BaseNote="[Note Name]"
            FineTune="[Fine Tune]"
        />
        ```
        Defines a single sound effect.

        **Attributes**
        - **Name**: The name of the sound effect, the name is made available in sequence files in the form `SF{n}_{name}` where `n` is the index of this soundfont and `name` is this name. For example, if `n=0` and `name=ExampleEffect` the name to use in sequence files is `SF0_ExampleEffect`.
        - **Sample**: The name of the sample associated with this effect.
        - [Optional] **SampleRate**: An overriding sample rate for this effect. **Default comes from the sample definition.**
        - [Optional] **BaseNote**: An overriding root key for this effect. **Default comes from the sample definition.**
        - [Optional] **FineTune**: An overriding fine tuning for this effect, in cents, in the range [-100, 100]. **Default comes from the sample definition.**

        ---

    ```xml
    </Effects>
    ```
    ---

-
    ```xml
    <Drums>
    ```
    Begins the percussion definitions for this soundfont. Percussion corresponds to the MIDI notion of percussion, where single samples are mapped across a range of keys.

    **Attributes**

    N/A

    **Tags**

    -
        ```xml
        <Drum
            Name="<C Identifier>"
            Note="[Note Name]"
            NoteStart="[Note Name]"
            NoteEnd="[Note Name]"
            Pan=""
            Envelope="<Envelope Name>"
            Release="[u8]"
            Sample="<Sample Name>"
            SampleRate="[Sample Rate]"
            BaseNote="[Note Name]"
            FineTune="[Fine Tune]"
        />
        ```
        Defines a single percussion range.

        **Attributes**
        - **Name**: The name of this sound. Definitions are emitted for sequence files in the form `SF{n}_{name}_{note}` for every note covered by this sound.
        - [Optional] **Note**: The key to map this sound to. Should not overlap with other definitions. **If this field is left unspecified, `NoteStart` and `NoteEnd` become required.**
        - [Optional] **NoteStart**: The first key that is mapped to this sound. Should not overlap with other definitions. **If this field is left unspecified, `Note` becomes required. If this field is specified, `NoteEnd` must also be specified.**
        - [Optional] **NoteEnd**: The last key that is mapped to this sound. Should not overlap with other definitions. **If this field is left unspecified, `Note` becomes required. If this field is specified, `NoteStart` must also be specified.**
        - **Pan**: The stereo weight for this sound. Center=`64`.
        - **Envelope**: The envelope to modulate the volume over time with. Must be defined in the `Envelopes` list.
        - [Optional] **Release**: An override for the envelope release rate. **Default is the release rate specified in the envelope definition**
        - **Sample**: The name of the sample to use.
        - [Optional] **SampleRate**: An overriding sample rate for this sound. **Default comes from the sample definition.**
        - [Optional] **BaseNote**: An overriding root key for this sound. **Default comes from the sample definition.**
        - [Optional] **FineTune**: An overriding fine tuning for this sound, in cents, in the range [-100, 100]. **Default comes from the sample definition.**

        ---

    ```xml
    </Drums>
    ```
    ---

-
    ```xml
    
    ```
    Begins the instrument definitions for this soundfont. Instruments correspond to the MIDI notion of instruments, with up to 3 samples (voices) per instrument that must map to contiguous ranges of notes.

    **Attributes**

    N/A

    **Tags**

    -
        ```xml
        "
            Name="<C Identifier>"
            Envelope="<Envelope Name>"
            Release="[u8]"

            Sample="<Sample Name>"
            SampleRate="[Sample Rate]"
            BaseNote="[Note Name]"
            FineTune="[Fine Tune]"

            RangeLo="[Note Name]"
            SampleLo="[Sample Name]"
            SampleRateLo="[Sample Rate]"
            BaseNoteLo="[Note Name]"
            FineTuneLo="[Fine Tune]"

            RangeHi="[Note Name]"
            SampleHi="[Sample Name]"
            SampleRateHi="[Sample Rate]"
            BaseNoteHi="[Note Name]"
            FineTuneHi="[Fine Tune]"
        />
        ```
        Defines an instrument.

        **Attributes**
        - **ProgramNumber**: MIDI Program Number for this instrument. Must be in the range `0 <= n <= 125`
        - **Name**: The name of this instrument.
        - **Envelope**: Envelope to use, identified by name.
        - [Optional] **Release**: Release rate index override. **Default release rate comes from the chosen envelope.**
        - **Sample**: The name of the middle sample to use for this instrument.
        - [Optional] **SampleRate**: Sample rate override for the middle sample. **Default is sourced from the sample properties.**
        - [Optional] **BaseNote**: Base note override for the middle sample. **Default is sourced from the sample properties.**
        - [Optional] **FineTune**: Fine tuning override for the middle sample, in cents, in the range [-100, 100]. **Default is sourced from the sample properties.**
        - [Optional] **RangeLo**: The largest note for SampleLo. SampleLo will be used instead of Sample for keys in the range [0, RangeLo]. **If left unspecified, SampleLo must not be specified. If specified, SampleLo must be specified.**
        - [Optional] **SampleLo**: The name of the low sample to use for this instrument.
        - [Optional] **SampleRateLo**: Sample rate override for the low sample. **Default is sourced from the sample properties.**
        - [Optional] **BaseNoteLo**: Base note override for the low sample. **Default is sourced from the sample properties.**
        - [Optional] **FineTuneLo**: Fine tuning override for the low sample, in cents, in the range [-100, 100]. **Default is sourced from the sample properties.**
        - [Optional] **RangeHi**: The smallest note for SampleHi. SampleHi will be used instead of Sample for keys in the range [RangeHi, 127]. **If left unspecified, SampleHi must not be specified. If specified, SampleHi must be specified.**
        - [Optional] **SampleHi**: The name of the high sample to use for this instrument.
        - [Optional] **SampleRateHi**: Sample rate override for the high sample. **Default is sourced from the sample properties.**
        - [Optional] **BaseNoteHi**: Base note override for the high sample. **Default is sourced from the sample properties.**
        - [Optional] **FineTuneHi**: Fine tuning override for the high sample, in cents, in the range [-100, 100]. **Default is sourced from the sample properties.**

        ---

    ```xml
    
    ```
    ---

```xml
</Soundfont>
```
---

---

## File: docs/BUILDING_DOCKER.md

# Building using Docker

## 1. Setup requirements

To use Docker, you'll need either Docker Desktop or Docker Toolbox installed and setup based on your system.

On Ubuntu, Docker and required tools can be installed with: `sudo apt install docker.io docker-compose docker-buildx`

You'll also need to prepare a local version of the project with a copied base ROM (see steps [2](../README.md#2-clone-the-repository) and [3](../README.md#3-prepare-a-base-rom) of the Linux instructions).

## 2. Create and start the Docker image build

From the root of your local project, run the following command:

```bash
docker-compose up --build
```

This should immediately begin steps [4](../README.md#4-setup-the-rom-and-build-process) and [5](../README.md#5-build-the-rom) within the Docker container.

## 3. Shell into the 'oot' container

To exec into the oot Docker image at any time, run the following command either during or after the build:

```bash
docker-compose exec oot bash
```

---

## File: docs/BUILDING_MACOS.md

# Building on macOS

**N.B.** C++17 is required to build the asset processing program that we use (ZAPD), so check your OS version can support this before proceeding.


## 1. Dependencies

For macOS, use Homebrew to install the following dependencies:

* coreutils
* make
* python3
* bash
* clang-format
* libxml2
* libiconv

You can install them with the following commands:

```bash
brew update
brew install coreutils make python3 bash clang-format libxml2 libiconv
```

(The repository expects Homebrew-installed programs to be either linked correctly in `$PATH` etc. or in their default locations.)


## 2. Building mips-linux-binutils

The following instructions are written for MacOS users but should apply to any Unix-like system, with maybe some modifications at the end regarding the bash_profile.

Create destination dir for binutils
```bash
sudo mkdir -p /opt/cross
```

Create and enter local working dir
```bash
mkdir ~/binutils-tmp
cd ~/binutils-tmp
```

Get and extract binutils source
```bash
curl -O https://ftp.gnu.org/gnu/binutils/binutils-2.46.0.tar.xz
tar xjf binutils-2.46.0.tar.xz
```

Create and enter a build directory
```bash
mkdir build-binutils
cd build-binutils
```

Configure the build
```bash
../binutils-2.46.0/configure --target=mips-linux-gnu --prefix=/opt/cross --with-system-zlib --disable-gprof --disable-gdb --disable-werror
```

Make and install binutils
```bash
make -j$(nproc)
sudo make install
```

Edit your `~/.bash_profile`/`~/.zprofile` (or whichever shell you use) to add the new binutils binaries to the system PATH
```bash
echo 'export PATH="$PATH:/opt/cross/bin"' >> ~/.bash_profile
```

Reload `~/.bash_profile` (or just launch a new terminal tab)
```bash
source ~/.bash_profile
```

If this worked, you can now delete the temporary directory `~/binutils-tmp`.


## 3. Final note

Apple's version of `make` is very out-of-date, so you should use the brew-installed `gmake` in place of `make` in this repo from now on.

You should now be able to continue from [step 2](../README.md#2-clone-the-repository) of the Linux instructions.


## 4. Building GCC (optional)

If you'd like to compile with GCC instead of IDO (e.g. for modding), you can build it from source similarly to how we built binutils:

Install dependences
```bash
brew install gcc@15 gmp isl libmpc mpfr
```

Create and enter local working dir
```bash
mkdir ~/gcc-tmp
cd ~/gcc-tmp
```

Get and extract gcc source
```bash
curl -O https://ftp.gnu.org/gnu/gcc/gcc-15.2.0/gcc-15.2.0.tar.xz
tar xvf gcc-15.2.0.tar.xz
```

Create and enter a build directory
```bash
mkdir build-gcc
cd build-gcc
```

Configure the build
```bash
CC=gcc-15 CXX=g++-15 ../gcc-15.2.0/configure --target=mips-linux-gnu --prefix=/opt/cross --disable-nls --enable-languages=c --with-gmp=$(brew --prefix)/opt/gmp --with-mpfr=$(brew --prefix)/opt/mpfr --with-mpc=$(brew --prefix)/opt/libmpc --with-isl=$(brew --prefix)/opt/isl
```

Make and install gcc
```bash
CC=gcc-15 CXX=g++-15 make all-gcc -j$(nproc)
sudo make install-gcc
```

If this worked, you can now delete the temporary directory `~/gcc-tmp`.

---

## File: docs/compilers.md

# Compilers

Ocarina of Time was written mostly in C, compiled to MIPS machine code. For the
N64 and GameCube versions, all code was compiled with the IDO compiler. For the
iQue Player versions, some of the code (namely libultra, and some game files
such as those related to Chinese text) was compiled with the EGCS compiler instead.

## IDO

Ocarina of Time was originally developed on
[Silicon Graphics "Indy"](https://en.wikipedia.org/wiki/SGI_Indy) workstations,
and IDO (IRIS Development Option) was the C compiler toolchain that shipped with
these. Two different versions of IDO were used for Ocarina of Time: IDO 5.3 was
used for some libraries (namely libultra, libleo, and the JPEG library) while
IDO 7.1 was used for the other libraries and all of the "main" game code.

These Silicon Graphics workstations ran the MIPS-based IRIX operating system, so
the original compiler binaries can't run on modern systems. Originally this
project used [qemu-irix](https://github.com/n64decomp/qemu-irix) (now
unmaintained) to run emulate IRIX on modern systems, but nowadays we use the
more lightweight
[ido-static-recomp](https://github.com/decompals/ido-static-recomp) instead.

## EGCS

[EGCS (Experimental/Enhanced GNU Compiler System)](https://en.wikipedia.org/wiki/GNU_Compiler_Collection#EGCS_fork)
was a fork of the GCC compiler. The Linux-based iQue SDK included a patched
version of EGCS release 1.1.2. The original compiler can still run on modern Linux
systems, but we use a
[modified version](https://github.com/decompals/mips-gcc-egcs-2.91.66)
that includes Mac support and a few other minor improvements (such as anonymous
struct/union support).

This version of the EGCS compiler has a bug where code that indexes into an array member can
fail to compile if the array member is at a large (>= 0x8000) offset in a struct. For
example, when run on the source code

```c
struct Foo {
    char a[0x8000];
    int b[1];
};

int test(struct Foo* foo, int i) {
    return foo->b[i];
}
```

the compiler errors with

```
Compiler error: src.c: In function `test':
src.c:8: internal error--unrecognizable insn:
(insn 20 18 22 (set (reg:SI 85)
        (plus:SI (reg:SI 81)
            (const_int 32768))) -1 (nil)
    (nil))
../../gcc/toplev.c:1367: Internal compiler error in function fatal_insn
```

In some recompiled files, the game developers had to modify the code to work
around this bug, for example by storing a pointer to the array in a temporary
variable before indexing into it.

---

## File: docs/decompiling_tutorial.md

This repository used to contain a tutorial for how to do
decompilation work in the repo.

It has been less useful as more and more was decompiled,
and also more of a chore to keep up-to-date, so it has been
removed from the repo.

It is still interesting for historical purposes or for
curiosity, you can find the last version of it in revision
[9963e7f5d5fa8caee329f6b40e393d8a2c45390b](https://github.com/zeldaret/oot/blob/9963e7f5d5fa8caee329f6b40e393d8a2c45390b/docs/tutorial/contents.md).

---

## File: docs/Documenting.md

# Documentation Style Guide

This project uses [Doxygen](https://www.doxygen.nl/index.html) to generate documentation pages from comments found in the source files. This guide focuses on writing compatible comments and ensuring consistency across the codebase.

However to keep the documentation readable in text and favor consistency, the Doxygen commands that should be used are restricted to what this document mentions.

To generate a doxygen manual for the project, ensure you have doxygen installed and then cd into the project root directory and run `doxygen Doxyfile`.

The documentation can then be browsed by opening `docs/doxygen/html/index.html` in a web browser.

## Documenting Functions

Any comments inside functions, except bugs ([see below](#documenting-bugs)), should use `//`-style comments, even if spanning over multiple lines.

A simple example of documenting a function with just a description (note the leading `/**`):

```c
/**
 * Update the crawl sound timer, and play the crawling sound when it reaches 0.
 */
void EnInsect_UpdateCrawlSfx(EnInsect* this) {
```

A more complete example:

```c
/**
 * Request to either increase or consume magic.
 *
 * @param amount the positive-valued amount to either increase or decrease magic by
 * @param type how the magic is increased or consumed.
 *
 * @return false if the request failed
 */
s32 Magic_RequestChange(PlayState* play, s16 amount, s16 type) {
```

Note:

- Documentation for self-explanatory arguments (`@param`) and return values (`@return`) may be omitted.
- `@param` commands should not have empty lines in between.
- Different commands (main description, `@param`, `@return`, ...) should be separated by empty lines.

Other directives that may be used for documenting functions:

- `@see` to reference something else ([see below](#linking-related-information)).
- `@note` to bring attention to some of the function behavior.

## Documenting Variables

In case the name of a variable isn't completely clear, documentation can provide a description.

If applicable, it may refer to a set of defines or enumerations that should be used with it (those should be linked with `@see`, [see below](#linking-related-information)).

```c
/**
 * My description of this variable
 */
s32 foo;
```

## Documenting Files

File documentation should be located at the top of the file, above `#include`s.

File documentation should only feature information that is general to the file or the system it implements.

```c
/**
 * @file z_fcurve_data_skelanime.c
 * @brief Curve skeleton animation system
 *
 * A curve skeleton has a fixed number of limbs, ...
...
 */
```

## Other

### Documenting Bugs:

Bugs should be documented on the line above where the bug begins.

```c
//! @bug Missing early return
```

Bug described on multiple lines should still use the `//!` syntax, over multiple lines. For example:

```c
//! @bug this code was clearly meaning to print `abs(camera->camDataIdx)` as a
//! one-or-two-digit number, instead of `i`.
```

### Linking related information:

`@see` should be used to provide links to related information where appropriate, for example:

```c
/**
 * Sets the next framebuffer to the framebuffer associated to `task`.
 * If there is no current buffer or it is time to swap, this buffer will be swapped to
 * immediately, otherwise it will be swapped to later in Sched_HandleRetrace.
 *
 * @see Sched_HandleRetrace
 */
void Sched_SetNextFramebufferFromTask(Scheduler* sc, OSScTask* task) {
```

In the case of functions, `@see` should come before the first `@param`.

`@see` may also be used for documenting files or variables.

### HTML and LaTeX

It is possible to include HTML and LaTeX in documentation comments.

However it is prefered not to do so, so that the raw text stays readable when looked at as plain text, for example when browsing the source code.

---

## File: docs/libu64.md

# libu64

This document explains the reasoning behind organizing the libu64 files.

libu64 is known about from the Animal Crossing (GameCube) map files.

Here is the relevant excerpt from the Doubutsu no Mori+ 1.0 map file (for .text):

```
/* Detailed source-code truncated for AI context efficiency. */
```

This repository's `debug.c` (formerly `logutils.c`), `gfxprint.c` and `pad.c` (formerly `padutils.c`) line up with the map.

Note `debug.c` has additional debug-only functions in gc-eu-mq-dbg, hinting that there were two versions of libu64, a debug version and a non-debug version.

Additionally `debug.c`, `gfxprint.c` and `pad.c` all require compilation flags `-O2` (instead of `-O2 -g3`) to match, as supplementary evidence these were part of a separately compiled library.

`-O2` is also required for most files between `gfxprint.c` and `pad.c` in the code segment (see spec), hinting that these other files (`loadfragment2_n64.c`, `loadfragment2_gc.c`, `mtxuty-cvt.c`, `relocation_gc.c`, `load_gc.c`, `system_heap.c`) are also part of libu64.

Files `rcp_utils.c` and `logseverity_gc.c` do not strictly require `-O2`, but they do match with `-O2`.

`padsetup.c` also requires `-O2`.

On the other hand, the function `Overlay_Load` (in `loadfragment2_n64.c` or `load_gc.c` depending on game version) calls `DmaMgr_RequestSync`, a function that is not part of libu64.
This could suggest these files are not part of libu64, but the other evidence detailed above seems stronger.
It is also a possibility that libu64 expected users to provide the function, and it would have been an undefined symbol in the library.

All in all this suggests all files in code between the audio code and libc64, are part of libu64.

In the OoT boot segment, `stackcheck.c` is right next to `debug.c` and requires `-O2`: this hints `stackcheck.c` could be part of libu64 too. This is confirmed by looking at Majora's Mask n64-us, where `stackcheck.c` is in the middle of other libu64 files in the boot segment (see MM spec).

---

## File: docs/retail_versions.md

# Decompiling retail versions

The next decompilation target for OOT is NTSC version 1.2
(`ntsc-1.2`), because it is the N64 version that is most similar to the GC
versions. Unfortunately there are still a lot of differences,
but once this version is done, future
N64 versions should be much easier, as the changes between N64 versions are
small in comparison.

Instead of `cp`ing a matching build into `expected/`, the target ROM is disassembled as `.s` files then
reassembled as `.o` files directly into `expected/build/ntsc-1.2` for diff tools.
This allows us to make progress matching code in parallel with solving other
problems (such as the build system, ROM organization, and BSS ordering). The
files in `tools/disasm/ntsc-1.2` say how to split the source files and where the
functions and variables are in the target ROM, and these may need to be updated
if there are mistakes or if function names change due to documentation work.

Unfortunately, the disassembly is not perfect, so a "correct" decompilation might
still show diffs with data symbols. We might improve this later, but these data
diffs are fine to ignore for now.

For register and stack allocation differences, often the code can be tweaked so
that it matches both the retail ROM while continuing to match GC versions and the Debug ROM (for
example, by reordering assignments or moving a local variable declaration inside
an `if` block). Since retail MM versions currently target N64, checking MM decomp for similar code can help.

We can handle code that is different between versions by adding
`#if PLATFORM_N64 ... #endif` or `#if PLATFORM_GC ... #endif` around these parts of the
code. In order to keep the code readable, we should try to minimize the amount of
`#if` noise whenever possible.

## Setup

1.  Copy your target JP NTSC 1.2 ROM to `baseroms/ntsc-1.2/baserom.z64`

1.  Build the non-matching test ROM by running

    ```sh
    make setup -jN VERSION=ntsc-1.2
    make -jN VERSION=ntsc-1.2
    ```

    where `N` is the number of cores on your machine. This will build into
    `build/ntsc-1.2` and produce `build/ntsc-1.2/oot-ntsc-1.2.z64`.

    If you later want to delete all output files, run

    ```sh
    make clean VERSION=ntsc-1.2
    ```

1.  Disassemble the target ROM by running

    ```sh
    make disasm VERSION=ntsc-1.2
    ```

    The outputs will be written to `expected/build/ntsc-1.2`.

    Note that if you need to copy a matching build for another version, you can use e.g.

    ```sh
    mkdir -p expected/build
    cp -r build/gc-eu-mq-dbg expected/build
    ```

    to avoid clobbering the disassembly.

## Diff Tools

Note that many tools will require activating the Python virtual environment
in your terminal session. To do this, run:

```sh
source .venv/bin/activate
```

### retail_progress.py

Running `./retail_progress.py path/to/file.c` will attempt to figure out which functions
in a file still need to match for `ntsc-1.2`. To get an overview of diffs for
all files, run `./retail_progress.py` with no arguments.

### asm-differ / diff.py

To diff assembly for a single function in `ntsc-1.2`, run e.g.

```sh
./diff.py -mwo3 -v ntsc-1.2 Math3D_CylTriVsIntersect
```

The `-v` flag tells `diff.py` to compare between `build/ntsc-1.2` and
`expected/build/ntsc-1.2`, and to use `make VERSION=ntsc-1.2` when rebuilding.

You may also want to diff versions `gc-eu-mq` and/or `gc-eu-mq-dbg` in another terminal
to ensure any changes still match there.

### Permuter and decomp.me

Disassembly for individual functions is written to
`expected/build/ntsc-1.2/functions`, so to get a [decomp.me](https://decomp.me/) scratch you can run
e.g.

```sh
decomp-permuter/import.py \
  src/code/sys_math3d.c \
  expected/build/ntsc-1.2/functions/src/code/sys_math3d/Math3D_CylTriVsIntersect.s \
  VERSION=ntsc-1.2 --decompme
```

## 2. Official Technical Reference & Guides (zeldaret/website)

# ZeldaRET Website

This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.10.

## Development server

Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.

## Code scaffolding

Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.

## Build

Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.

## Running unit tests

Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).

## Running end-to-end tests

Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.

## Further help

To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.