1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-03 06:24:30 +00:00

Merge branch 'main' into doc_pause_menu

This commit is contained in:
Dragorn421 2024-08-12 01:05:38 +02:00
commit b5f68ac54e
No known key found for this signature in database
GPG key ID: 381AEBAF3D429335
692 changed files with 40408 additions and 19055 deletions

44
.gitignore vendored
View file

@ -7,54 +7,24 @@ __pycache__/
.vscode/
.vs/
.idea/
CMakeLists.txt
cmake-build-debug
venv/
.venv/
# Project-specific ignores
.make_options.mk
extracted/
build/
expected/
notes/
baserom/
baseroms/*/segments/
docs/doxygen/
*.elf
*.sra
*.z64
*.n64
*.v64
*.map
*.dump
out.txt
*.ram
# Tool artifacts
tools/mipspro7.2_compiler/
tools/overlayhelpers/batchdisasm/output/*
tools/overlayhelpers/batchdisasm/output2/*
tools/overlayhelpers/batchdisasm/mipsdisasm/*
tools/disasm/output/*
tools/asmsplitter/asm/*
tools/asmsplitter/c/*
# Tools
.venv/
ctx.c
tools/*dSYM/
graphs/
# Assets
*.png
*.jpg
*.mdli
*.anmi
*.obj
*.mtl
*.fbx
!*_custom*
.extracted-assets.json
extracted/
# Docs
!docs/tutorial/
# Per-user configuration
.python-version
# If you want to use your own gitignore rules without modifying this file:
# - use `git config core.excludesFile path/to/my_gitignore_file`
# - or edit `.git/info/exclude`

26
Jenkinsfile vendored
View file

@ -30,20 +30,7 @@ pipeline {
sh 'make -j setup'
}
}
stage('Build gc-eu-mq-dbg (qemu-irix)') {
when {
branch 'main'
}
steps {
sh 'make -j ORIG_COMPILER=1'
}
}
stage('Build gc-eu-mq-dbg') {
when {
not {
branch 'main'
}
}
steps {
sh 'make -j RUN_CC_CHECK=0'
}
@ -54,20 +41,7 @@ pipeline {
sh 'make -j setup VERSION=gc-eu-mq'
}
}
stage('Build gc-eu-mq (qemu-irix)') {
when {
branch 'main'
}
steps {
sh 'make -j VERSION=gc-eu-mq ORIG_COMPILER=1'
}
}
stage('Build gc-eu-mq') {
when {
not {
branch 'main'
}
}
steps {
sh 'make -j VERSION=gc-eu-mq RUN_CC_CHECK=0'
}

187
Makefile
View file

@ -5,31 +5,106 @@ SHELL = /bin/bash
.SHELLFLAGS = -o pipefail -c
# Build options can either be changed by modifying the makefile, or by building with 'make SETTING=value'
# It is also possible to override default settings in a file called .make_options.mk with 'SETTING=value'.
-include .make_options.mk
# If COMPARE is 1, check the output md5sum after building
COMPARE := 1
COMPARE ?= 1
# If NON_MATCHING is 1, define the NON_MATCHING C flag when building
NON_MATCHING := 0
NON_MATCHING ?= 0
# If ORIG_COMPILER is 1, compile with QEMU_IRIX and the original compiler
ORIG_COMPILER := 0
ORIG_COMPILER ?= 0
# If COMPILER is "gcc", compile with GCC instead of IDO.
COMPILER := ido
COMPILER ?= ido
# Target game version. Currently the following versions are supported:
# gc-jp GameCube Japan
# gc-jp-mq GameCube Japan Master Quest
# gc-jp-ce GameCube Japan (Collector's Edition disc)
# gc-us GameCube US
# gc-us-mq GameCube US
# gc-eu GameCube Europe/PAL
# gc-eu-mq GameCube Europe/PAL Master Quest
# gc-eu-mq-dbg GameCube Europe/PAL Master Quest Debug (default)
# The following versions are work-in-progress and not yet matching:
# gc-us GameCube US
VERSION := gc-eu-mq-dbg
# ntsc-1.2 N64 NTSC 1.2 (Japan)
VERSION ?= gc-eu-mq-dbg
# Number of threads to extract and compress with
N_THREADS := $(shell nproc)
N_THREADS ?= $(shell nproc)
# Check code syntax with host compiler
RUN_CC_CHECK := 1
RUN_CC_CHECK ?= 1
# Set prefix to mips binutils binaries (mips-linux-gnu-ld => 'mips-linux-gnu-') - Change at your own risk!
# In nearly all cases, not having 'mips-linux-gnu-*' binaries on the PATH is indicative of missing dependencies
MIPS_BINUTILS_PREFIX ?= mips-linux-gnu-
# Emulator w/ flags
N64_EMULATOR ?=
# Set to override game region in the ROM header. Options: JP, US, EU
# REGION ?= US
CFLAGS ?=
CPPFLAGS ?=
CPP_DEFINES ?=
# Version-specific settings
ifeq ($(VERSION),ntsc-1.2)
REGION ?= JP
PLATFORM := N64
PAL := 0
MQ := 0
DEBUG := 0
COMPARE := 0
else ifeq ($(VERSION),gc-jp)
REGION ?= JP
PLATFORM := GC
PAL := 0
MQ := 0
DEBUG := 0
else ifeq ($(VERSION),gc-jp-mq)
REGION ?= JP
PLATFORM := GC
PAL := 0
MQ := 1
DEBUG := 0
else ifeq ($(VERSION),gc-jp-ce)
REGION ?= JP
PLATFORM := GC
PAL := 0
MQ := 0
DEBUG := 0
else ifeq ($(VERSION),gc-us)
REGION ?= US
PLATFORM := GC
PAL := 0
MQ := 0
DEBUG := 0
else ifeq ($(VERSION),gc-us-mq)
REGION ?= US
PLATFORM := GC
PAL := 0
MQ := 1
DEBUG := 0
else ifeq ($(VERSION),gc-eu)
REGION ?= EU
PLATFORM := GC
PAL := 1
MQ := 0
DEBUG := 0
else ifeq ($(VERSION),gc-eu-mq)
REGION ?= EU
PLATFORM := GC
PAL := 1
MQ := 1
DEBUG := 0
else ifeq ($(VERSION),gc-eu-mq-dbg)
REGION ?= EU
PLATFORM := GC
PAL := 1
MQ := 1
DEBUG := 1
else
$(error Unsupported version $(VERSION))
endif
# ORIG_COMPILER cannot be combined with a non-IDO compiler. Check for this case and error out if found.
ifneq ($(COMPILER),ido)
ifeq ($(ORIG_COMPILER),1)
@ -42,40 +117,11 @@ ifeq ($(COMPILER),gcc)
NON_MATCHING := 1
endif
# Set prefix to mips binutils binaries (mips-linux-gnu-ld => 'mips-linux-gnu-') - Change at your own risk!
# In nearly all cases, not having 'mips-linux-gnu-*' binaries on the PATH is indicative of missing dependencies
MIPS_BINUTILS_PREFIX := mips-linux-gnu-
ifeq ($(NON_MATCHING),1)
CPP_DEFINES += -DNON_MATCHING -DAVOID_UB
COMPARE := 0
endif
# Version-specific settings
ifeq ($(VERSION),gc-us)
REGION := US
PAL := 0
MQ := 0
DEBUG := 0
else ifeq ($(VERSION),gc-eu)
REGION := EU
PAL := 1
MQ := 0
DEBUG := 0
else ifeq ($(VERSION),gc-eu-mq)
REGION := EU
PAL := 1
MQ := 1
DEBUG := 0
else ifeq ($(VERSION),gc-eu-mq-dbg)
REGION := EU
PAL := 1
MQ := 1
DEBUG := 1
else
$(error Unsupported version $(VERSION))
endif
PROJECT_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
BUILD_DIR := build/$(VERSION)
EXPECTED_DIR := expected/$(BUILD_DIR)
@ -91,6 +137,14 @@ VERSION_MACRO := OOT_$(shell echo $(VERSION) | tr a-z-. A-Z__)
CPP_DEFINES += -DOOT_VERSION=$(VERSION_MACRO)
CPP_DEFINES += -DOOT_REGION=REGION_$(REGION)
ifeq ($(PLATFORM),N64)
CPP_DEFINES += -DPLATFORM_N64=1 -DPLATFORM_GC=0
else ifeq ($(PLATFORM),GC)
CPP_DEFINES += -DPLATFORM_N64=0 -DPLATFORM_GC=1
else
$(error Unsupported platform $(PLATFORM))
endif
ifeq ($(PAL),0)
CPP_DEFINES += -DOOT_NTSC=1
else
@ -157,8 +211,6 @@ OBJCOPY := $(MIPS_BINUTILS_PREFIX)objcopy
OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump
NM := $(MIPS_BINUTILS_PREFIX)nm
N64_EMULATOR ?=
INC := -Iinclude -Iinclude/libc -Isrc -I$(BUILD_DIR) -I. -I$(EXTRACTED_DIR)
# Check code syntax with host compiler
@ -179,6 +231,10 @@ PYTHON ?= $(VENV)/bin/python3
# preprocessor for this because it won't substitute inside string literals.
SPEC_REPLACE_VARS := sed -e 's|$$(BUILD_DIR)|$(BUILD_DIR)|g'
# Audio tools
AUDIO_EXTRACT := $(PYTHON) tools/audio_extraction.py
SAMPLECONV := tools/audio/sampleconv/sampleconv
CFLAGS += $(CPP_DEFINES)
CPPFLAGS += $(CPP_DEFINES)
@ -186,8 +242,10 @@ ifeq ($(COMPILER),gcc)
OPTFLAGS := -Os -ffast-math -fno-unsafe-math-optimizations
endif
# TODO PL and DOWHILE should be disabled for non-gamecube
GBI_DEFINES := -DF3DEX_GBI_2 -DF3DEX_GBI_PL -DGBI_DOWHILE
GBI_DEFINES := -DF3DEX_GBI_2
ifeq ($(PLATFORM),GC)
GBI_DEFINES += -DF3DEX_GBI_PL -DGBI_DOWHILE
endif
ifeq ($(DEBUG),1)
GBI_DEFINES += -DGBI_DEBUG
endif
@ -241,6 +299,22 @@ else
SRC_DIRS := $(shell find src -type d)
endif
ifneq ($(wildcard $(EXTRACTED_DIR)/assets/audio),)
SAMPLE_EXTRACT_DIRS := $(shell find $(EXTRACTED_DIR)/assets/audio/samples -type d)
else
SAMPLE_EXTRACT_DIRS :=
endif
ifneq ($(wildcard assets/audio/samples),)
SAMPLE_DIRS := $(shell find assets/audio/samples -type d)
else
SAMPLE_DIRS :=
endif
SAMPLE_FILES := $(foreach dir,$(SAMPLE_DIRS),$(wildcard $(dir)/*.wav))
SAMPLE_EXTRACT_FILES := $(foreach dir,$(SAMPLE_EXTRACT_DIRS),$(wildcard $(dir)/*.wav))
AIFC_FILES := $(foreach f,$(SAMPLE_FILES),$(BUILD_DIR)/$(f:.wav=.aifc)) $(foreach f,$(SAMPLE_EXTRACT_FILES:.wav=.aifc),$(f:$(EXTRACTED_DIR)/%=$(BUILD_DIR)/%))
# create extracted directories
$(shell mkdir -p $(EXTRACTED_DIR) $(EXTRACTED_DIR)/assets $(EXTRACTED_DIR)/text)
@ -378,7 +452,7 @@ $(BUILD_DIR)/src/code/jpegdecoder.o: CC := $(CC_OLD)
ifeq ($(PERMUTER),) # permuter + preprocess.py misbehaves, permuter doesn't care about rodata diffs or bss ordering so just don't use it in that case
# Handle encoding (UTF-8 -> EUC-JP) and custom pragmas
$(BUILD_DIR)/src/%.o: CC := $(PYTHON) tools/preprocess.py $(CC)
$(BUILD_DIR)/src/%.o: CC := $(PYTHON) tools/preprocess.py -v $(VERSION) -- $(CC)
endif
else
@ -423,6 +497,10 @@ venv:
$(PYTHON) -m pip install -U pip
$(PYTHON) -m pip install -U -r requirements.txt
# TODO this is a temporary rule for testing audio, to be removed
setup-audio:
$(AUDIO_EXTRACT) -o $(EXTRACTED_DIR) -v $(VERSION) --read-xml
setup: venv
$(MAKE) -C tools
$(PYTHON) tools/decompress_baserom.py $(VERSION)
@ -430,6 +508,7 @@ setup: venv
$(PYTHON) tools/extract_incbins.py $(EXTRACTED_DIR)/baserom --oot-version $(VERSION) -o $(EXTRACTED_DIR)/incbin
$(PYTHON) tools/msgdis.py $(VERSION)
$(PYTHON) extract_assets.py -v $(VERSION) -j$(N_THREADS)
$(AUDIO_EXTRACT) -o $(EXTRACTED_DIR) -v $(VERSION) --read-xml
disasm:
$(RM) -r $(EXPECTED_DIR)
@ -582,6 +661,30 @@ $(BUILD_DIR)/assets/%.jpg.inc.c: assets/%.jpg
$(BUILD_DIR)/assets/%.jpg.inc.c: $(EXTRACTED_DIR)/assets/%.jpg
$(ZAPD) bren -eh -i $< -o $@
# Audio
AUDIO_BUILD_DEBUG ?= 0
# first build samples...
$(BUILD_DIR)/assets/audio/samples/%.half.aifc: assets/audio/samples/%.half.wav
$(SAMPLECONV) vadpcm-half $< $@
$(BUILD_DIR)/assets/audio/samples/%.half.aifc: $(EXTRACTED_DIR)/assets/audio/samples/%.half.wav
$(SAMPLECONV) vadpcm-half $< $@
ifeq ($(AUDIO_BUILD_DEBUG),1)
@(cmp $(<D)/aifc/$(<F:.half.wav=.half.aifc) $@ && echo "$(<F) OK") || (mkdir -p NONMATCHINGS/$(<D) && cp $(<D)/aifc/$(<F:.half.wav=.half.aifc) NONMATCHINGS/$(<D)/$(<F:.half.wav=.half.aifc))
endif
$(BUILD_DIR)/assets/audio/samples/%.aifc: assets/audio/samples/%.wav
$(SAMPLECONV) vadpcm $< $@
$(BUILD_DIR)/assets/audio/samples/%.aifc: $(EXTRACTED_DIR)/assets/audio/samples/%.wav
$(SAMPLECONV) vadpcm $< $@
ifeq ($(AUDIO_BUILD_DEBUG),1)
@(cmp $(<D)/aifc/$(<F:.wav=.aifc) $@ && echo "$(<F) OK") || (mkdir -p NONMATCHINGS/$(<D) && cp $(<D)/aifc/$(<F:.wav=.aifc) NONMATCHINGS/$(<D)/$(<F:.wav=.aifc))
endif
-include $(DEP_FILES)
# Print target for debugging

View file

@ -0,0 +1,433 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/samplebanks/ -->
<SampleBank Name="SampleBank_0" Index="0">
<Sample Name="SAMPLE_0_0" FileName="Sample000" Offset="0x000000" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_1" FileName="Sample001" Offset="0x0005B0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_2" FileName="Sample002" Offset="0x000780" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_3" FileName="Sample003" Offset="0x000C70" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_4" FileName="Sample004" Offset="0x001730" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_5" FileName="Sample005" Offset="0x001ED0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_6" FileName="Sample006" Offset="0x002D10" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_7" FileName="Sample007" Offset="0x004250" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_8" FileName="Sample008" Offset="0x005480" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_9" FileName="Sample009" Offset="0x0077D0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_10" FileName="Sample010" Offset="0x0097E0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_11" FileName="Sample011" Offset="0x00B660" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_12" FileName="Sample012" Offset="0x00BC80" SampleRate="32000" BaseNote="F3"/>
<Sample Name="SAMPLE_0_13" FileName="Sample013" Offset="0x00E4B0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_14" FileName="Sample014" Offset="0x011D80" SampleRate="24000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_15" FileName="Sample015" Offset="0x01C4A0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_16" FileName="Sample016" Offset="0x027DA0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_17" FileName="Sample017" Offset="0x033800" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_18" FileName="Sample018" Offset="0x0393F0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_19" FileName="Sample019" Offset="0x03D090" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_20" FileName="Sample020" Offset="0x03E360" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_21" FileName="Sample021" Offset="0x03ECE0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_22" FileName="Sample022" Offset="0x03F770" SampleRate="16000" BaseNote="G4"/>
<Sample Name="SAMPLE_0_23" FileName="Sample023" Offset="0x040000" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_24" FileName="Sample024" Offset="0x040AA0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_25" FileName="Sample025" Offset="0x0414F0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_26" FileName="Sample026" Offset="0x041A20" SampleRate="8000" BaseNote="G3"/>
<Sample Name="SAMPLE_0_27" FileName="Sample027" Offset="0x041CD0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_28" FileName="Sample028" Offset="0x0439A0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_29" FileName="Sample029" Offset="0x046810" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_30" FileName="Sample030" Offset="0x048840" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_31" FileName="Sample031" Offset="0x04A510" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_32" FileName="Sample032" Offset="0x04A6A0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_33" FileName="Sample033" Offset="0x04F790" SampleRate="23220" BaseNote="C4"/>
<Sample Name="SAMPLE_0_34" FileName="Sample034" Offset="0x053210" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_35" FileName="Sample035" Offset="0x055BA0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_36" FileName="Sample036" Offset="0x057D10" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_37" FileName="Sample037" Offset="0x05B590" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_38" FileName="Sample038" Offset="0x05CBA0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_39" FileName="Sample039" Offset="0x060240" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_40" FileName="Sample040" Offset="0x061B90" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_41" FileName="Sample041" Offset="0x063350" SampleRate="16000" BaseNote="AF4"/>
<Sample Name="SAMPLE_0_42" FileName="Sample042" Offset="0x063B70" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_43" FileName="Sample043" Offset="0x064600" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_44" FileName="Sample044" Offset="0x064F70" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_45" FileName="Sample045" Offset="0x065580" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_46" FileName="Sample046" Offset="0x067FA0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_47" FileName="Sample047" Offset="0x068CC0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_48" FileName="Sample048" Offset="0x069130" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_49" FileName="Sample049" Offset="0x06A040" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_50" FileName="Sample050" Offset="0x06BA00" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_51" FileName="Sample051" Offset="0x06C3C0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_52" FileName="Sample052" Offset="0x06D5B0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_53" FileName="Sample053" Offset="0x071C70" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_54" FileName="Sample054" Offset="0x0732A0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_55" FileName="Sample055" Offset="0x074790" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_56" FileName="Sample056" Offset="0x077010" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_57" FileName="Sample057" Offset="0x077BA0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_58" FileName="Sample058" Offset="0x07AFD0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_59" FileName="Sample059" Offset="0x07D290" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_60" FileName="Sample060" Offset="0x07F3F0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_61" FileName="Sample061" Offset="0x07FC90" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_62" FileName="Sample062" Offset="0x080E00" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_63" FileName="Sample063" Offset="0x082000" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_64" FileName="Sample064" Offset="0x082ED0" SampleRate="22050" BaseNote="C0"/>
<Sample Name="SAMPLE_0_65" FileName="Sample065" Offset="0x084380" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_66" FileName="Sample066" Offset="0x087030" SampleRate="22050" BaseNote="C0"/>
<Sample Name="SAMPLE_0_67" FileName="Sample067" Offset="0x087440" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_68" FileName="Sample068" Offset="0x088620" SampleRate="22050" BaseNote="C0"/>
<Sample Name="SAMPLE_0_69" FileName="Sample069" Offset="0x088A50" SampleRate="45530" BaseNote="F1"/>
<Sample Name="SAMPLE_0_70" FileName="Sample070" Offset="0x08A4B0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_71" FileName="Sample071" Offset="0x08E160" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_72" FileName="Sample072" Offset="0x08F6F0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_73" FileName="Sample073" Offset="0x093DB0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_74" FileName="Sample074" Offset="0x094B10" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_75" FileName="Sample075" Offset="0x098B00" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_76" FileName="Sample076" Offset="0x09D5F0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_77" FileName="Sample077" Offset="0x0A0260" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_78" FileName="Sample078" Offset="0x0A14A0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_79" FileName="Sample079" Offset="0x0A2590" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_80" FileName="Sample080" Offset="0x0A9EF0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_81" FileName="Sample081" Offset="0x0AB9E0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_82" FileName="Sample082" Offset="0x0ADBA0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_83" FileName="Sample083" Offset="0x0AF0A0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_84" FileName="Sample084" Offset="0x0B0960" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_85" FileName="Sample085" Offset="0x0B3600" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_86" FileName="Sample086" Offset="0x0B3B10" SampleRate="24000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_87" FileName="Sample087" Offset="0x0B4B90" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_88" FileName="Sample088" Offset="0x0B5A80" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_89" FileName="Sample089" Offset="0x0B8690" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_90" FileName="Sample090" Offset="0x0BA0D0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_91" FileName="Sample091" Offset="0x0BBB00" SampleRate="32000" BaseNote="B1"/>
<Sample Name="SAMPLE_0_92" FileName="Sample092" Offset="0x0C42B0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_93" FileName="Sample093" Offset="0x0C5140" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_94" FileName="Sample094" Offset="0x0C88C0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_95" FileName="Sample095" Offset="0x0CAF60" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_96" FileName="Sample096" Offset="0x0D16F0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_97" FileName="Sample097" Offset="0x0D2110" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_98" FileName="Sample098" Offset="0x0D3DC0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_99" FileName="Sample099" Offset="0x0D57A0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_100" FileName="Sample100" Offset="0x0DE0A0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_101" FileName="Sample101" Offset="0x0E01F0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_102" FileName="Sample102" Offset="0x0E2510" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_103" FileName="Sample103" Offset="0x0E44A0" SampleRate="22050" BaseNote="C0"/>
<Sample Name="SAMPLE_0_104" FileName="Sample104" Offset="0x0E4B00" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_105" FileName="Sample105" Offset="0x0E5B70" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_106" FileName="Sample106" Offset="0x0EA760" SampleRate="8000" BaseNote="A0"/>
<Sample Name="SAMPLE_0_107" FileName="Sample107" Offset="0x0EAFC0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_108" FileName="Sample108" Offset="0x0EB5B0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_109" FileName="Sample109" Offset="0x0ECF40" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_110" FileName="Sample110" Offset="0x0EEB80" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_111" FileName="Sample111" Offset="0x0F2FE0" SampleRate="22050" BaseNote="GF3"/>
<Sample Name="SAMPLE_0_112" FileName="Sample112" Offset="0x0F5350" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_113" FileName="Sample113" Offset="0x0F5A90" SampleRate="22050" BaseNote="C0"/>
<Sample Name="SAMPLE_0_114" FileName="Sample114" Offset="0x0F72A0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_115" FileName="Sample115" Offset="0x0FAD40" SampleRate="32000" BaseNote="E3"/>
<Sample Name="SAMPLE_0_116" FileName="Sample116" Offset="0x0FDFC0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_117" FileName="Sample117" Offset="0x1026F0" SampleRate="24000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_118" FileName="Sample118" Offset="0x106C20" SampleRate="22050" BaseNote="E3"/>
<Sample Name="SAMPLE_0_119" FileName="Sample119" Offset="0x108690" SampleRate="32000" BaseNote="F2"/>
<Sample Name="SAMPLE_0_120" FileName="Sample120" Offset="0x10CD20" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_121" FileName="Sample121" Offset="0x10EFF0" SampleRate="32000" BaseNote="D4"/>
<Sample Name="SAMPLE_0_122" FileName="Sample122" Offset="0x111520" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_123" FileName="Sample123" Offset="0x1129E0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_124" FileName="Sample124" Offset="0x114D70" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_125" FileName="Sample125" Offset="0x1165E0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_126" FileName="Sample126" Offset="0x1176B0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_127" FileName="Sample127" Offset="0x118910" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_128" FileName="Sample128" Offset="0x119870" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_129" FileName="Sample129" Offset="0x11A270" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_130" FileName="Sample130" Offset="0x11B0E0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_131" FileName="Sample131" Offset="0x11B790" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_132" FileName="Sample132" Offset="0x11BE20" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_133" FileName="Sample133" Offset="0x11D6D0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_134" FileName="Sample134" Offset="0x11EE50" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_135" FileName="Sample135" Offset="0x11FB00" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_136" FileName="Sample136" Offset="0x120D60" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_137" FileName="Sample137" Offset="0x121BF0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_138" FileName="Sample138" Offset="0x122C10" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_139" FileName="Sample139" Offset="0x1243F0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_140" FileName="Sample140" Offset="0x125A90" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_141" FileName="Sample141" Offset="0x126ED0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_142" FileName="Sample142" Offset="0x128DA0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_143" FileName="Sample143" Offset="0x12AC80" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_144" FileName="Sample144" Offset="0x12CD30" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_145" FileName="Sample145" Offset="0x133AB0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_146" FileName="Sample146" Offset="0x139D70" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_147" FileName="Sample147" Offset="0x13AF50" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_148" FileName="Sample148" Offset="0x13C040" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_149" FileName="Sample149" Offset="0x13D3B0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_150" FileName="Sample150" Offset="0x13E870" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_151" FileName="Sample151" Offset="0x13F6B0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_152" FileName="Sample152" Offset="0x140FC0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_153" FileName="Sample153" Offset="0x141960" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_154" FileName="Sample154" Offset="0x143690" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_155" FileName="Sample155" Offset="0x146490" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_156" FileName="Sample156" Offset="0x1478F0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_157" FileName="Sample157" Offset="0x148390" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_158" FileName="Sample158" Offset="0x1493C0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_159" FileName="Sample159" Offset="0x14B440" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_160" FileName="Sample160" Offset="0x14C250" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_161" FileName="Sample161" Offset="0x151520" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_162" FileName="Sample162" Offset="0x15A6A0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_163" FileName="Sample163" Offset="0x15BE50" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_164" FileName="Sample164" Offset="0x15DCB0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_165" FileName="Sample165" Offset="0x15F4B0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_166" FileName="Sample166" Offset="0x1617F0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_167" FileName="Sample167" Offset="0x163280" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_168" FileName="Sample168" Offset="0x166790" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_169" FileName="Sample169" Offset="0x167800" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_170" FileName="Sample170" Offset="0x168650" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_171" FileName="Sample171" Offset="0x1698E0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_172" FileName="Sample172" Offset="0x16A450" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_173" FileName="Sample173" Offset="0x16AEA0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_174" FileName="Sample174" Offset="0x16B3E0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_175" FileName="Sample175" Offset="0x16CE20" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_176" FileName="Sample176" Offset="0x16EEA0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_177" FileName="Sample177" Offset="0x16FE60" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_178" FileName="Sample178" Offset="0x170E80" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_179" FileName="Sample179" Offset="0x171DA0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_180" FileName="Sample180" Offset="0x173320" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_181" FileName="Sample181" Offset="0x174240" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_182" FileName="Sample182" Offset="0x175140" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_183" FileName="Sample183" Offset="0x175C30" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_184" FileName="Sample184" Offset="0x177480" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_185" FileName="Sample185" Offset="0x178D40" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_186" FileName="Sample186" Offset="0x1795F0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_187" FileName="Sample187" Offset="0x17E6C0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_188" FileName="Sample188" Offset="0x182EC0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_189" FileName="Sample189" Offset="0x1844E0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_190" FileName="Sample190" Offset="0x185BA0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_191" FileName="Sample191" Offset="0x188170" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_192" FileName="Sample192" Offset="0x18A560" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_193" FileName="Sample193" Offset="0x18B650" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_194" FileName="Sample194" Offset="0x18D090" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_195" FileName="Sample195" Offset="0x18E480" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_196" FileName="Sample196" Offset="0x190200" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_197" FileName="Sample197" Offset="0x193410" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_198" FileName="Sample198" Offset="0x196950" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_199" FileName="Sample199" Offset="0x1971A0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_200" FileName="Sample200" Offset="0x197500" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_201" FileName="Sample201" Offset="0x198F30" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_202" FileName="Sample202" Offset="0x19F6D0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_203" FileName="Sample203" Offset="0x1A1670" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_204" FileName="Sample204" Offset="0x1A2580" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_205" FileName="Sample205" Offset="0x1A71E0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_206" FileName="Sample206" Offset="0x1A79C0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_207" FileName="Sample207" Offset="0x1AF2E0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_208" FileName="Sample208" Offset="0x1AFEE0" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_209" FileName="Sample209" Offset="0x1B3F50" SampleRate="20000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_210" FileName="Sample210" Offset="0x1B6530" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_211" FileName="Sample211" Offset="0x1B7B40" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_212" FileName="Sample212" Offset="0x1B8DB0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_213" FileName="Sample213" Offset="0x1B9D70" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_214" FileName="Sample214" Offset="0x1BB410" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_215" FileName="Sample215" Offset="0x1BC380" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_216" FileName="Sample216" Offset="0x1BFA40" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_217" FileName="Sample217" Offset="0x1C0F80" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_218" FileName="Sample218" Offset="0x1C2510" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_219" FileName="Sample219" Offset="0x1C6870" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_220" FileName="Sample220" Offset="0x1CC560" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_221" FileName="Sample221" Offset="0x1CF9C0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_222" FileName="Sample222" Offset="0x1D25C0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_223" FileName="Sample223" Offset="0x1D58F0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_224" FileName="Sample224" Offset="0x1D74B0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_225" FileName="Sample225" Offset="0x1D8420" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_226" FileName="Sample226" Offset="0x1D9880" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_227" FileName="Sample227" Offset="0x1DDA40" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_228" FileName="Sample228" Offset="0x1DE3C0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_229" FileName="Sample229" Offset="0x1DF040" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_230" FileName="Sample230" Offset="0x1E0140" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_231" FileName="Sample231" Offset="0x1E3160" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_232" FileName="Sample232" Offset="0x1E48E0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_233" FileName="Sample233" Offset="0x1E55F0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_234" FileName="Sample234" Offset="0x1E6000" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_235" FileName="Sample235" Offset="0x1E7E90" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_236" FileName="Sample236" Offset="0x1E9960" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_237" FileName="Sample237" Offset="0x1EB6B0" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_238" FileName="Sample238" Offset="0x1EC2B0" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_239" FileName="Sample239" Offset="0x1EC990" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_240" FileName="Sample240" Offset="0x1EE390" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_241" FileName="Sample241" Offset="0x1EF1B0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_242" FileName="Sample242" Offset="0x1EFCE0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_243" FileName="Sample243" Offset="0x1F1600" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_244" FileName="Sample244" Offset="0x1F3020" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_245" FileName="Sample245" Offset="0x1F4010" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_246" FileName="Sample246" Offset="0x1F4EB0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_247" FileName="Sample247" Offset="0x1F5E50" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_248" FileName="Sample248" Offset="0x1F7220" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_249" FileName="Sample249" Offset="0x1F9490" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_250" FileName="Sample250" Offset="0x1FA230" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_251" FileName="Sample251" Offset="0x1FB850" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_252" FileName="Sample252" Offset="0x1FEA30" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_253" FileName="Sample253" Offset="0x1FFD80" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_254" FileName="Sample254" Offset="0x200840" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_255" FileName="Sample255" Offset="0x206D10" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_256" FileName="Sample256" Offset="0x209E40" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_257" FileName="Sample257" Offset="0x20B580" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_258" FileName="Sample258" Offset="0x20BDA0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_259" FileName="Sample259" Offset="0x20C9E0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_260" FileName="Sample260" Offset="0x20DE70" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_261" FileName="Sample261" Offset="0x20F440" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_262" FileName="Sample262" Offset="0x2115A0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_263" FileName="Sample263" Offset="0x212040" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_264" FileName="Sample264" Offset="0x2147A0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_265" FileName="Sample265" Offset="0x214E10" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_266" FileName="Sample266" Offset="0x215810" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_267" FileName="Sample267" Offset="0x216210" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_268" FileName="Sample268" Offset="0x216D00" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_269" FileName="Sample269" Offset="0x2187D0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_270" FileName="Sample270" Offset="0x2193E0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_271" FileName="Sample271" Offset="0x219F10" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_272" FileName="Sample272" Offset="0x21A810" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_273" FileName="Sample273" Offset="0x21AA80" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_274" FileName="Sample274" Offset="0x21ACF0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_275" FileName="Sample275" Offset="0x21B150" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_276" FileName="Sample276" Offset="0x21B370" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_277" FileName="Sample277" Offset="0x21BBC0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_278" FileName="Sample278" Offset="0x21C330" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_279" FileName="Sample279" Offset="0x21CF00" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_280" FileName="Sample280" Offset="0x21DDB0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_281" FileName="Sample281" Offset="0x220770" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_282" FileName="Sample282" Offset="0x2222F0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_283" FileName="Sample283" Offset="0x222BA0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_284" FileName="Sample284" Offset="0x2230B0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_285" FileName="Sample285" Offset="0x223C90" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_286" FileName="Sample286" Offset="0x224FD0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_287" FileName="Sample287" Offset="0x228A70" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_288" FileName="Sample288" Offset="0x22C380" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_289" FileName="Sample289" Offset="0x22DD50" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_290" FileName="Sample290" Offset="0x233280" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_291" FileName="Sample291" Offset="0x236F80" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_292" FileName="Sample292" Offset="0x237BA0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_293" FileName="Sample293" Offset="0x23AD60" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_294" FileName="Sample294" Offset="0x23D490" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_295" FileName="Sample295" Offset="0x240600" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_296" FileName="Sample296" Offset="0x241690" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_297" FileName="Sample297" Offset="0x241C20" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_298" FileName="Sample298" Offset="0x243440" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_299" FileName="Sample299" Offset="0x244DD0" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_300" FileName="Sample300" Offset="0x247290" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_301" FileName="Sample301" Offset="0x249810" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_302" FileName="Sample302" Offset="0x24AB70" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_303" FileName="Sample303" Offset="0x24BBE0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_304" FileName="Sample304" Offset="0x24C2C0" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_305" FileName="Sample305" Offset="0x24E060" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_306" FileName="Sample306" Offset="0x24F440" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_307" FileName="Sample307" Offset="0x24FED0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_308" FileName="Sample308" Offset="0x250E20" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_309" FileName="Sample309" Offset="0x2516D0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_310" FileName="Sample310" Offset="0x252B10" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_311" FileName="Sample311" Offset="0x255720" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_312" FileName="Sample312" Offset="0x2564A0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_313" FileName="Sample313" Offset="0x2581C0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_314" FileName="Sample314" Offset="0x258360" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_315" FileName="Sample315" Offset="0x259120" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_316" FileName="Sample316" Offset="0x259BF0" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_317" FileName="Sample317" Offset="0x25AAC0" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_318" FileName="Sample318" Offset="0x25C140" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_319" FileName="Sample319" Offset="0x25CD60" SampleRate="16000" BaseNote="AF3"/>
<Sample Name="SAMPLE_0_320" FileName="Sample320" Offset="0x25DB50" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_321" FileName="Sample321" Offset="0x25E9E0" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_322" FileName="Sample322" Offset="0x25FC50" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_323" FileName="Sample323" Offset="0x260420" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_324" FileName="Sample324" Offset="0x261790" SampleRate="16000" BaseNote="AF3"/>
<Sample Name="SAMPLE_0_325" FileName="Sample325" Offset="0x262170" SampleRate="16000" BaseNote="AF3"/>
<Sample Name="SAMPLE_0_326" FileName="Sample326" Offset="0x263270" SampleRate="22050" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_327" FileName="Sample327" Offset="0x264B60" SampleRate="16000" BaseNote="AF3"/>
<Sample Name="SAMPLE_0_328" FileName="Sample328" Offset="0x26A060" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_329" FileName="Sample329" Offset="0x26AAD0" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_330" FileName="Sample330" Offset="0x26B960" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_331" FileName="Sample331" Offset="0x26BEF0" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_332" FileName="Sample332" Offset="0x26CE70" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_333" FileName="Sample333" Offset="0x26DF40" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_334" FileName="Sample334" Offset="0x26FC60" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_335" FileName="Sample335" Offset="0x270E40" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_336" FileName="Sample336" Offset="0x271A70" SampleRate="16000" BaseNote="AF3"/>
<Sample Name="SAMPLE_0_337" FileName="Sample337" Offset="0x273860" SampleRate="16000" BaseNote="AF3"/>
<Sample Name="SAMPLE_0_338" FileName="Sample338" Offset="0x274EA0" SampleRate="16000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_339" FileName="Sample339" Offset="0x2765B0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_340" FileName="Sample340" Offset="0x27C0A0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_341" FileName="Sample341" Offset="0x27E260" SampleRate="16000" BaseNote="AF3"/>
<Sample Name="SAMPLE_0_342" FileName="Sample342" Offset="0x280C70" SampleRate="16000" BaseNote="G3"/>
<Sample Name="SAMPLE_0_343" FileName="Sample343" Offset="0x283440" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_344" FileName="Sample344" Offset="0x2869C0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_345" FileName="Sample345" Offset="0x28BF50" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_346" FileName="Sample346" Offset="0x28CE90" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_347" FileName="Sample347" Offset="0x2938F0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_348" FileName="Sample348" Offset="0x29B480" SampleRate="16000" BaseNote="C0"/>
<Sample Name="SAMPLE_0_349" FileName="Sample349" Offset="0x29EB20" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_350" FileName="Sample350" Offset="0x29FE30" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_351" FileName="Sample351" Offset="0x2A4D40" SampleRate="32000" BaseNote="G4"/>
<Sample Name="SAMPLE_0_352" FileName="Sample352" Offset="0x2A8500" SampleRate="32000" BaseNote="C2"/>
<Sample Name="SAMPLE_0_353" FileName="Sample353" Offset="0x2AF020" SampleRate="22050" BaseNote="GF4"/>
<Sample Name="SAMPLE_0_354" FileName="Sample354" Offset="0x2B43B0" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_355" FileName="Sample355" Offset="0x2B9E60" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_356" FileName="Sample356" Offset="0x2C8510" SampleRate="22050" BaseNote="A5"/>
<Sample Name="SAMPLE_0_357" FileName="Sample357" Offset="0x2CFEE0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_358" FileName="Sample358" Offset="0x2D96A0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_359" FileName="Sample359" Offset="0x2DFF40" SampleRate="22050" BaseNote="G3"/>
<Sample Name="SAMPLE_0_360" FileName="Sample360" Offset="0x2E7410" SampleRate="22050" BaseNote="DF3"/>
<Sample Name="SAMPLE_0_361" FileName="Sample361" Offset="0x2EF650" SampleRate="24000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_362" FileName="Sample362" Offset="0x2F3300" SampleRate="32000" BaseNote="DF3"/>
<Sample Name="SAMPLE_0_363" FileName="Sample363" Offset="0x2F8690" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_364" FileName="Sample364" Offset="0x2F9A90" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_365" FileName="Sample365" Offset="0x2FD270" SampleRate="32000" BaseNote="F3"/>
<Sample Name="SAMPLE_0_366" FileName="Sample366" Offset="0x301EC0" SampleRate="32000" BaseNote="AF5"/>
<Sample Name="SAMPLE_0_367" FileName="Sample367" Offset="0x304E30" SampleRate="22000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_368" FileName="Sample368" Offset="0x309BD0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_369" FileName="Sample369" Offset="0x30C360" SampleRate="32000" BaseNote="D4"/>
<Sample Name="SAMPLE_0_370" FileName="Sample370" Offset="0x30EAF0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_371" FileName="Sample371" Offset="0x317260" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_372" FileName="Sample372" Offset="0x31F640" SampleRate="32000" BaseNote="C6"/>
<Sample Name="SAMPLE_0_373" FileName="Sample373" Offset="0x324660" SampleRate="32000" BaseNote="E4"/>
<Sample Name="SAMPLE_0_374" FileName="Sample374" Offset="0x328D10" SampleRate="32000" BaseNote="E3"/>
<Sample Name="SAMPLE_0_375" FileName="Sample375" Offset="0x32CA00" SampleRate="32000" BaseNote="E3"/>
<Sample Name="SAMPLE_0_376" FileName="Sample376" Offset="0x32ECB0" SampleRate="32000" BaseNote="E4"/>
<Sample Name="SAMPLE_0_377" FileName="Sample377" Offset="0x332D10" SampleRate="32000" BaseNote="A2"/>
<Sample Name="SAMPLE_0_378" FileName="Sample378" Offset="0x335740" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_379" FileName="Sample379" Offset="0x337A10" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_380" FileName="Sample380" Offset="0x338450" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_381" FileName="Sample381" Offset="0x33A980" SampleRate="32000" BaseNote="AF2"/>
<Sample Name="SAMPLE_0_382" FileName="Sample382" Offset="0x33BC30" SampleRate="32000" BaseNote="EF5"/>
<Sample Name="SAMPLE_0_383" FileName="Sample383" Offset="0x33D130" SampleRate="32000" BaseNote="DF5"/>
<Sample Name="SAMPLE_0_384" FileName="Sample384" Offset="0x3403F0" SampleRate="32000" BaseNote="D3"/>
<Sample Name="SAMPLE_0_385" FileName="Sample385" Offset="0x343870" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_386" FileName="Sample386" Offset="0x34D670" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_387" FileName="Sample387" Offset="0x351810" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_388" FileName="Sample388" Offset="0x359170" SampleRate="24000" BaseNote="AF5"/>
<Sample Name="SAMPLE_0_389" FileName="Sample389" Offset="0x35C900" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_390" FileName="Sample390" Offset="0x35D100" SampleRate="22050" BaseNote="A3"/>
<Sample Name="SAMPLE_0_391" FileName="Sample391" Offset="0x364580" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_392" FileName="Sample392" Offset="0x36FE80" SampleRate="27777" BaseNote="C4"/>
<Sample Name="SAMPLE_0_393" FileName="Sample393" Offset="0x374C20" SampleRate="32000" BaseNote="D3"/>
<Sample Name="SAMPLE_0_394" FileName="Sample394" Offset="0x378360" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_395" FileName="Sample395" Offset="0x37A6B0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_396" FileName="Sample396" Offset="0x37B2A0" SampleRate="32000" BaseNote="F4"/>
<Sample Name="SAMPLE_0_397" FileName="Sample397" Offset="0x382830" SampleRate="32000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_398" FileName="Sample398" Offset="0x384ED0" SampleRate="32000" BaseNote="BF2"/>
<Sample Name="SAMPLE_0_399" FileName="Sample399" Offset="0x387060" SampleRate="48000" BaseNote="D3"/>
<Sample Name="SAMPLE_0_400" FileName="Sample400" Offset="0x38F000" SampleRate="32000" BaseNote="BF4"/>
<Sample Name="SAMPLE_0_401" FileName="Sample401" Offset="0x3926D0" SampleRate="32000" BaseNote="BF3"/>
<Sample Name="SAMPLE_0_402" FileName="Sample402" Offset="0x396F80" SampleRate="32000" BaseNote="C6"/>
<Sample Name="SAMPLE_0_403" FileName="Sample403" Offset="0x397FA0" SampleRate="32000" BaseNote="G5"/>
<Sample Name="SAMPLE_0_404" FileName="Sample404" Offset="0x399790" SampleRate="24000" BaseNote="GF5"/>
<Sample Name="SAMPLE_0_405" FileName="Sample405" Offset="0x39A6B0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_406" FileName="Sample406" Offset="0x3A4BE0" SampleRate="24000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_407" FileName="Sample407" Offset="0x3AA6E0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_408" FileName="Sample408" Offset="0x3ACC20" SampleRate="32000" BaseNote="DF4"/>
<Sample Name="SAMPLE_0_409" FileName="Sample409" Offset="0x3AE1C0" SampleRate="24000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_410" FileName="Sample410" Offset="0x3B45D0" SampleRate="32000" BaseNote="AF5"/>
<Sample Name="SAMPLE_0_411" FileName="Sample411" Offset="0x3B5490" SampleRate="32000" BaseNote="E4"/>
<Sample Name="SAMPLE_0_412" FileName="Sample412" Offset="0x3B63F0" SampleRate="32000" BaseNote="E3"/>
<Sample Name="SAMPLE_0_413" FileName="Sample413" Offset="0x3B71F0" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_414" FileName="Sample414" Offset="0x3B94B0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_415" FileName="Sample415" Offset="0x3BBC80" SampleRate="22050" BaseNote="F6"/>
<Sample Name="SAMPLE_0_416" FileName="Sample416" Offset="0x3BE750" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_417" FileName="Sample417" Offset="0x3BF6A0" SampleRate="32000" BaseNote="A1"/>
<Sample Name="SAMPLE_0_418" FileName="Sample418" Offset="0x3C0360" SampleRate="24000" BaseNote="AF5"/>
<Sample Name="SAMPLE_0_419" FileName="Sample419" Offset="0x3C2B40" SampleRate="24000" BaseNote="F4"/>
<Sample Name="SAMPLE_0_420" FileName="Sample420" Offset="0x3C4D00" SampleRate="24000" BaseNote="BF2"/>
<Sample Name="SAMPLE_0_421" FileName="Sample421" Offset="0x3C6BD0" SampleRate="32000" BaseNote="EF3"/>
<Sample Name="SAMPLE_0_422" FileName="Sample422" Offset="0x3CAC50" SampleRate="22050" BaseNote="C4"/>
<Sample Name="SAMPLE_0_423" FileName="Sample423" Offset="0x3CF8A0" SampleRate="16000" BaseNote="DF6"/>
<Sample Name="SAMPLE_0_424" FileName="Sample424" Offset="0x3D0140" SampleRate="22050" BaseNote="B5"/>
<Sample Name="SAMPLE_0_425" FileName="Sample425" Offset="0x3D0C00" SampleRate="32000" BaseNote="BF4"/>
<Sample Name="SAMPLE_0_426" FileName="Sample426" Offset="0x3D3A40" SampleRate="32000" BaseNote="EF4"/>
<Sample Name="SAMPLE_0_427" FileName="Sample427" Offset="0x3D62E0" SampleRate="16000" BaseNote="C2"/>
<Sample Name="SAMPLE_0_428" FileName="Sample428" Offset="0x3E3F50" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_0_429" FileName="Sample429" Offset="0x3E8BB0" SampleRate="32000" BaseNote="BF2"/>
</SampleBank>

View file

@ -0,0 +1,4 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/samplebanks/ -->
<SampleBank Name="SampleBank_2" Index="2">
<Sample Name="SAMPLE_2_0" FileName="Sample0" Offset="0x000000" SampleRate="32000" BaseNote="F4"/>
</SampleBank>

View file

@ -0,0 +1,8 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/samplebanks/ -->
<SampleBank Name="SampleBank_3" Index="3">
<Sample Name="SAMPLE_3_0" FileName="Sample0" Offset="0x000000" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_3_1" FileName="Sample1" Offset="0x008BC0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_3_2" FileName="Sample2" Offset="0x00A590" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_3_3" FileName="Sample3" Offset="0x00B3B0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_3_4" FileName="Sample4" Offset="0x016480" SampleRate="32000" BaseNote="C4"/>
</SampleBank>

View file

@ -0,0 +1,8 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/samplebanks/ -->
<SampleBank Name="SampleBank_4" Index="4">
<Sample Name="SAMPLE_4_0" FileName="Sample0" Offset="0x000000" SampleRate="24000" BaseNote="C4"/>
<Sample Name="SAMPLE_4_1" FileName="Sample1" Offset="0x006410" SampleRate="32000" BaseNote="AF5"/>
<Sample Name="SAMPLE_4_2" FileName="Sample2" Offset="0x0072D0" SampleRate="32000" BaseNote="E4"/>
<Sample Name="SAMPLE_4_3" FileName="Sample3" Offset="0x008230" SampleRate="32000" BaseNote="E3"/>
<Sample Name="SAMPLE_4_4" FileName="Sample4" Offset="0x009030" SampleRate="32000" BaseNote="DF4"/>
</SampleBank>

View file

@ -0,0 +1,9 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/samplebanks/ -->
<SampleBank Name="SampleBank_5" Index="5">
<Sample Name="SAMPLE_5_0" FileName="Sample0" Offset="0x000000" SampleRate="16000" BaseNote="C4"/>
<Sample Name="SAMPLE_5_1" FileName="Sample1" Offset="0x002540" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_5_2" FileName="Sample2" Offset="0x004800" SampleRate="22050" BaseNote="BF4"/>
<Sample Name="SAMPLE_5_3" FileName="Sample3" Offset="0x0072D0" SampleRate="16000" BaseNote="DF6"/>
<Sample Name="SAMPLE_5_4" FileName="Sample4" Offset="0x007B70" SampleRate="22050" BaseNote="B5"/>
<Sample Name="SAMPLE_5_5" FileName="Sample5" Offset="0x008630" SampleRate="22050" BaseNote="A3"/>
</SampleBank>

View file

@ -0,0 +1,10 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/samplebanks/ -->
<SampleBank Name="SampleBank_6" Index="6">
<Sample Name="SAMPLE_6_0" FileName="Sample0" Offset="0x000000" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_6_1" FileName="Sample1" Offset="0x00B0D0" SampleRate="32000" BaseNote="BF2"/>
<Sample Name="SAMPLE_6_2" FileName="Sample2" Offset="0x00E120" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_6_3" FileName="Sample3" Offset="0x0103E0" SampleRate="22050" BaseNote="BF4"/>
<Sample Name="SAMPLE_6_4" FileName="Sample4" Offset="0x012EB0" SampleRate="32000" BaseNote="C4"/>
<Sample Name="SAMPLE_6_5" FileName="Sample5" Offset="0x01D3E0" SampleRate="24000" BaseNote="C4"/>
<Sample Name="SAMPLE_6_6" FileName="Sample6" Offset="0x022EE0" SampleRate="24000" BaseNote="C4"/>
</SampleBank>

View file

@ -0,0 +1,250 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_0" Index="0">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
<Envelope Name="Env7"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="9" Name="INST_9"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
<Instrument ProgramNumber="16" Name="INST_16"/>
<Instrument ProgramNumber="17" Name="INST_17"/>
<Instrument ProgramNumber="18" Name="INST_18"/>
<Instrument ProgramNumber="19" Name="INST_19"/>
<Instrument ProgramNumber="20" Name="INST_20"/>
<Instrument ProgramNumber="21" Name="INST_21"/>
<Instrument ProgramNumber="22" Name="INST_22"/>
<Instrument ProgramNumber="23" Name="INST_23"/>
<Instrument ProgramNumber="24" Name="INST_24"/>
<Instrument ProgramNumber="25" Name="INST_25"/>
<Instrument ProgramNumber="15" Name="INST_15"/>
<Instrument ProgramNumber="26" Name="INST_26"/>
<Instrument ProgramNumber="27" Name="INST_27"/>
<Instrument ProgramNumber="28" Name="INST_28"/>
<Instrument ProgramNumber="29" Name="INST_29"/>
<Instrument ProgramNumber="30" Name="INST_30"/>
<Instrument ProgramNumber="31" Name="INST_31"/>
<Instrument ProgramNumber="33" Name="INST_33"/>
<Instrument ProgramNumber="32" Name="INST_32"/>
<Instrument ProgramNumber="34" Name="INST_34"/>
<Instrument ProgramNumber="35" Name="INST_35"/>
<Instrument ProgramNumber="36" Name="INST_36"/>
<Instrument ProgramNumber="91" Name="INST_91"/>
<Instrument ProgramNumber="52" Name="INST_52"/>
<Instrument ProgramNumber="53" Name="INST_53"/>
<Instrument ProgramNumber="37" Name="INST_37"/>
<Instrument ProgramNumber="38" Name="INST_38"/>
<Instrument ProgramNumber="39" Name="INST_39"/>
<Instrument ProgramNumber="40" Name="INST_40"/>
<Instrument ProgramNumber="41" Name="INST_41"/>
<Instrument ProgramNumber="42" Name="INST_42"/>
<Instrument ProgramNumber="43" Name="INST_43"/>
<Instrument ProgramNumber="44" Name="INST_44"/>
<Instrument ProgramNumber="45" Name="INST_45"/>
<Instrument ProgramNumber="47" Name="INST_47"/>
<Instrument ProgramNumber="48" Name="INST_48"/>
<Instrument ProgramNumber="50" Name="INST_50"/>
<Instrument ProgramNumber="51" Name="INST_51"/>
<Instrument ProgramNumber="54" Name="INST_54"/>
<Instrument ProgramNumber="55" Name="INST_55"/>
<Instrument ProgramNumber="56" Name="INST_56"/>
<Instrument ProgramNumber="57" Name="INST_57"/>
<Instrument ProgramNumber="58" Name="INST_58"/>
<Instrument ProgramNumber="59" Name="INST_59"/>
<Instrument ProgramNumber="61" Name="INST_61"/>
<Instrument ProgramNumber="62" Name="INST_62"/>
<Instrument ProgramNumber="63" Name="INST_63"/>
<Instrument ProgramNumber="64" Name="INST_64"/>
<Instrument ProgramNumber="65" Name="INST_65"/>
<Instrument ProgramNumber="66" Name="INST_66"/>
<Instrument ProgramNumber="67" Name="INST_67"/>
<Instrument ProgramNumber="68" Name="INST_68"/>
<Instrument ProgramNumber="69" Name="INST_69"/>
<Instrument ProgramNumber="70" Name="INST_70"/>
<Instrument ProgramNumber="71" Name="INST_71"/>
<Instrument ProgramNumber="72" Name="INST_72"/>
<Instrument ProgramNumber="73" Name="INST_73"/>
<Instrument ProgramNumber="74" Name="INST_74"/>
<Instrument ProgramNumber="75" Name="INST_75"/>
<Instrument ProgramNumber="76" Name="INST_76"/>
<Instrument ProgramNumber="77" Name="INST_77"/>
<Instrument ProgramNumber="78" Name="INST_78"/>
<Instrument ProgramNumber="60" Name="INST_60"/>
<Instrument ProgramNumber="79" Name="INST_79"/>
<Instrument ProgramNumber="80" Name="INST_80"/>
<Instrument ProgramNumber="81" Name="INST_81"/>
<Instrument ProgramNumber="46" Name="INST_46"/>
<Instrument ProgramNumber="84" Name="INST_84"/>
<Instrument ProgramNumber="87" Name="INST_87"/>
<Instrument ProgramNumber="88" Name="INST_88"/>
<Instrument ProgramNumber="89" Name="INST_89"/>
<Instrument ProgramNumber="90" Name="INST_90"/>
<Instrument ProgramNumber="85" Name="INST_85"/>
<Instrument ProgramNumber="86" Name="INST_86"/>
<Instrument ProgramNumber="83" Name="INST_83"/>
<Instrument ProgramNumber="82" Name="INST_82"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
</Drums>
<Effects>
<Effect Name="EFFECT_0"/>
<Effect Name="EFFECT_1"/>
<Effect Name="EFFECT_2"/>
<Effect Name="EFFECT_3"/>
<Effect Name="EFFECT_4"/>
<Effect Name="EFFECT_5"/>
<Effect Name="EFFECT_6"/>
<Effect Name="EFFECT_7"/>
<Effect Name="EFFECT_8"/>
<Effect Name="EFFECT_9"/>
<Effect Name="EFFECT_10"/>
<Effect Name="EFFECT_11"/>
<Effect Name="EFFECT_12"/>
<Effect Name="EFFECT_13"/>
<Effect Name="EFFECT_14"/>
<Effect Name="EFFECT_15"/>
<Effect Name="EFFECT_16"/>
<Effect Name="EFFECT_17"/>
<Effect Name="EFFECT_18"/>
<Effect Name="EFFECT_19"/>
<Effect Name="EFFECT_20"/>
<Effect Name="EFFECT_21"/>
<Effect Name="EFFECT_22"/>
<Effect Name="EFFECT_23"/>
<Effect Name="EFFECT_24"/>
<Effect Name="EFFECT_25"/>
<Effect Name="EFFECT_26"/>
<Effect Name="EFFECT_27"/>
<Effect Name="EFFECT_28"/>
<Effect Name="EFFECT_29"/>
<Effect Name="EFFECT_30"/>
<Effect Name="EFFECT_31"/>
<Effect Name="EFFECT_32"/>
<Effect Name="EFFECT_33"/>
<Effect Name="EFFECT_34"/>
<Effect Name="EFFECT_35"/>
<Effect Name="EFFECT_36"/>
<Effect Name="EFFECT_37"/>
<Effect Name="EFFECT_38"/>
<Effect Name="EFFECT_39"/>
<Effect Name="EFFECT_40"/>
<Effect Name="EFFECT_41"/>
<Effect Name="EFFECT_42"/>
<Effect Name="EFFECT_43"/>
<Effect Name="EFFECT_44"/>
<Effect Name="EFFECT_45"/>
<Effect Name="EFFECT_46"/>
<Effect Name="EFFECT_47"/>
<Effect Name="EFFECT_48"/>
<Effect Name="EFFECT_49"/>
<Effect Name="EFFECT_50"/>
<Effect Name="EFFECT_51"/>
<Effect Name="EFFECT_52"/>
<Effect Name="EFFECT_53"/>
<Effect Name="EFFECT_54"/>
<Effect Name="EFFECT_55"/>
<Effect Name="EFFECT_56"/>
<Effect Name="EFFECT_57"/>
<Effect Name="EFFECT_58"/>
<Effect Name="EFFECT_59"/>
<Effect Name="EFFECT_60"/>
<Effect Name="EFFECT_61"/>
<Effect Name="EFFECT_62"/>
<Effect Name="EFFECT_63"/>
<Effect Name="EFFECT_64"/>
<Effect Name="EFFECT_65"/>
<Effect Name="EFFECT_66"/>
<Effect Name="EFFECT_67"/>
<Effect Name="EFFECT_68"/>
<Effect Name="EFFECT_69"/>
<Effect Name="EFFECT_70"/>
<Effect Name="EFFECT_71"/>
<Effect Name="EFFECT_72"/>
<Effect Name="EFFECT_73"/>
<Effect Name="EFFECT_74"/>
<Effect Name="EFFECT_75"/>
<Effect Name="EFFECT_76"/>
<Effect Name="EFFECT_77"/>
<Effect Name="EFFECT_78"/>
<Effect Name="EFFECT_79"/>
<Effect Name="EFFECT_80"/>
<Effect Name="EFFECT_81"/>
<Effect Name="EFFECT_82"/>
<Effect Name="EFFECT_83"/>
<Effect Name="EFFECT_84"/>
<Effect Name="EFFECT_85"/>
<Effect Name="EFFECT_86"/>
<Effect Name="EFFECT_87"/>
<Effect Name="EFFECT_88"/>
<Effect Name="EFFECT_89"/>
<Effect Name="EFFECT_90"/>
<Effect Name="EFFECT_91"/>
<Effect Name="EFFECT_92"/>
<Effect Name="EFFECT_93"/>
<Effect Name="EFFECT_94"/>
<Effect Name="EFFECT_95"/>
<Effect Name="EFFECT_96"/>
<Effect Name="EFFECT_97"/>
<Effect Name="EFFECT_98"/>
<Effect Name="EFFECT_99"/>
<Effect Name="EFFECT_100"/>
<Effect Name="EFFECT_101"/>
<Effect Name="EFFECT_102"/>
<Effect Name="EFFECT_103"/>
<Effect Name="EFFECT_104"/>
<Effect Name="EFFECT_105"/>
<Effect Name="EFFECT_106"/>
<Effect Name="EFFECT_107"/>
<Effect Name="EFFECT_108"/>
<Effect Name="EFFECT_109"/>
<Effect Name="EFFECT_110"/>
<Effect Name="EFFECT_111"/>
<Effect Name="EFFECT_112"/>
<Effect Name="EFFECT_113"/>
<Effect Name="EFFECT_114"/>
<Effect Name="EFFECT_115"/>
<Effect Name="EFFECT_116"/>
<Effect Name="EFFECT_117"/>
<Effect Name="EFFECT_118"/>
<Effect Name="EFFECT_119"/>
<Effect Name="EFFECT_120"/>
<Effect Name="EFFECT_121"/>
<Effect Name="EFFECT_122"/>
<Effect Name="EFFECT_123"/>
<Effect Name="EFFECT_124"/>
<Effect Name="EFFECT_125"/>
<Effect Name="EFFECT_126"/>
<Effect Name="EFFECT_127"/>
<Effect Name="EFFECT_128"/>
<Effect Name="EFFECT_129"/>
<Effect Name="EFFECT_130"/>
<Effect Name="EFFECT_131"/>
<Effect Name="EFFECT_132"/>
<Effect Name="EFFECT_133"/>
<Effect Name="EFFECT_134"/>
<Effect Name="EFFECT_135"/>
</Effects>
</SoundFont>

View file

@ -0,0 +1,102 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_1" Index="1">
<Envelopes>
<Envelope Name="Env0"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="18" Name="INST_18"/>
<Instrument ProgramNumber="19" Name="INST_19"/>
<Instrument ProgramNumber="20" Name="INST_20"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="9" Name="INST_9"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="23" Name="INST_23"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="15" Name="INST_15"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
<Instrument ProgramNumber="16" Name="INST_16"/>
<Instrument ProgramNumber="17" Name="INST_17"/>
<Instrument ProgramNumber="25" Name="INST_25"/>
<Instrument ProgramNumber="26" Name="INST_26"/>
<Instrument ProgramNumber="27" Name="INST_27"/>
<Instrument ProgramNumber="28" Name="INST_28"/>
<Instrument ProgramNumber="21" Name="INST_21"/>
<Instrument ProgramNumber="24" Name="INST_24"/>
<Instrument ProgramNumber="29" Name="INST_29"/>
<Instrument ProgramNumber="30" Name="INST_30"/>
<Instrument ProgramNumber="31" Name="INST_31"/>
<Instrument ProgramNumber="32" Name="INST_32"/>
<Instrument ProgramNumber="33" Name="INST_33"/>
<Instrument ProgramNumber="34" Name="INST_34"/>
<Instrument ProgramNumber="35" Name="INST_35"/>
<Instrument ProgramNumber="36" Name="INST_36"/>
<Instrument ProgramNumber="37" Name="INST_37"/>
<Instrument ProgramNumber="41" Name="INST_41"/>
<Instrument ProgramNumber="42" Name="INST_42"/>
<Instrument ProgramNumber="43" Name="INST_43"/>
<Instrument ProgramNumber="45" Name="INST_45"/>
<Instrument ProgramNumber="46" Name="INST_46"/>
<Instrument ProgramNumber="48" Name="INST_48"/>
<Instrument ProgramNumber="50" Name="INST_50"/>
<Instrument ProgramNumber="38" Name="INST_38"/>
<Instrument ProgramNumber="39" Name="INST_39"/>
<Instrument ProgramNumber="40" Name="INST_40"/>
<Instrument ProgramNumber="44" Name="INST_44"/>
<Instrument ProgramNumber="22" Name="INST_22"/>
<Instrument ProgramNumber="47" Name="INST_47"/>
<Instrument ProgramNumber="49" Name="INST_49"/>
</Instruments>
<Effects>
<Effect Name="EFFECT_0"/>
<Effect Name="EFFECT_1"/>
<Effect Name="EFFECT_2"/>
<Effect Name="EFFECT_3"/>
<Effect Name="EFFECT_4"/>
<Effect Name="EFFECT_5"/>
<Effect Name="EFFECT_6"/>
<Effect Name="EFFECT_7"/>
<Effect Name="EFFECT_8"/>
<Effect Name="EFFECT_9"/>
<Effect Name="EFFECT_10"/>
<Effect Name="EFFECT_11"/>
<Effect Name="EFFECT_12"/>
<Effect Name="EFFECT_13"/>
<Effect Name="EFFECT_14"/>
<Effect Name="EFFECT_15"/>
<Effect Name="EFFECT_16"/>
<Effect Name="EFFECT_17"/>
<Effect Name="EFFECT_18"/>
<Effect Name="EFFECT_19"/>
<Effect Name="EFFECT_20"/>
<Effect Name="EFFECT_21"/>
<Effect Name="EFFECT_22"/>
<Effect Name="EFFECT_23"/>
<Effect Name="EFFECT_24"/>
<Effect Name="EFFECT_25"/>
<Effect Name="EFFECT_26"/>
<Effect Name="EFFECT_27"/>
<Effect Name="EFFECT_28"/>
<Effect Name="EFFECT_29"/>
<Effect Name="EFFECT_30"/>
<Effect Name="EFFECT_31"/>
<Effect Name="EFFECT_32"/>
<Effect Name="EFFECT_33"/>
<Effect Name="EFFECT_34"/>
<Effect Name="EFFECT_35"/>
<Effect Name="EFFECT_36"/>
<Effect Name="EFFECT_37"/>
<Effect Name="EFFECT_38"/>
<Effect Name="EFFECT_39"/>
<Effect Name="EFFECT_40"/>
</Effects>
</SoundFont>

View file

@ -0,0 +1,23 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_10" Index="10">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,15 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_11" Index="11">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,13 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_12" Index="12">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,24 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_13" Index="13">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
<Instrument ProgramNumber="15" Name="INST_15"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,15 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_14" Index="14">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,26 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_15" Index="15">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
<Instrument ProgramNumber="15" Name="INST_15"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,23 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_16" Index="16">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="0" Name="INST_0"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,18 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_17" Index="17">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,29 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_18" Index="18">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
<Drum Name="DRUM_4"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,14 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_19" Index="19">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,28 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_2" Index="2">
<Envelopes>
<Envelope Name="Env0"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="9" Name="INST_9"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
<Instrument ProgramNumber="15" Name="INST_15"/>
<Instrument ProgramNumber="16" Name="INST_16"/>
<Instrument ProgramNumber="17" Name="INST_17"/>
<Instrument ProgramNumber="18" Name="INST_18"/>
<Instrument ProgramNumber="19" Name="INST_19"/>
<Instrument ProgramNumber="20" Name="INST_20"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,23 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_20" Index="20">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
<Drum Name="DRUM_4"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,20 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_21" Index="21">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,25 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_22" Index="22">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,14 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_23" Index="23">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,23 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_24" Index="24">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
<Envelope Name="Env7"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,19 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_25" Index="25">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,10 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_26" Index="26">
<Envelopes>
<Envelope Name="Env0"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="14" Name="INST_14"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,21 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_27" Index="27">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,15 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_28" Index="28">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,22 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_29" Index="29">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,37 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_3" Index="3">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
<Envelope Name="Env7"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
<Instrument ProgramNumber="15" Name="INST_15"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
<Drum Name="DRUM_4"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,13 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_30" Index="30">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,19 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_31" Index="31">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,32 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_32" Index="32">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="15" Name="INST_15"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
<Drum Name="DRUM_4"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,37 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_33" Index="33">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
<Envelope Name="Env7"/>
<Envelope Name="Env8"/>
<Envelope Name="Env9"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
<Instrument ProgramNumber="15" Name="INST_15"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
<Drum Name="DRUM_4"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,42 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_34" Index="34">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
<Envelope Name="Env7"/>
<Envelope Name="Env8"/>
<Envelope Name="Env9"/>
<Envelope Name="Env10"/>
<Envelope Name="Env11"/>
<Envelope Name="Env12"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
<Instrument ProgramNumber="15" Name="INST_15"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
<Drum Name="DRUM_4"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,26 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_35" Index="35">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
<Drum Name="DRUM_4"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,17 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_36" Index="36">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,11 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_37" Index="37">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,11 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_4" Index="4">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,22 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_5" Index="5">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,16 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_6" Index="6">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="13" Name="INST_13"/>
<Instrument ProgramNumber="14" Name="INST_14"/>
</Instruments>
</SoundFont>

View file

@ -0,0 +1,17 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_7" Index="7">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,26 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_8" Index="8">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
</Drums>
</SoundFont>

View file

@ -0,0 +1,34 @@
<!-- This file is only for extraction of vanilla data. For other purposes see assets/audio/soundfonts/ -->
<SoundFont Name="Soundfont_9" Index="9">
<Envelopes>
<Envelope Name="Env0"/>
<Envelope Name="Env1"/>
<Envelope Name="Env2"/>
<Envelope Name="Env3"/>
<Envelope Name="Env4"/>
<Envelope Name="Env5"/>
<Envelope Name="Env6"/>
<Envelope Name="Env7"/>
</Envelopes>
<Instruments>
<Instrument ProgramNumber="0" Name="INST_0"/>
<Instrument ProgramNumber="1" Name="INST_1"/>
<Instrument ProgramNumber="2" Name="INST_2"/>
<Instrument ProgramNumber="3" Name="INST_3"/>
<Instrument ProgramNumber="4" Name="INST_4"/>
<Instrument ProgramNumber="5" Name="INST_5"/>
<Instrument ProgramNumber="6" Name="INST_6"/>
<Instrument ProgramNumber="7" Name="INST_7"/>
<Instrument ProgramNumber="8" Name="INST_8"/>
<Instrument ProgramNumber="10" Name="INST_10"/>
<Instrument ProgramNumber="11" Name="INST_11"/>
<Instrument ProgramNumber="12" Name="INST_12"/>
</Instruments>
<Drums>
<Drum Name="DRUM_0"/>
<Drum Name="DRUM_1"/>
<Drum Name="DRUM_2"/>
<Drum Name="DRUM_3"/>
<Drum Name="DRUM_4"/>
</Drums>
</SoundFont>

View file

@ -1,21 +1,20 @@
<Root>
<File Name="object_mag" Segment="6">
<Texture Name="gTitleZeldaShieldLogoTex" OutName="title_zelda_shield_logo" Format="rgba32" Width="160" Height="160" Offset="0x0"/>
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16" Offset="0x19000"/>
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16" Offset="0x19A00"/>
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16" Offset="0x1A400"/>
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64" Offset="0x1A700"/>
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64" Offset="0x1AF00"/>
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64" Offset="0x1B700"/>
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64" Offset="0x1BF00"/>
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64" Offset="0x1C700"/>
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64" Offset="0x1CF00"/>
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64" Offset="0x1D700"/>
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64" Offset="0x1DF00"/>
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64" Offset="0x1E700"/>
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32" Offset="0x1EF00"/>
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8" Offset="0x1F300"/>
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8" Offset="0x1F540"/>
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16" Offset="0x1F840"/>
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16" Offset="0x0"/>
<Texture Name="gTitleZeldaShieldLogoTex" OutName="title_zelda_shield_logo" Format="rgba32" Width="160" Height="160" Offset="0x300"/>
<Texture Name="gTitleCopyright1998Tex" OutName="title_copyright_1998" Format="ia8" Width="128" Height="16" Offset="0x19300"/>
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64" Offset="0x19B00"/>
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64" Offset="0x1A300"/>
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64" Offset="0x1AB00"/>
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64" Offset="0x1B300"/>
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64" Offset="0x1BB00"/>
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64" Offset="0x1C300"/>
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64" Offset="0x1CB00"/>
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64" Offset="0x1D300"/>
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64" Offset="0x1DB00"/>
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32" Offset="0x1E300"/>
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8" Offset="0x1E700"/>
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8" Offset="0x1E940"/>
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16" Offset="0x1EC40"/>
</File>
</Root>

View file

@ -0,0 +1,20 @@
<Root>
<File Name="object_mag" Segment="6">
<Texture Name="gTitleZeldaShieldLogoTex" OutName="title_zelda_shield_logo" Format="rgba32" Width="160" Height="160" Offset="0x0"/>
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16" Offset="0x19000"/>
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16" Offset="0x19A00"/>
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64" Offset="0x19D00"/>
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64" Offset="0x1A500"/>
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64" Offset="0x1AD00"/>
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64" Offset="0x1B500"/>
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64" Offset="0x1BD00"/>
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64" Offset="0x1C500"/>
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64" Offset="0x1CD00"/>
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64" Offset="0x1D500"/>
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64" Offset="0x1DD00"/>
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32" Offset="0x1E500"/>
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8" Offset="0x1E900"/>
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8" Offset="0x1EB40"/>
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16" Offset="0x1EE40"/>
</File>
</Root>

View file

@ -0,0 +1,21 @@
<Root>
<File Name="object_mag" Segment="6">
<Texture Name="gTitleZeldaShieldLogoTex" OutName="title_zelda_shield_logo" Format="rgba32" Width="160" Height="160" Offset="0x0"/>
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16" Offset="0x19000"/>
<Texture Name="gTitleUraLogoTex" OutName="title_ura_logo" Format="rgba32" Width="40" Height="40" Offset="0x19A00"/>
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16" Offset="0x1B300"/>
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64" Offset="0x1B600"/>
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64" Offset="0x1BE00"/>
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64" Offset="0x1C600"/>
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64" Offset="0x1CE00"/>
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64" Offset="0x1D600"/>
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64" Offset="0x1DE00"/>
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64" Offset="0x1E600"/>
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64" Offset="0x1EE00"/>
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64" Offset="0x1F600"/>
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32" Offset="0x1FE00"/>
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8" Offset="0x20200"/>
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8" Offset="0x20440"/>
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16" Offset="0x20740"/>
</File>
</Root>

View file

@ -0,0 +1,21 @@
<Root>
<File Name="object_mag" Segment="6">
<Texture Name="gTitleZeldaShieldLogoTex" OutName="title_zelda_shield_logo" Format="rgba32" Width="160" Height="160" Offset="0x0"/>
<Texture Name="gTitleCopyright19982002Tex" OutName="title_copyright_19982002" Format="ia8" Width="160" Height="16" Offset="0x19000"/>
<Texture Name="gTitleCopyright19982003Tex" OutName="title_copyright_19982003" Format="ia8" Width="160" Height="16" Offset="0x19A00"/>
<Texture Name="gTitleDiskTex" OutName="title_disk" Format="ia8" Width="48" Height="16" Offset="0x1A400"/>
<Texture Name="gTitleEffectMask00Tex" OutName="title_effect_mask_0_0" Format="i4" Width="64" Height="64" Offset="0x1A700"/>
<Texture Name="gTitleEffectMask01Tex" OutName="title_effect_mask_0_1" Format="i4" Width="64" Height="64" Offset="0x1AF00"/>
<Texture Name="gTitleEffectMask02Tex" OutName="title_effect_mask_0_2" Format="i4" Width="64" Height="64" Offset="0x1B700"/>
<Texture Name="gTitleEffectMask10Tex" OutName="title_effect_mask_1_0" Format="i4" Width="64" Height="64" Offset="0x1BF00"/>
<Texture Name="gTitleEffectMask11Tex" OutName="title_effect_mask_1_1" Format="i4" Width="64" Height="64" Offset="0x1C700"/>
<Texture Name="gTitleEffectMask12Tex" OutName="title_effect_mask_1_2" Format="i4" Width="64" Height="64" Offset="0x1CF00"/>
<Texture Name="gTitleEffectMask20Tex" OutName="title_effect_mask_2_0" Format="i4" Width="64" Height="64" Offset="0x1D700"/>
<Texture Name="gTitleEffectMask21Tex" OutName="title_effect_mask_2_1" Format="i4" Width="64" Height="64" Offset="0x1DF00"/>
<Texture Name="gTitleEffectMask22Tex" OutName="title_effect_mask_2_2" Format="i4" Width="64" Height="64" Offset="0x1E700"/>
<Texture Name="gTitleFlameEffectTex" OutName="title_flame_effect" Format="i8" Width="32" Height="32" Offset="0x1EF00"/>
<Texture Name="gTitleTheLegendOfTextTex" OutName="title_the_legend_of_text" Format="i8" Width="72" Height="8" Offset="0x1F300"/>
<Texture Name="gTitleOcarinaOfTimeTMTextTex" OutName="title_ocarina_of_time_tm_text" Format="i8" Width="96" Height="8" Offset="0x1F540"/>
<Texture Name="gTitleTitleJPNTex" OutName="title_title_jpn" Format="i8" Width="128" Height="16" Offset="0x1F840"/>
</File>
</Root>

View file

@ -3,25 +3,31 @@
<Array Name="D_80811BB0" Count="24" Offset="0x0" Static="Off">
<Vtx/>
</Array>
<Array Name="D_80811D30" Count="16" Offset="0x180" Static="Off">
<Array Name="gCharPageHira" Count="65" Offset="0x180" Static="Off">
<Scalar Type="s16"/>
</Array>
<Array Name="gCharPageKata" Count="65" Offset="0x204" Static="Off">
<Scalar Type="s16"/>
</Array>
<Array Name="gCharPageEng" Count="65" Offset="0x288" Static="Off">
<Scalar Type="s16"/>
</Array>
<Array Name="gNextCharPage" Count="9" Offset="0x30C" Static="Off">
<Scalar Type="s16"/>
</Array>
<Array Name="D_80811D30" Count="16" Offset="0x320" Static="Off">
<Vtx/>
</Array>
<Array Name="D_80811E30" Count="16" Offset="0x280" Static="Off">
<Array Name="D_80811F30" Count="32" Offset="0x420" Static="Off">
<Vtx/>
</Array>
<Array Name="D_80811F30" Count="32" Offset="0x380" Static="Off">
<Array Name="gOptionsDividerTopVtx" Count="4" Offset="0x620" Static="Off">
<Vtx/>
</Array>
<Array Name="D_80812130" Count="32" Offset="0x580" Static="Off">
<Array Name="gOptionsDividerMiddleVtx" Count="4" Offset="0x660" Static="Off">
<Vtx/>
</Array>
<Array Name="gOptionsDividerTopVtx" Count="4" Offset="0x780" Static="Off">
<Vtx/>
</Array>
<Array Name="gOptionsDividerMiddleVtx" Count="4" Offset="0x7C0" Static="Off">
<Vtx/>
</Array>
<Array Name="gOptionsDividerBottomVtx" Count="4" Offset="0x800" Static="Off">
<Array Name="gOptionsDividerBottomVtx" Count="4" Offset="0x6A0" Static="Off">
<Vtx/>
</Array>
</File>

View file

@ -0,0 +1,31 @@
<Root>
<File Name="ovl_file_choose">
<Array Name="D_80811BB0" Count="24" Offset="0x0" Static="Off">
<Vtx/>
</Array>
<Array Name="D_80811D30" Count="16" Offset="0x180" Static="Off">
<Vtx/>
</Array>
<Array Name="D_80811E30" Count="16" Offset="0x280" Static="Off">
<Vtx/>
</Array>
<Array Name="D_80811F30" Count="32" Offset="0x380" Static="Off">
<Vtx/>
</Array>
<Array Name="D_80812130" Count="32" Offset="0x580" Static="Off">
<Vtx/>
</Array>
<Array Name="gOptionsDividerTopVtx" Count="4" Offset="0x780" Static="Off">
<Vtx/>
</Array>
<Array Name="gOptionsDividerMiddleVtx" Count="4" Offset="0x7C0" Static="Off">
<Vtx/>
</Array>
<Array Name="gOptionsDividerBottomVtx" Count="4" Offset="0x800" Static="Off">
<Vtx/>
</Array>
<Array Name="gCharPageEng" Count="65" Offset="0x840" Static="Off">
<Scalar Type="s16"/>
</Array>
</File>
</Root>

View file

@ -11,8 +11,8 @@
<Texture Name="gPauseBotWTitleJPNTex" OutName="pause_botw_title_jpn" Format="ia8" Width="96" Height="16" Offset="0x3000"/>
<Texture Name="gPauseIceCavernTitleJPNTex" OutName="pause_ice_cavern_title_jpn" Format="ia8" Width="96" Height="16" Offset="0x3600"/>
<Texture Name="gPauseToEquipJPNTex" OutName="pause_to_equip_jpn" Format="ia8" Width="56" Height="16" Offset="0x3C00"/>
<Texture Name="gPauseToDecideJPNTex" OutName="pause_to_decide_jpn" Format="ia8" Width="64" Height="16" Offset="0x3F80"/>
<Texture Name="gPauseToPlayMelodyJPNTex" OutName="pause_to_play_melody_jpn" Format="ia8" Width="80" Height="16" Offset="0x4380"/>
<Texture Name="gPauseToDecideJPNTex" OutName="pause_to_decide_jpn" Format="ia8" Width="48" Height="16" Offset="0x3F80"/>
<Texture Name="gPauseToPlayMelodyJPNTex" OutName="pause_to_play_melody_jpn" Format="ia8" Width="96" Height="16" Offset="0x4280"/>
<Texture Name="gPauseToSelectItemJPNTex" OutName="pause_to_select_item_jpn" Format="ia8" Width="128" Height="16" Offset="0x4880"/>
<Texture Name="gPauseToMapJPNTex" OutName="pause_to_map_jpn" Format="ia8" Width="128" Height="16" Offset="0x5080"/>
<Texture Name="gPauseToQuestStatusJPNTex" OutName="pause_to_quest_status_jpn" Format="ia8" Width="128" Height="16" Offset="0x5880"/>

View file

@ -140,6 +140,5 @@
<Texture Name="gMsgCharA8ButtonCRightTex" OutName="msg_char_a8_button_c_right" Format="i4" Width="16" Height="16" Offset="0x4400"/>
<Texture Name="gMsgCharA9ZTargetSignTex" OutName="msg_char_a9_z_target_sign" Format="i4" Width="16" Height="16" Offset="0x4480"/>
<Texture Name="gMsgCharAAControlStickTex" OutName="msg_char_aa_control_stick" Format="i4" Width="16" Height="16" Offset="0x4500"/>
<Texture Name="gMsgCharABControlPadTex" OutName="msg_char_ab_control_pad" Format="i4" Width="16" Height="16" Offset="0x4580"/>
</File>
</Root>

View file

@ -0,0 +1,145 @@
<Root>
<File Name="nes_font_static" Segment="10">
<!-- The two-digit number after the prefix is the character's codepoint: the hexadecimal byte it corresponds to in the text data -->
<Texture Name="gMsgChar20SpaceTex" OutName="msg_char_20_space" Format="i4" Width="16" Height="16" Offset="0x0"/>
<Texture Name="gMsgChar21ExclamationMarkTex" OutName="msg_char_21_exclamation_mark" Format="i4" Width="16" Height="16" Offset="0x80"/>
<Texture Name="gMsgChar22QuotationMarkTex" OutName="msg_char_22_quotation_mark" Format="i4" Width="16" Height="16" Offset="0x100"/>
<Texture Name="gMsgChar23NumberSignTex" OutName="msg_char_23_number_sign" Format="i4" Width="16" Height="16" Offset="0x180"/>
<Texture Name="gMsgChar24DollarSignTex" OutName="msg_char_24_dollar_sign" Format="i4" Width="16" Height="16" Offset="0x200"/>
<Texture Name="gMsgChar25PercentSignTex" OutName="msg_char_25_percent_sign" Format="i4" Width="16" Height="16" Offset="0x280"/>
<Texture Name="gMsgChar26AmpersandTex" OutName="msg_char_26_ampersand" Format="i4" Width="16" Height="16" Offset="0x300"/>
<Texture Name="gMsgChar27ApostropheTex" OutName="msg_char_27_apostrophe" Format="i4" Width="16" Height="16" Offset="0x380"/>
<Texture Name="gMsgChar28LeftParenthesesTex" OutName="msg_char_28_left_parentheses" Format="i4" Width="16" Height="16" Offset="0x400"/>
<Texture Name="gMsgChar29RightParenthesesTex" OutName="msg_char_29_right_parentheses" Format="i4" Width="16" Height="16" Offset="0x480"/>
<Texture Name="gMsgChar2AAsteriskTex" OutName="msg_char_2a_asterisk" Format="i4" Width="16" Height="16" Offset="0x500"/>
<Texture Name="gMsgChar2BPlusSignTex" OutName="msg_char_2b_plus_sign" Format="i4" Width="16" Height="16" Offset="0x580"/>
<Texture Name="gMsgChar2CCommaTex" OutName="msg_char_2c_comma" Format="i4" Width="16" Height="16" Offset="0x600"/>
<Texture Name="gMsgChar2DHyphenMinusTex" OutName="msg_char_2d_hyphen_minus" Format="i4" Width="16" Height="16" Offset="0x680"/>
<Texture Name="gMsgChar2EFullStopTex" OutName="msg_char_2e_full_stop" Format="i4" Width="16" Height="16" Offset="0x700"/>
<Texture Name="gMsgChar2FSolidusTex" OutName="msg_char_2f_solidus" Format="i4" Width="16" Height="16" Offset="0x780"/>
<Texture Name="gMsgChar30Digit0Tex" OutName="msg_char_30_digit_0" Format="i4" Width="16" Height="16" Offset="0x800"/>
<Texture Name="gMsgChar31Digit1Tex" OutName="msg_char_31_digit_1" Format="i4" Width="16" Height="16" Offset="0x880"/>
<Texture Name="gMsgChar32Digit2Tex" OutName="msg_char_32_digit_2" Format="i4" Width="16" Height="16" Offset="0x900"/>
<Texture Name="gMsgChar33Digit3Tex" OutName="msg_char_33_digit_3" Format="i4" Width="16" Height="16" Offset="0x980"/>
<Texture Name="gMsgChar34Digit4Tex" OutName="msg_char_34_digit_4" Format="i4" Width="16" Height="16" Offset="0xA00"/>
<Texture Name="gMsgChar35Digit5Tex" OutName="msg_char_35_digit_5" Format="i4" Width="16" Height="16" Offset="0xA80"/>
<Texture Name="gMsgChar36Digit6Tex" OutName="msg_char_36_digit_6" Format="i4" Width="16" Height="16" Offset="0xB00"/>
<Texture Name="gMsgChar37Digit7Tex" OutName="msg_char_37_digit_7" Format="i4" Width="16" Height="16" Offset="0xB80"/>
<Texture Name="gMsgChar38Digit8Tex" OutName="msg_char_38_digit_8" Format="i4" Width="16" Height="16" Offset="0xC00"/>
<Texture Name="gMsgChar39Digit9Tex" OutName="msg_char_39_digit_9" Format="i4" Width="16" Height="16" Offset="0xC80"/>
<Texture Name="gMsgChar3AColonTex" OutName="msg_char_3a_colon" Format="i4" Width="16" Height="16" Offset="0xD00"/>
<Texture Name="gMsgChar3BSemicolonTex" OutName="msg_char_3b_semicolon" Format="i4" Width="16" Height="16" Offset="0xD80"/>
<Texture Name="gMsgChar3CLessThanSignTex" OutName="msg_char_3c_less_than_sign" Format="i4" Width="16" Height="16" Offset="0xE00"/>
<Texture Name="gMsgChar3DEqualsSignTex" OutName="msg_char_3d_equals_sign" Format="i4" Width="16" Height="16" Offset="0xE80"/>
<Texture Name="gMsgChar3EGreaterThanSignTex" OutName="msg_char_3e_greater_than_sign" Format="i4" Width="16" Height="16" Offset="0xF00"/>
<Texture Name="gMsgChar3FQuestionMarkTex" OutName="msg_char_3f_question_mark" Format="i4" Width="16" Height="16" Offset="0xF80"/>
<Texture Name="gMsgChar40CommercialAtTex" OutName="msg_char_40_commercial_at" Format="i4" Width="16" Height="16" Offset="0x1000"/>
<Texture Name="gMsgChar41LatinCapitalLetterATex" OutName="msg_char_41_latin_capital_letter_a" Format="i4" Width="16" Height="16" Offset="0x1080"/>
<Texture Name="gMsgChar42LatinCapitalLetterBTex" OutName="msg_char_42_latin_capital_letter_b" Format="i4" Width="16" Height="16" Offset="0x1100"/>
<Texture Name="gMsgChar43LatinCapitalLetterCTex" OutName="msg_char_43_latin_capital_letter_c" Format="i4" Width="16" Height="16" Offset="0x1180"/>
<Texture Name="gMsgChar44LatinCapitalLetterDTex" OutName="msg_char_44_latin_capital_letter_d" Format="i4" Width="16" Height="16" Offset="0x1200"/>
<Texture Name="gMsgChar45LatinCapitalLetterETex" OutName="msg_char_45_latin_capital_letter_e" Format="i4" Width="16" Height="16" Offset="0x1280"/>
<Texture Name="gMsgChar46LatinCapitalLetterFTex" OutName="msg_char_46_latin_capital_letter_f" Format="i4" Width="16" Height="16" Offset="0x1300"/>
<Texture Name="gMsgChar47LatinCapitalLetterGTex" OutName="msg_char_47_latin_capital_letter_g" Format="i4" Width="16" Height="16" Offset="0x1380"/>
<Texture Name="gMsgChar48LatinCapitalLetterHTex" OutName="msg_char_48_latin_capital_letter_h" Format="i4" Width="16" Height="16" Offset="0x1400"/>
<Texture Name="gMsgChar49LatinCapitalLetterITex" OutName="msg_char_49_latin_capital_letter_i" Format="i4" Width="16" Height="16" Offset="0x1480"/>
<Texture Name="gMsgChar4ALatinCapitalLetterJTex" OutName="msg_char_4a_latin_capital_letter_j" Format="i4" Width="16" Height="16" Offset="0x1500"/>
<Texture Name="gMsgChar4BLatinCapitalLetterKTex" OutName="msg_char_4b_latin_capital_letter_k" Format="i4" Width="16" Height="16" Offset="0x1580"/>
<Texture Name="gMsgChar4CLatinCapitalLetterLTex" OutName="msg_char_4c_latin_capital_letter_l" Format="i4" Width="16" Height="16" Offset="0x1600"/>
<Texture Name="gMsgChar4DLatinCapitalLetterMTex" OutName="msg_char_4d_latin_capital_letter_m" Format="i4" Width="16" Height="16" Offset="0x1680"/>
<Texture Name="gMsgChar4ELatinCapitalLetterNTex" OutName="msg_char_4e_latin_capital_letter_n" Format="i4" Width="16" Height="16" Offset="0x1700"/>
<Texture Name="gMsgChar4FLatinCapitalLetterOTex" OutName="msg_char_4f_latin_capital_letter_o" Format="i4" Width="16" Height="16" Offset="0x1780"/>
<Texture Name="gMsgChar50LatinCapitalLetterPTex" OutName="msg_char_50_latin_capital_letter_p" Format="i4" Width="16" Height="16" Offset="0x1800"/>
<Texture Name="gMsgChar51LatinCapitalLetterQTex" OutName="msg_char_51_latin_capital_letter_q" Format="i4" Width="16" Height="16" Offset="0x1880"/>
<Texture Name="gMsgChar52LatinCapitalLetterRTex" OutName="msg_char_52_latin_capital_letter_r" Format="i4" Width="16" Height="16" Offset="0x1900"/>
<Texture Name="gMsgChar53LatinCapitalLetterSTex" OutName="msg_char_53_latin_capital_letter_s" Format="i4" Width="16" Height="16" Offset="0x1980"/>
<Texture Name="gMsgChar54LatinCapitalLetterTTex" OutName="msg_char_54_latin_capital_letter_t" Format="i4" Width="16" Height="16" Offset="0x1A00"/>
<Texture Name="gMsgChar55LatinCapitalLetterUTex" OutName="msg_char_55_latin_capital_letter_u" Format="i4" Width="16" Height="16" Offset="0x1A80"/>
<Texture Name="gMsgChar56LatinCapitalLetterVTex" OutName="msg_char_56_latin_capital_letter_v" Format="i4" Width="16" Height="16" Offset="0x1B00"/>
<Texture Name="gMsgChar57LatinCapitalLetterWTex" OutName="msg_char_57_latin_capital_letter_w" Format="i4" Width="16" Height="16" Offset="0x1B80"/>
<Texture Name="gMsgChar58LatinCapitalLetterXTex" OutName="msg_char_58_latin_capital_letter_x" Format="i4" Width="16" Height="16" Offset="0x1C00"/>
<Texture Name="gMsgChar59LatinCapitalLetterYTex" OutName="msg_char_59_latin_capital_letter_y" Format="i4" Width="16" Height="16" Offset="0x1C80"/>
<Texture Name="gMsgChar5ALatinCapitalLetterZTex" OutName="msg_char_5a_latin_capital_letter_z" Format="i4" Width="16" Height="16" Offset="0x1D00"/>
<Texture Name="gMsgChar5BLeftSquareBracketTex" OutName="msg_char_5b_left_square_bracket" Format="i4" Width="16" Height="16" Offset="0x1D80"/>
<Texture Name="gMsgChar5CYenSignTex" OutName="msg_char_5c_yen_sign" Format="i4" Width="16" Height="16" Offset="0x1E00"/>
<Texture Name="gMsgChar5DRightSquareBracketTex" OutName="msg_char_5d_right_square_bracket" Format="i4" Width="16" Height="16" Offset="0x1E80"/>
<Texture Name="gMsgChar5ECircumflexAccentTex" OutName="msg_char_5e_circumflex_accent" Format="i4" Width="16" Height="16" Offset="0x1F00"/>
<Texture Name="gMsgChar5FLowLineTex" OutName="msg_char_5f_low_line" Format="i4" Width="16" Height="16" Offset="0x1F80"/>
<Texture Name="gMsgChar60GraveAccentTex" OutName="msg_char_60_grave_accent" Format="i4" Width="16" Height="16" Offset="0x2000"/>
<Texture Name="gMsgChar61LatinSmallLetterATex" OutName="msg_char_61_latin_small_letter_a" Format="i4" Width="16" Height="16" Offset="0x2080"/>
<Texture Name="gMsgChar62LatinSmallLetterBTex" OutName="msg_char_62_latin_small_letter_b" Format="i4" Width="16" Height="16" Offset="0x2100"/>
<Texture Name="gMsgChar63LatinSmallLetterCTex" OutName="msg_char_63_latin_small_letter_c" Format="i4" Width="16" Height="16" Offset="0x2180"/>
<Texture Name="gMsgChar64LatinSmallLetterDTex" OutName="msg_char_64_latin_small_letter_d" Format="i4" Width="16" Height="16" Offset="0x2200"/>
<Texture Name="gMsgChar65LatinSmallLetterETex" OutName="msg_char_65_latin_small_letter_e" Format="i4" Width="16" Height="16" Offset="0x2280"/>
<Texture Name="gMsgChar66LatinSmallLetterFTex" OutName="msg_char_66_latin_small_letter_f" Format="i4" Width="16" Height="16" Offset="0x2300"/>
<Texture Name="gMsgChar67LatinSmallLetterGTex" OutName="msg_char_67_latin_small_letter_g" Format="i4" Width="16" Height="16" Offset="0x2380"/>
<Texture Name="gMsgChar68LatinSmallLetterHTex" OutName="msg_char_68_latin_small_letter_h" Format="i4" Width="16" Height="16" Offset="0x2400"/>
<Texture Name="gMsgChar69LatinSmallLetterITex" OutName="msg_char_69_latin_small_letter_i" Format="i4" Width="16" Height="16" Offset="0x2480"/>
<Texture Name="gMsgChar6ALatinSmallLetterJTex" OutName="msg_char_6a_latin_small_letter_j" Format="i4" Width="16" Height="16" Offset="0x2500"/>
<Texture Name="gMsgChar6BLatinSmallLetterKTex" OutName="msg_char_6b_latin_small_letter_k" Format="i4" Width="16" Height="16" Offset="0x2580"/>
<Texture Name="gMsgChar6CLatinSmallLetterLTex" OutName="msg_char_6c_latin_small_letter_l" Format="i4" Width="16" Height="16" Offset="0x2600"/>
<Texture Name="gMsgChar6DLatinSmallLetterMTex" OutName="msg_char_6d_latin_small_letter_m" Format="i4" Width="16" Height="16" Offset="0x2680"/>
<Texture Name="gMsgChar6ELatinSmallLetterNTex" OutName="msg_char_6e_latin_small_letter_n" Format="i4" Width="16" Height="16" Offset="0x2700"/>
<Texture Name="gMsgChar6FLatinSmallLetterOTex" OutName="msg_char_6f_latin_small_letter_o" Format="i4" Width="16" Height="16" Offset="0x2780"/>
<Texture Name="gMsgChar70LatinSmallLetterPTex" OutName="msg_char_70_latin_small_letter_p" Format="i4" Width="16" Height="16" Offset="0x2800"/>
<Texture Name="gMsgChar71LatinSmallLetterQTex" OutName="msg_char_71_latin_small_letter_q" Format="i4" Width="16" Height="16" Offset="0x2880"/>
<Texture Name="gMsgChar72LatinSmallLetterRTex" OutName="msg_char_72_latin_small_letter_r" Format="i4" Width="16" Height="16" Offset="0x2900"/>
<Texture Name="gMsgChar73LatinSmallLetterSTex" OutName="msg_char_73_latin_small_letter_s" Format="i4" Width="16" Height="16" Offset="0x2980"/>
<Texture Name="gMsgChar74LatinSmallLetterTTex" OutName="msg_char_74_latin_small_letter_t" Format="i4" Width="16" Height="16" Offset="0x2A00"/>
<Texture Name="gMsgChar75LatinSmallLetterUTex" OutName="msg_char_75_latin_small_letter_u" Format="i4" Width="16" Height="16" Offset="0x2A80"/>
<Texture Name="gMsgChar76LatinSmallLetterVTex" OutName="msg_char_76_latin_small_letter_v" Format="i4" Width="16" Height="16" Offset="0x2B00"/>
<Texture Name="gMsgChar77LatinSmallLetterWTex" OutName="msg_char_77_latin_small_letter_w" Format="i4" Width="16" Height="16" Offset="0x2B80"/>
<Texture Name="gMsgChar78LatinSmallLetterXTex" OutName="msg_char_78_latin_small_letter_x" Format="i4" Width="16" Height="16" Offset="0x2C00"/>
<Texture Name="gMsgChar79LatinSmallLetterYTex" OutName="msg_char_79_latin_small_letter_y" Format="i4" Width="16" Height="16" Offset="0x2C80"/>
<Texture Name="gMsgChar7ALatinSmallLetterZTex" OutName="msg_char_7a_latin_small_letter_z" Format="i4" Width="16" Height="16" Offset="0x2D00"/>
<Texture Name="gMsgChar7BLeftCurlyBracketTex" OutName="msg_char_7b_left_curly_bracket" Format="i4" Width="16" Height="16" Offset="0x2D80"/>
<Texture Name="gMsgChar7CVerticalLineTex" OutName="msg_char_7c_vertical_line" Format="i4" Width="16" Height="16" Offset="0x2E00"/>
<Texture Name="gMsgChar7DRightCurlyBracketTex" OutName="msg_char_7d_right_curly_bracket" Format="i4" Width="16" Height="16" Offset="0x2E80"/>
<Texture Name="gMsgChar7ETildeTex" OutName="msg_char_7e_tilde" Format="i4" Width="16" Height="16" Offset="0x2F00"/>
<Texture Name="gMsgChar7FBlankTex" OutName="msg_char_7f_blank" Format="i4" Width="16" Height="16" Offset="0x2F80"/>
<Texture Name="gMsgChar80LatinCapitalLetterAWithGraveTex" OutName="msg_char_80_latin_capital_letter_a_with_grave" Format="i4" Width="16" Height="16" Offset="0x3000"/>
<Texture Name="gMsgChar81LatinCapitalLetterIWithCircumflexTex" OutName="msg_char_81_latin_capital_letter_i_with_circumflex" Format="i4" Width="16" Height="16" Offset="0x3080"/>
<Texture Name="gMsgChar82LatinCapitalLetterAWithCircumflexTex" OutName="msg_char_82_latin_capital_letter_a_with_circumflex" Format="i4" Width="16" Height="16" Offset="0x3100"/>
<Texture Name="gMsgChar83LatinCapitalLetterAWithDiaeresisTex" OutName="msg_char_83_latin_capital_letter_a_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3180"/>
<Texture Name="gMsgChar84LatinCapitalLetterCWithCedillaTex" OutName="msg_char_84_latin_capital_letter_c_with_cedilla" Format="i4" Width="16" Height="16" Offset="0x3200"/>
<Texture Name="gMsgChar85LatinCapitalLetterEWithGraveTex" OutName="msg_char_85_latin_capital_letter_e_with_grave" Format="i4" Width="16" Height="16" Offset="0x3280"/>
<Texture Name="gMsgChar86LatinCapitalLetterEWithAcuteTex" OutName="msg_char_86_latin_capital_letter_e_with_acute" Format="i4" Width="16" Height="16" Offset="0x3300"/>
<Texture Name="gMsgChar87LatinCapitalLetterEWithCircumflexTex" OutName="msg_char_87_latin_capital_letter_e_with_circumflex" Format="i4" Width="16" Height="16" Offset="0x3380"/>
<Texture Name="gMsgChar88LatinCapitalLetterEWithDiaeresisTex" OutName="msg_char_88_latin_capital_letter_e_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3400"/>
<Texture Name="gMsgChar89LatinCapitalLetterIWithDiaeresisTex" OutName="msg_char_89_latin_capital_letter_i_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3480"/>
<Texture Name="gMsgChar8ALatinCapitalLetterOWithCircumflexTex" OutName="msg_char_8a_latin_capital_letter_o_with_circumflex" Format="i4" Width="16" Height="16" Offset="0x3500"/>
<Texture Name="gMsgChar8BLatinCapitalLetterOWithDiaeresisTex" OutName="msg_char_8b_latin_capital_letter_o_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3580"/>
<Texture Name="gMsgChar8CLatinCapitalLetterUWithGraveTex" OutName="msg_char_8c_latin_capital_letter_u_with_grave" Format="i4" Width="16" Height="16" Offset="0x3600"/>
<Texture Name="gMsgChar8DLatinCapitalLetterUWithCircumflexTex" OutName="msg_char_8d_latin_capital_letter_u_with_circumflex" Format="i4" Width="16" Height="16" Offset="0x3680"/>
<Texture Name="gMsgChar8ELatinCapitalLetterUWithDiaeresisTex" OutName="msg_char_8e_latin_capital_letter_u_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3700"/>
<Texture Name="gMsgChar8FLatinSmallLetterSharpSTex" OutName="msg_char_8f_latin_small_letter_sharp_s" Format="i4" Width="16" Height="16" Offset="0x3780"/>
<Texture Name="gMsgChar90LatinSmallLetterAWithGraveTex" OutName="msg_char_90_latin_small_letter_a_with_grave" Format="i4" Width="16" Height="16" Offset="0x3800"/>
<Texture Name="gMsgChar91LatinSmallLetterAWithAcuteTex" OutName="msg_char_91_latin_small_letter_a_with_acute" Format="i4" Width="16" Height="16" Offset="0x3880"/>
<Texture Name="gMsgChar92LatinSmallLetterAWithCircumflexTex" OutName="msg_char_92_latin_small_letter_a_with_circumflex" Format="i4" Width="16" Height="16" Offset="0x3900"/>
<Texture Name="gMsgChar93LatinSmallLetterAWithDiaeresisTex" OutName="msg_char_93_latin_small_letter_a_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3980"/>
<Texture Name="gMsgChar94LatinSmallLetterCWithCedillaTex" OutName="msg_char_94_latin_small_letter_c_with_cedilla" Format="i4" Width="16" Height="16" Offset="0x3A00"/>
<Texture Name="gMsgChar95LatinSmallLetterEWithGraveTex" OutName="msg_char_95_latin_small_letter_e_with_grave" Format="i4" Width="16" Height="16" Offset="0x3A80"/>
<Texture Name="gMsgChar96LatinSmallLetterEWithAcuteTex" OutName="msg_char_96_latin_small_letter_e_with_acute" Format="i4" Width="16" Height="16" Offset="0x3B00"/>
<Texture Name="gMsgChar97LatinSmallLetterEWithCircumflexTex" OutName="msg_char_97_latin_small_letter_e_with_circumflex" Format="i4" Width="16" Height="16" Offset="0x3B80"/>
<Texture Name="gMsgChar98LatinSmallLetterEWithDiaeresisTex" OutName="msg_char_98_latin_small_letter_e_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3C00"/>
<Texture Name="gMsgChar99LatinSmallLetterIWithDiaeresisTex" OutName="msg_char_99_latin_small_letter_i_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3C80"/>
<Texture Name="gMsgChar9ALatinSmallLetterOWithCircumflexTex" OutName="msg_char_9a_latin_small_letter_o_with_circumflex" Format="i4" Width="16" Height="16" Offset="0x3D00"/>
<Texture Name="gMsgChar9BLatinSmallLetterOWithDiaeresisTex" OutName="msg_char_9b_latin_small_letter_o_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3D80"/>
<Texture Name="gMsgChar9CLatinSmallLetterUWithGraveTex" OutName="msg_char_9c_latin_small_letter_u_with_grave" Format="i4" Width="16" Height="16" Offset="0x3E00"/>
<Texture Name="gMsgChar9DLatinSmallLetterUWithCircumflexTex" OutName="msg_char_9d_latin_small_letter_u_with_circumflex" Format="i4" Width="16" Height="16" Offset="0x3E80"/>
<Texture Name="gMsgChar9ELatinSmallLetterUWithDiaeresisTex" OutName="msg_char_9e_latin_small_letter_u_with_diaeresis" Format="i4" Width="16" Height="16" Offset="0x3F00"/>
<Texture Name="gMsgChar9FButtonATex" OutName="msg_char_9f_button_a" Format="i4" Width="16" Height="16" Offset="0x3F80"/>
<Texture Name="gMsgCharA0ButtonBTex" OutName="msg_char_a0_button_b" Format="i4" Width="16" Height="16" Offset="0x4000"/>
<Texture Name="gMsgCharA1ButtonCTex" OutName="msg_char_a1_button_c" Format="i4" Width="16" Height="16" Offset="0x4080"/>
<Texture Name="gMsgCharA2ButtonLTex" OutName="msg_char_a2_button_l" Format="i4" Width="16" Height="16" Offset="0x4100"/>
<Texture Name="gMsgCharA3ButtonRTex" OutName="msg_char_a3_button_r" Format="i4" Width="16" Height="16" Offset="0x4180"/>
<Texture Name="gMsgCharA4ButtonZTex" OutName="msg_char_a4_button_z" Format="i4" Width="16" Height="16" Offset="0x4200"/>
<Texture Name="gMsgCharA5ButtonCUpTex" OutName="msg_char_a5_button_c_up" Format="i4" Width="16" Height="16" Offset="0x4280"/>
<Texture Name="gMsgCharA6ButtonCDownTex" OutName="msg_char_a6_button_c_down" Format="i4" Width="16" Height="16" Offset="0x4300"/>
<Texture Name="gMsgCharA7ButtonCLeftTex" OutName="msg_char_a7_button_c_left" Format="i4" Width="16" Height="16" Offset="0x4380"/>
<Texture Name="gMsgCharA8ButtonCRightTex" OutName="msg_char_a8_button_c_right" Format="i4" Width="16" Height="16" Offset="0x4400"/>
<Texture Name="gMsgCharA9ZTargetSignTex" OutName="msg_char_a9_z_target_sign" Format="i4" Width="16" Height="16" Offset="0x4480"/>
<Texture Name="gMsgCharAAControlStickTex" OutName="msg_char_aa_control_stick" Format="i4" Width="16" Height="16" Offset="0x4500"/>
<Texture Name="gMsgCharABControlPadTex" OutName="msg_char_ab_control_pad" Format="i4" Width="16" Height="16" Offset="0x4580"/>
</File>
</Root>

View file

@ -71,6 +71,10 @@ variables:
sGerMessageEntryTable: 0x8014F548
sFraMessageEntryTable: 0x80151658
sStaffMessageEntryTable: 0x80153768
gSoundFontTable: 0x801550D0
gSequenceFontTable: 0x80155340
gSequenceTable: 0x80155500
gSampleBankTable: 0x80155BF0
sShadowTex: 0x80A8E610
assets:
- name: code/fbdemo_circle
@ -534,7 +538,7 @@ assets:
- name: objects/object_ma2
xml_path: assets/xml/objects/object_ma2.xml
- name: objects/object_mag
xml_path: assets/xml/objects/object_mag_mq.xml
xml_path: assets/xml/objects/object_mag_v3_mq.xml
- name: objects/object_mamenoki
xml_path: assets/xml/objects/object_mamenoki.xml
- name: objects/object_mastergolon
@ -952,9 +956,9 @@ assets:
start_offset: 0x780
end_offset: 0x4128
- name: overlays/ovl_file_choose
xml_path: assets/xml/overlays/ovl_file_choose.xml
xml_path: assets/xml/overlays/ovl_file_choose_pal.xml
start_offset: 0xDE70
end_offset: 0xE6B0
end_offset: 0xE740
- name: overlays/ovl_Magic_Dark
xml_path: assets/xml/overlays/ovl_Magic_Dark.xml
start_offset: 0xD10
@ -1246,7 +1250,7 @@ assets:
- name: textures/message_texture_static
xml_path: assets/xml/textures/message_texture_static.xml
- name: textures/nes_font_static
xml_path: assets/xml/textures/nes_font_static.xml
xml_path: assets/xml/textures/nes_font_static_v2.xml
- name: textures/nintendo_rogo_static
xml_path: assets/xml/textures/nintendo_rogo_static.xml
- name: textures/parameter_static

View file

@ -63,6 +63,10 @@ variables:
sGerMessageEntryTable: 0x8010BA18
sFraMessageEntryTable: 0x8010DB28
sStaffMessageEntryTable: 0x8010FC38
gSoundFontTable: 0x80110470
gSequenceFontTable: 0x801106E0
gSequenceTable: 0x801108A0
gSampleBankTable: 0x80110F90
sShadowTex: 0x80A72FA0
assets:
- name: code/fbdemo_circle
@ -526,7 +530,7 @@ assets:
- name: objects/object_ma2
xml_path: assets/xml/objects/object_ma2.xml
- name: objects/object_mag
xml_path: assets/xml/objects/object_mag_mq.xml
xml_path: assets/xml/objects/object_mag_v3_mq.xml
- name: objects/object_mamenoki
xml_path: assets/xml/objects/object_mamenoki.xml
- name: objects/object_mastergolon
@ -936,9 +940,9 @@ assets:
start_offset: 0x6E0
end_offset: 0x4088
- name: overlays/ovl_file_choose
xml_path: assets/xml/overlays/ovl_file_choose.xml
xml_path: assets/xml/overlays/ovl_file_choose_pal.xml
start_offset: 0xD740
end_offset: 0xDF80
end_offset: 0xE010
- name: overlays/ovl_Magic_Dark
xml_path: assets/xml/overlays/ovl_Magic_Dark.xml
start_offset: 0xC90
@ -1212,7 +1216,7 @@ assets:
- name: textures/message_texture_static
xml_path: assets/xml/textures/message_texture_static.xml
- name: textures/nes_font_static
xml_path: assets/xml/textures/nes_font_static.xml
xml_path: assets/xml/textures/nes_font_static_v2.xml
- name: textures/nintendo_rogo_static
xml_path: assets/xml/textures/nintendo_rogo_static.xml
- name: textures/parameter_static

View file

@ -63,6 +63,10 @@ variables:
sGerMessageEntryTable: 0x8010BA38
sFraMessageEntryTable: 0x8010DB48
sStaffMessageEntryTable: 0x8010FC58
gSoundFontTable: 0x80110490
gSequenceFontTable: 0x80110700
gSequenceTable: 0x801108C0
gSampleBankTable: 0x80110FB0
sShadowTex: 0x80A73020
assets:
- name: code/fbdemo_circle
@ -526,7 +530,7 @@ assets:
- name: objects/object_ma2
xml_path: assets/xml/objects/object_ma2.xml
- name: objects/object_mag
xml_path: assets/xml/objects/object_mag.xml
xml_path: assets/xml/objects/object_mag_v3.xml
- name: objects/object_mamenoki
xml_path: assets/xml/objects/object_mamenoki.xml
- name: objects/object_mastergolon
@ -936,9 +940,9 @@ assets:
start_offset: 0x6E0
end_offset: 0x4088
- name: overlays/ovl_file_choose
xml_path: assets/xml/overlays/ovl_file_choose.xml
xml_path: assets/xml/overlays/ovl_file_choose_pal.xml
start_offset: 0xD740
end_offset: 0xDF80
end_offset: 0xE010
- name: overlays/ovl_Magic_Dark
xml_path: assets/xml/overlays/ovl_Magic_Dark.xml
start_offset: 0xC90
@ -1212,7 +1216,7 @@ assets:
- name: textures/message_texture_static
xml_path: assets/xml/textures/message_texture_static.xml
- name: textures/nes_font_static
xml_path: assets/xml/textures/nes_font_static.xml
xml_path: assets/xml/textures/nes_font_static_v2.xml
- name: textures/nintendo_rogo_static
xml_path: assets/xml/textures/nintendo_rogo_static.xml
- name: textures/parameter_static

View file

@ -0,0 +1 @@
0c13e0449a28ea5b925cdb8af8d29768 build/gc-jp-ce/oot-gc-jp-ce-compressed.z64

View file

@ -0,0 +1 @@
fe2f22c16e03762513b5af5449d453aa build/gc-jp-ce/oot-gc-jp-ce.z64

1228
baseroms/gc-jp-ce/config.yml Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
69895c5c78442260f6eafb2506dc482a build/gc-jp-mq/oot-gc-jp-mq-compressed.z64

View file

@ -0,0 +1 @@
f70cf137eb8f783cb5d79756190728ce build/gc-jp-mq/oot-gc-jp-mq.z64

1228
baseroms/gc-jp-mq/config.yml Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
33fb7852c180b18ea0b9620b630f413f build/gc-jp/oot-gc-jp-compressed.z64

View file

@ -0,0 +1 @@
c72746a38cee7b25e6bbecde8db7e2d1 build/gc-jp/oot-gc-jp.z64

1228
baseroms/gc-jp/config.yml Normal file

File diff suppressed because it is too large Load diff

1510
baseroms/gc-jp/segments.csv Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
da35577fe54579f6a266931cc75f512d build/gc-us-mq/oot-gc-us-mq-compressed.z64

View file

@ -0,0 +1 @@
3f0d68ac5b8a9dc3898655025db474dd build/gc-us-mq/oot-gc-us-mq.z64

1228
baseroms/gc-us-mq/config.yml Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -62,6 +62,10 @@ variables:
sJpnMessageEntryTable: 0x80109E8C
sNesMessageEntryTable: 0x8010DFCC
sStaffMessageEntryTable: 0x801121EC
gSoundFontTable: 0x80112C80
gSequenceFontTable: 0x80112EF0
gSequenceTable: 0x801130B0
gSampleBankTable: 0x801137A0
sShadowTex: 0x80A74130
assets:
- name: code/fbdemo_circle
@ -525,7 +529,7 @@ assets:
- name: objects/object_ma2
xml_path: assets/xml/objects/object_ma2.xml
- name: objects/object_mag
xml_path: assets/xml/objects/object_mag.xml
xml_path: assets/xml/objects/object_mag_v3.xml
- name: objects/object_mamenoki
xml_path: assets/xml/objects/object_mamenoki.xml
- name: objects/object_mastergolon
@ -936,8 +940,8 @@ assets:
end_offset: 0x4088
- name: overlays/ovl_file_choose
xml_path: assets/xml/overlays/ovl_file_choose.xml
start_offset: 0xD740
end_offset: 0xDF80
start_offset: 0xEC40
end_offset: 0xF320
- name: overlays/ovl_Magic_Dark
xml_path: assets/xml/overlays/ovl_Magic_Dark.xml
start_offset: 0xC90
@ -1211,7 +1215,7 @@ assets:
- name: textures/message_texture_static
xml_path: assets/xml/textures/message_texture_static.xml
- name: textures/nes_font_static
xml_path: assets/xml/textures/nes_font_static.xml
xml_path: assets/xml/textures/nes_font_static_v2.xml
- name: textures/nintendo_rogo_static
xml_path: assets/xml/textures/nintendo_rogo_static.xml
- name: textures/parameter_static

View file

@ -0,0 +1 @@
2258052847bdd056c8406a9ef6427f13 build/ntsc-1.2/oot-ntsc-1.2-compressed.z64

View file

@ -0,0 +1 @@
48b3e547359f21bb7e123fb362c1dd4e build/ntsc-1.2/oot-ntsc-1.2.z64

1228
baseroms/ntsc-1.2/config.yml Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

113
docs/c_cpp_properties.json Normal file
View file

@ -0,0 +1,113 @@
{
"configurations": [
{
"name": "oot-gc-us",
"compilerArgs": [
"-m32"
],
"includePath": [
"include",
"include/libc",
"src",
"build/gc-us",
".",
"extracted/gc-us"
],
"defines": [
"_LANGUAGE_C",
"OOT_VERSION=OOT_GC_US",
"OOT_REGION=REGION_US",
"OOT_NTSC=1",
"OOT_MQ=0",
"OOT_DEBUG=0",
"NDEBUG",
"F3DEX_GBI_2",
"F3DEX_GBI_PL",
"GBI_DOWHILE"
],
"cStandard": "gnu89"
},
{
"name": "oot-gc-eu",
"compilerArgs": [
"-m32"
],
"includePath": [
"include",
"include/libc",
"src",
"build/gc-eu",
".",
"extracted/gc-eu"
],
"defines": [
"_LANGUAGE_C",
"OOT_VERSION=OOT_GC_EU",
"OOT_REGION=REGION_EU",
"OOT_PAL=1",
"OOT_MQ=0",
"OOT_DEBUG=0",
"NDEBUG",
"F3DEX_GBI_2",
"F3DEX_GBI_PL",
"GBI_DOWHILE"
],
"cStandard": "gnu89"
},
{
"name": "oot-gc-eu-mq",
"compilerArgs": [
"-m32"
],
"includePath": [
"include",
"include/libc",
"src",
"build/gc-eu-mq",
".",
"extracted/gc-eu-mq"
],
"defines": [
"_LANGUAGE_C",
"OOT_VERSION=OOT_GC_EU_MQ",
"OOT_REGION=REGION_EU",
"OOT_PAL=1",
"OOT_MQ=1",
"OOT_DEBUG=0",
"NDEBUG",
"F3DEX_GBI_2",
"F3DEX_GBI_PL",
"GBI_DOWHILE"
],
"cStandard": "gnu89"
},
{
"name": "oot-gc-eu-mq-dbg",
"compilerArgs": [
"-m32"
],
"includePath": [
"include",
"include/libc",
"src",
"build/gc-eu-mq-dbg",
".",
"extracted/gc-eu-mq-dbg"
],
"defines": [
"_LANGUAGE_C",
"OOT_VERSION=OOT_GC_EU_MQ_DBG",
"OOT_REGION=REGION_EU",
"OOT_PAL=1",
"OOT_MQ=1",
"OOT_DEBUG=1",
"F3DEX_GBI_2",
"F3DEX_GBI_PL",
"GBI_DOWHILE",
"GBI_DEBUG"
],
"cStandard": "gnu89"
}
],
"version": 4
}

View file

@ -0,0 +1,10 @@
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).

View file

@ -1,18 +1,17 @@
# Decompiling retail versions
The next decompilation target for OOT is the PAL GameCube Master Quest ROM
(`gc-eu-mq`), because it is the retail version that is most similar to the Debug
ROM. Unfortunately there are still a lot of differences, many of which are
register or stack allocation differences because retail ROMs were built with
different compiler flags. However, once this version is done, future
retail versions should be much easier, as the changes between retail versions are
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/gc-eu-mq` for diff tools.
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/gc-eu-mq` say how to split the source files and where 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.
@ -21,55 +20,44 @@ still show diffs with data symbols. We might improve this later, but these data
diffs are fine to ignore for now.
For register and stack allocation differences, often the code can be tweaked so
that it matches both the retail ROM while continuing to match the Debug ROM (for
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 use the same compiler flags as retail
OOT, checking MM decomp for similar code can help.
an `if` block). Since retail MM versions currently target N64, checking MM decomp for similar code can help.
We can disable code that was removed in retail builds by adding
`#if OOT_DEBUG ... #endif` or `if (OOT_DEBUG) { ... }` around these parts of the
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 PAL GameCube Master Quest ROM (non-debug) to
`baseroms/gc-eu-mq/baserom.z64`
1. Extract assets and ROM files **from the Debug ROM** by running
```sh
make setup -jN
```
if necessary, where `N` is the number of cores on your machine.
1. 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=gc-eu-mq
make -jN VERSION=gc-eu-mq
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/gc-eu-mq` and produce `build/gc-eu-mq/oot-gc-eu-mq.z64`.
`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=gc-eu-mq
make clean VERSION=ntsc-1.2
```
1. Disassemble the target ROM by running
```sh
make disasm -jN VERSION=gc-eu-mq
make disasm VERSION=ntsc-1.2
```
where `N` is the number of cores on your machine. The outputs will be written to
`expected/build/gc-eu-mq`.
The outputs will be written to `expected/build/ntsc-1.2`.
Note that if you need to copy a matching build for the Debug ROM, you can use
Note that if you need to copy a matching build for another version, you can use e.g.
```sh
mkdir -p expected/build
@ -90,37 +78,32 @@ source .venv/bin/activate
### retail_progress.py
Running `./retail_progress.py path/to/file.c` will attempt to figure out which functions
in a file still need to match for `gc-eu-mq`. To get an overview of diffs for
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 `gc-eu-mq`, run e.g.
To diff assembly for a single function in `ntsc-1.2`, run e.g.
```sh
./diff.py -mwo3 -v gc-eu-mq Math3D_CylTriVsIntersect
./diff.py -mwo3 -v ntsc-1.2 Math3D_CylTriVsIntersect
```
The `-v` flag tells `diff.py` to compare between `build/gc-eu-mq` and
`expected/build/gc-eu-mq`, and to use `make VERSION=gc-eu-mq` when rebuilding.
You may also want to diff the Debug ROM in another terminal with
```sh
./diff.py -mwo3 Math3D_CylTriVsIntersect
```
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/gc-eu-mq/functions`, so to get a [decomp.me](https://decomp.me/) scratch you can run
`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/gc-eu-mq/functions/src/code/sys_math3d/Math3D_CylTriVsIntersect.s \
VERSION=gc-eu-mq --decompme
expected/build/ntsc-1.2/functions/src/code/sys_math3d/Math3D_CylTriVsIntersect.s \
VERSION=ntsc-1.2 --decompme
```

View file

@ -1,926 +0,0 @@
# Beginning decompilation: the Init function and the Actor struct
Up: [Contents](contents.md)
Open the C file and the H file with your actor's name from the appropriate directory in `src/overlays/actors/`. These will be the main files we work with. We will be using EnJj (Lord Jabu Jabu) as our example: despite being a fairly small actor, it has a number of interesting features.
Each actor has associated to it a data file and one assembly file per function. During the process, we will transfer the contents of all or most of these into the main C file. VSCode's search feature usually makes it quite easy to find the appropriate files without troubling the directory tree.
## Anatomy of the C file
The actor file starts off looking like:
![Fresh actor file annotated](images/fresh_actor_file_annotated.png)
It is currently divided into six sections as follows:
1. Preliminary description of the actor. This is not present for all actors, but gives a short description based on what we know about the actor already. It may be inaccurate, so feel free to correct it after you understand the actor better.
2. Specific `include`s and `define`s for the actor. You may need to add more header files, but otherwise this section is unlikely to change.
3. These are prototypes for the "main four" functions that almost every actor has. You add more functions here if they need to be declared above their first use.
4. A set of `extern`s. These refer to data that comes from other files, usually in the actor's corresponding object file. They point to addresses in the ROM where assets are stored (usually collision data, animations or display lists). Once the corresponding object files have been decompiled, these will simply be replaced by including the object file (see [Object Decompilation](object_decomp.md) for how this process works). For now, you can put them between blocks 5 and 6 to conform with how the rest of our files are structured. These symbols have been automatically extracted from the MIPS code. There may turn out to be some that were not caught by the script, in which case they need to be placed in the file called `undefined_syms.txt` in the root directory of the project. Ask in Discord for how to do this: it is simple, but rare enough to not be worth covering here.
5. Commented-out section containing the `InitVars`. This can be ignored until we import the data: it is a section of the actor data that has been imported automatically since, unlike most of the data, it has the same format in every actor. (This image is out of date: actors now also have their ColliderInits in here)
6. List of functions. Each `#pragma` is letting the compiler use the corresponding assembly file while we do not have decompiled C code for that function. The majority of the decompilation work is converting these functions into C that it looks like a human wrote.
## Header file
The header file looks like this at the moment:
![Fresh actor header](images/fresh_actor_header.png)
The struct currently contains a variable that is the `Actor` struct, which all actors use one way or another, plus other items. Currently we don't know what those items are, so we have an array of chars as padding instead, just so the struct is the right size. As we understand the actor better, we will be able to gradually replace this padding with the actual variables that the actor uses.
The header file is also used to declare structs and other information about the actor that is needed globally (e.g. by other actors).
## Order of decompilation
The general rule for order of decompilation is
- Start with `Init`, because it usually contains the most information about the structure of the actor.
- Next, decompile any other functions from the actor you have found in `Init`. You generally start with the action functions, because they return nothing and all take the same arguments,
```C
void func_80whatever(EnJj* this, PlayState* play);
```
- Decompile each action function in turn until you run out. Along the way, do any other functions in the actor for which you have discovered the argument types. (You are probably better doing depth-first on action functions than breadth-first: it's normally easier to follow along one branch of the actions than )
- After you've run out, do `Update`. This usually provides the rest of the function tree, apart from posibly some Draw functions.
- Finally, do the draw functions.
The above is a rough ordering for the beginner. As you become more experienced, you can deviate from this scheme, but the general principle remains that you should work on functions that you already know something about.
## Data
![Fresh actor data](images/fresh_actor_data.png)
Associated to each actor is a `.data` file, containing data that the actor uses. This ranges from spawn positions, to display lists, to even some cutscene data. Since the structure of the data is very inconsistent between actors, automatic importing has been very limited, so the vast majority must be done manually.
There are two ways of transfering the data into an actor: we can either
- import it all naively as words (`s32`s), which will still allow it to compile, and sort out the actual types later, or
- we can extern each piece of data as we come across it, and come back to it later when we have a better idea of what it is.
We will concentrate on the second here; the other is covered in [the document about data](data.md). Thankfully this means we essentially don't have to do anything to the data yet. Nevertheless, it is often quite helpful to copy over at least some of the data and leave it commented out for later replacement. *Data must go in the same order as in the data file, and data is "all or nothing": you cannot only import some of it*.
![Data copied in and commented out](images/data_inserted_commented_out.png)
**WARNING** The way in which the data was extracted from the ROM means that there are sometimes "fake symbols" in the data, which have to be removed to avoid confusing the compiler. Thankfully it will turn out that this is not the case here, although there will be other data issues.
(Sometimes it is useful to import the data in the middle of doing functions: you just have to choose an appropriate moment.)
Some actors also have a `.bss` file. This is just data that is initialised to 0, and can be imported immediately once you know what type it is, by declaring it without giving it a value.
## Init
The Init function sets up the various components of the actor when it is first loaded. It is hence usually very useful for finding out what is in the actor struct, and so we usually start with it. (Some people like starting with Destroy, which is usually shorter and simpler, but gives some basic information about the actor, but Init is probably best for beginners.)
### mips2c
The first stage of decompilation is done by a program called mips2c or mips_to_c, which constructs a C interpretation of the assembly code based on reading it very literally. This means that considerable cleanup will be required to turn it into something that firstly compiles at all, and secondly looks like a human wrote it, let alone a Zelda developer from the late '90s.
The web version of mips2c can be found [here](https://simonsoftware.se/other/mips_to_c.py). There is also a downloadable version, but let's just use the online one for now.
Since the actor depends on the rest of the codebase, we can't expect to get much intelligible out of mips2c without giving it some context. We make this using a Python script in the `tools` directory called `m2ctx.py`, so run
```
$ ./tools/m2ctx.py <path_to_c_file>
```
from the main directory of the repository. In this case, the C file is `src/overlays/actors/ovl_En_Jj/z_en_jj.c`. This generates a file called `ctx.c` in the main directory of the repository. Open this file in a text editor (Notepad will do) and copy the whole contents into the "Existing C source, preprocessed" box.
![Copying the context](images/ctx.png)
Now, open the file containing the assembly for `EnJj_Init`.
![Copying the Init asm](images/init_asm.png)
Copy the entire contents of this file into the upper box, labelled "MIPS assembly". Now, for Init (and also the other "main 4" functions `Destroy`, `Update` and `Draw`), the function's first argument is `Actor* thisx`. But we would like mips2c to use the fields in the actual actor struct; we can make it do this by deliberately changing the prototype of the `EnJj_Init` in the pasted context to have first argument `EnJj* this` instead.
![Changing init prototype](images/changing_init_prototype.png)
Now press "Decompile". This should produce C code:
```C
void EnJj_Init(EnJj *this, PlayState *play) {
CollisionHeader *sp4C;
DynaCollisionContext *sp44;
DynaCollisionContext *temp_a1;
DynaCollisionContext *temp_a1_2;
DynaCollisionContext *temp_a1_3;
char *temp_v0_2;
s16 temp_v0;
sp4C = NULL;
Actor_ProcessInitChain((Actor *) this, &D_80A88CE0);
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
temp_v0 = this->actor.params;
temp_a1 = this + 0x164;
[...]
```
Typically for all buth the simplest functions, there is a lot that needs fixing before we are anywhere near seeing how close we are to the original code. You will notice that mips2c creates a lot of temporary variables. Usually most of these will turn out to not be real, and we need to remove the right ones to get the code to match.
First, change the first argument back to `Actor* thisx` so that the function matches its prototype above. To allow the function to find the variables, we need another correction. Half of this has already been done at the top of the function, where we have
```C
#define THIS ((EnJj*)thisx)
```
To do the other half, write the following at the beginning of the function, before any declarations:
```C
EnJj* this = THIS;
```
Now everything points to the right place, even though the argument of the function seems inconsistent with the contents.
(This step is only necessary for the "main 4" functions, and sometimes functions that are used by these: it relates to how such functions are used outside the actor.)
While we are carrying out initial changes, you can also find-and-replace any instances of `(Actor *) this` by `&this->actor`. The function now looks like this:
<details>
<summary>
Large code block, click to show.
</summary>
```C
void EnJj_Init(Actor *thisx, PlayState *play) {
EnJj* this = THIS;
CollisionHeader *sp4C;
DynaCollisionContext *sp44;
DynaCollisionContext *temp_a1;
DynaCollisionContext *temp_a1_2;
DynaCollisionContext *temp_a1_3;
char *temp_v0_2;
s16 temp_v0;
sp4C = NULL;
Actor_ProcessInitChain(&this->actor, &D_80A88CE0);
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
temp_v0 = this->actor.params;
temp_a1 = this + 0x164;
if (temp_v0 == -1) {
sp44 = temp_a1;
SkelAnime_InitFlex(play, (SkelAnime *) temp_a1, (FlexSkeletonHeader *) &D_0600B9A8, (AnimationHeader *) &D_06001F4C, this + 0x1A8, this + 0x22C, 0x16);
Animation_PlayLoop((SkelAnime *) sp44, (AnimationHeader *) &D_06001F4C);
this->unk30A = (u16)0;
this->unk30E = (u8)0;
this->unk30F = (u8)0;
this->unk310 = (u8)0;
this->unk311 = (u8)0;
if ((*(&gSaveContext + 0xEDA) & 0x400) != 0) {
func_80A87800(this, &func_80A87BEC);
} else {
func_80A87800(this, &func_80A87C30);
}
this->unk300 = Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, (u16)0x5A, this->actor.world.pos.x - 10.0f, this->actor.world.pos.y, this->actor.world.pos.z, 0, (?32) this->actor.world.rot.y, 0, 0);
DynaPolyActor_Init((DynaPolyActor *) this, 0);
CollisionHeader_GetVirtual((void *) &D_06000A1C, &sp4C);
this->unk_14C = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->actor, sp4C);
temp_a1_3 = this + 0x2B0;
sp44 = temp_a1_3;
Collider_InitCylinder(play, (ColliderCylinder *) temp_a1_3);
Collider_SetCylinder(play, (ColliderCylinder *) temp_a1_3, &this->actor, &D_80A88CB4);
this->actor.colChkInfo.mass = 0xFF;
return;
}
if (temp_v0 == 0) {
DynaPolyActor_Init((DynaPolyActor *) this, 0);
CollisionHeader_GetVirtual((void *) &D_06001830, &sp4C);
temp_a1_2 = &play->colCtx.dyna;
sp44 = temp_a1_2;
temp_v0_2 = DynaPoly_SetBgActor(play, temp_a1_2, &this->actor, sp4C);
this->unk_14C = temp_v0_2;
func_8003ECA8(play, temp_a1_2, (s32) temp_v0_2);
this->actor.update = &func_80A87F44;
this->actor.draw = NULL;
Actor_SetScale(&this->actor, 0.087f);
return;
}
if (temp_v0 != 1) {
return;
}
DynaPolyActor_Init((DynaPolyActor *) this, 0);
CollisionHeader_GetVirtual((void *) &D_0600BA8C, &sp4C);
this->unk_14C = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->actor, sp4C);
this->actor.update = &func_80A87F44;
this->actor.draw = NULL;
Actor_SetScale(&this->actor, 0.087f);
}
```
</details>
In the next sections, we shall sort out the various initialisation functions that occur in Init. There are several types, and one of the reasons we are using EnJj as the example is that it has several of the most common ones. A disadvantage of this actor is that it has an unusually complicated Init: we can see that it does three different things depending on the value of its params.
### Init chains
Almost always, one of the first items in `Init` is a function that looks like
```C
Actor_ProcessInitChain(&this->actor, &D_80A88CE0);
```
which initialises common properties of actor using an InitChain, which is usually somewhere near the top of the data, in this case in the variable `D_80A88CE0`. Although we don't need to do this now since we we will extern the data, we might as well work out what it is now. Fortunately, we have a script to do this.
The InitChain script is also in the tools directory, and is called `ichaindis.py`. Simply passing it the ROM address will spit out the entire contents of the InitChain, in this case:
```
$ ./tools/ichaindis.py baseroms/gc-eu-mq-dbg/baserom-decompressed.z64 80A88CE0
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(unk_50, 87, ICHAIN_CONTINUE),
ICHAIN_F32(unk_F4, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(unk_F8, 3300, ICHAIN_CONTINUE),
ICHAIN_F32(unk_FC, 1100, ICHAIN_STOP),
};
```
However, some of these variables have now been given names in the Actor struct. Pass it `--names` to fill these in automatically:
```
$ ./tools/ichaindis.py --names baseroms/gc-eu-mq-dbg/baserom-decompressed.z64 80A88CE0
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 87, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 3300, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1100, ICHAIN_STOP),
};
```
Replace the commented-out .words for the `glabel D_80A88CE0` with this, and comment it out, instead adding
```C
extern InitChainEntry D_80A88CE0[];
```
above it:
```C
extern InitChainEntry D_80A88CE0[];
// static InitChainEntry sInitChain[] = {
// ICHAIN_VEC3F_DIV1000(scale, 87, ICHAIN_CONTINUE),
// ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
// ICHAIN_F32(uncullZoneScale, 3300, ICHAIN_CONTINUE),
// ICHAIN_F32(uncullZoneDownward, 1100, ICHAIN_STOP),
// };
```
(We will come back and actually import it after doing the rest of the actor.)
Since this is an array, we do not need the `&` in the function any more, which leaves us with
```C
Actor_ProcessInitChain(&this->actor, D_80A88CE0);
```
in `EnJj_Init`.
### DynaPoly
Glancing through the rest of `EnJj_Init`, we notice some references to DynaPoly, for example
```C
DynaPolyActor_Init((DynaPolyActor *) this, 0);
CollisionHeader_GetVirtual((void *) &D_06000A1C, &sp4C);
this->unk_14C = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->actor, sp4C);
```
This means that EnJj is not an ordinary actor: it is instead a DynaPoly actor. In-game this is to do with how the actor interacts with Link and the environment (a good rule of thumb is that Link can often stand on DynaPoly actors as if they were ground). For decompilation purposes, it means that the actor struct is wrong: the first element of a DynaPoly actor's struct is not an `Actor` struct, but a `DynaPolyActor`, usually called `dyna`. We should fix this immediately to avoid confusion later. (Some actors have this correctly identified already; we were unlucky with this one.)
Since there's basically nothing in the struct at present, the change is easy to make: replace `Actor actor` with `DynaPolyActor dyna`. Now, `DynaPolyActor` is a different size to `Actor`, so we need to account for that. To find out what size it is, you need to find the definition. In VSCode you can usually Ctrl+Left Click on things to go to where they are defined. Doing so takes us to `z64actor.h`, where most actor-related structs are defined: we find
```C
typedef struct {
/* 0x000 */ Actor actor;
/* 0x14C */ u32 bgId;
/* 0x150 */ f32 unk_150;
/* 0x154 */ f32 unk_154;
/* 0x158 */ s16 unk_158;
/* 0x15A */ u16 unk_15A;
/* 0x15C */ u32 unk_15C;
/* 0x160 */ u8 unk_160;
/* 0x162 */ s16 unk_162;
} DynaPolyActor; // size = 0x164
```
so a `DynaPolyActor` struct is an `Actor` with various other things after it. For now all we care about is the size, i.e. `0x164`. This tells us that the next thing after the `DynaPolyActor` struct in the `EnJj` struct begins at `0x164`, not `0x14C` as it does for `Actor`s.
So rename the variable to `unk_164` and change the comment to say `0x0164` (the comments don't do anything, they just make it easier to keep track of where everything is when it's named).
Next we need to adjust the size of the array so that the struct is still the right size. In this case, we just subtract the address of the padding variable from the total size of the struct:
```0x314 - 0x164 = 1B0```. Hence the struct is now
```C
typedef struct EnJj {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ char unk_164[0x1B0];
} EnJj; // size = 0x0314
```
Now that we know this, it is worth remaking the context file and running mips2c again, since we have changed the struct significantly. Doing so, and replacing `(Actor*) this` with `&this->dyna.actor` this time, we find that the block we quoted above has become
```C
DynaPolyActor_Init((DynaPolyActor *) this, 0);
CollisionHeader_GetVirtual((void *) &D_06000A1C, &sp4C);
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
```
Next, replace `(DynaPolyActor *) this` by `&this->dyna`. There's not a lot more we can do to the DynaPoly stuff right now, so just remove the casts to void and move on.
### Colliders
The next common thing that actors have is colliders. Not every actor has these, but most do, even if they don't just use them for collision system purposes.
The relevant functions in this actor are
```C
temp_a1_3 = this + 0x2B0;
sp44 = temp_a1_3;
Collider_InitCylinder(play, (ColliderCylinder *) temp_a1_3);
Collider_SetCylinder(play, (ColliderCylinder *) temp_a1_3, &this->dyna.actor, &D_80A88CB4);
```
Notice that `sp44` is set, but actually not used anywhere in the actor. This is a good indication that it is fake. We'll get back to that. Similarly, `temp_a1_3` is only used in these functions, so is likely to be fake as well: it's simply trying to get the pointer into the `a1` register.
Since mips2c doesn't know about the collider, it has just told us where it is, namely `this + 0x2B0`. So insert a `ColliderCylinder collider` variable in the actor struct, look up its size, and redo the padding. This should give
```C
typedef struct EnJj {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ char unk_164[0x14C];
/* 0x02B0 */ ColliderCylinder collider;
/* 0x02FC */ char unk_2FC[0x18];
} EnJj; // size = 0x0314
```
Now replace the temps, so we have
```C
Collider_InitCylinder(play, &this->collider);
Collider_SetCylinder(play, &this->collider, &this->dyna.actor, &D_80A88CB4);
```
(You may prefer to just comment out temps initially, to keep track of where they were.)
The last thing we need to deal with is the last variable of `Collider_SetCylinder`, which is again data.
<!--Also again we have a script to translate the raw data. This one is called `colliderinit.py`, and lives in `tools/overlayhelpers`. It takes the VRAM address of the data and the type of collider (for more info on use, pass it `-h`). We find
```
$ ./tools/overlayhelpers/colliderinit.py 80A88CB4 ColliderCylinderInit
ovl_En_Jj: Rom 00E3E3D0:00E3F9E0 VRam 80A87800:80A88E10 Offset 0014B4
static ColliderCylinderInit sCylinderInit =
{
{ COLTYPE_UNK10, 0x00, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000004, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
{ 170, 150, 0, { 0, 0, 0 } },
};
```
As with the InitChain, replace the commented-out data we copied into the C file with this:
```C
extern ColliderCylinderInit D_80A88CB4;
// static ColliderCylinderInit sCylinderInit =
// {
// { COLTYPE_UNK10, 0x00, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
// { 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000004, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
// { 170, 150, 0, { 0, 0, 0 } },
// };
```-->
This is already in the actor file in the correct format, all you need to do is add an extern for it underneath:
```C
/*
[...]
*/
extern ColliderCylinderInit D_80A88CB4;
```
Unlike the InitChain, this is not an array, so keep the `&` in the function.
### SkelAnime
This is the combined system that handles actors' skeletons and their animations. It is the other significant part of most actor structs. We see its initialisation in this part of the code:
```C
temp_a1 = this->unk_164;
...
sp44 = (DynaCollisionContext *) temp_a1;
SkelAnime_InitFlex(play, (SkelAnime *) temp_a1, (FlexSkeletonHeader *) &D_0600B9A8, (AnimationHeader *) &D_06001F4C, this + 0x1A8, this + 0x22C, 0x16);
Animation_PlayLoop((SkelAnime *) sp44, (AnimationHeader *) &D_06001F4C);
```
(Both of the temps are likely to be fake.)
An actor with SkelAnime has three structs in the Actor struct that handle it: one called SkelAnime, and two arrays of `Vec3s`, called `jointTable` and `overrideDrawTable` (for now). Usually, although not always, they are next to one another.
There are two different sorts of SkelAnime, although for decompilation purposes there is not much difference between them. From `SkelAnime_InitFlex` we can read off that
- The `SkelAnime` struct is at `this + 0x164`
- The `jointTable` is at `this + 0x1A8`
- The `overrideDrawTable` is at `this + 0x22C`
- The number of limbs is `0x16 = 22`
- Hence the `jointTable` and `overrideDrawTable` both have `22` elements
Looking in `z64animation.h`, we find that `SkelAnime` has size `0x44`, and looking in `z64math.h`, that `Vec3s` has size `0x6`. Since ` 0x164 + 0x44 = 0x1A8 `, `jointTable` is immediately after the `SkelAnime`, and since `0x1A8 + 0x6 * 0x16 = 0x22C`, `overrideDrawTable` is immediately after the `jointTable`. Finally, `0x22C + 0x6 * 0x16 = 2B0`, and we have filled all the space between the `dyna` and `collider`. Therefore the struct now looks like
```C
typedef struct EnJj {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ SkelAnime skelAnime;
/* 0x01A8 */ Vec3s jointTable[22];
/* 0x022C */ Vec3s overrideDrawTable[22];
/* 0x02B0 */ ColliderCylinder collider;
/* 0x02FC */ char unk_2FC[0x18];
} EnJj; // size = 0x0314
```
The last information we get from the SkelAnime functions is the types of two of the externed symbols: `D_0600B9A8` is a `FlexSkeletonHeader`, and `D_06001F4C` is an `AnimationHeader`. So we can change these in the C file:
```C
extern UNK_TYPE D_06000A1C;
extern UNK_TYPE D_06001830;
extern AnimationHeader D_06001F4C;
extern FlexSkeletonHeader D_0600B9A8;
extern UNK_TYPE D_0600BA8C;
```
and removing the temps,
```C
SkelAnime_InitFlex(play, &this->skelAnime, &D_0600B9A8, &D_06001F4C, this->jointTable, this->morphTable, 22);
Animation_PlayLoop(&this->skelAnime, &D_06001F4C);
```
### More struct variables
This function also gives us information about other things in the struct. One obvious thing that sticks out is
```C
this->unk300 = Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, (u16)0x5A, this->dyna.actor.world.pos.x - 10.0f, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, (?32) this->dyna.actor.world.rot.y, 0, 0);
```
Hovering over this function tells us it outputs a pointer to the spawned actor, so `this->unk_300` is an `Actor*`. We may or may not care what this actor actually is, depending on how it is used later on, so let's just add `/* 0x0300 */ Actor* childActor` to the struct for now.
We can look up what the actor with ID 0x5A is in `z64actor.h`: we find it is `ACTOR_EN_JJ`. So some Jabus spawn another Jabu. Filling this in and removing the spurious cast, we have
```C
this->childActor = Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_EN_JJ, this->dyna.actor.world.pos.x - 10.0f, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, this->dyna.actor.world.rot.y, 0, 0);
```
Finally, we have this block:
```C
this->unk30A = (u16)0;
this->unk30E = (u8)0;
this->unk30F = (u8)0;
this->unk310 = (u8)0;
this->unk311 = (u8)0;
```
This is not quite as helpful as you might think: it tells us the size of these variables, but despite mips2c's assertion that they are all unsigned, they may actually be signed: you can't tell from the MIPS unless they are loaded: there is only `sh`, but there are both `lh` and `lhu`, for example. There's not much to choose between them when guessing, but generally signed is a better guess with no other context. For unnamed struct variables, our convention is `unk_30A` etc. Adding them to the struct, we end up with
<details>
<summary>
Large code block, click to show.
</summary>
```C
typedef struct EnJj {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ SkelAnime skelAnime;
/* 0x01A8 */ Vec3s jointTable[22];
/* 0x022C */ Vec3s morphTable[22];
/* 0x02B0 */ ColliderCylinder collider;
/* 0x02FC */ char unk_2FC[0x4];
/* 0x0300 */ Actor* childActor;
/* 0x0304 */ char unk_304[0x6];
/* 0x030A */ s16 unk_30A;
/* 0x030C */ char unk_30C[0x2];
/* 0x030E */ s8 unk_30E;
/* 0x030F */ s8 unk_30F;
/* 0x0310 */ s8 unk_310;
/* 0x0311 */ s8 unk_311;
/* 0x0312 */ char unk_312[0x2];
} EnJj; // size = 0x0314
```
We can remove a few more temps that don't look real, and end up with
```C
void EnJj_Init(Actor *thisx, PlayState *play) {
EnJj* this = THIS;
CollisionHeader *sp4C;
// DynaCollisionContext *sp44;
// DynaCollisionContext *temp_a1_2;
// DynaCollisionContext *temp_a1_3;
// char *temp_a1;
s16 temp_v0;
// u32 temp_v0_2;
sp4C = NULL;
Actor_ProcessInitChain(&this->dyna.actor, D_80A88CE0);
ActorShape_Init(&this->dyna.actor.shape, 0.0f, NULL, 0.0f);
temp_v0 = this->dyna.actor.params;
// temp_a1 = this->unk_164;
if (temp_v0 == -1) {
// sp44 = (DynaCollisionContext *) temp_a1;
SkelAnime_InitFlex(play, &this->skelAnime, &D_0600B9A8, &D_06001F4C, this->jointTable, this->morphTable, 22);
Animation_PlayLoop(&this->skelAnime, &D_06001F4C);
this->unk_30A = 0;
this->unk_30E = 0;
this->unk_30F = 0;
this->unk_310 = 0;
this->unk_311 = 0;
if ((*(&gSaveContext + 0xEDA) & 0x400) != 0) {
func_80A87800(this, &func_80A87BEC);
} else {
func_80A87800(this, &func_80A87C30);
}
this->childActor = Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_EN_JJ, this->dyna.actor.world.pos.x - 10.0f, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, this->dyna.actor.world.rot.y, 0, 0);
DynaPolyActor_Init(&this->dyna, 0);
CollisionHeader_GetVirtual(&D_06000A1C, &sp4C);
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
// temp_a1_3 = this + 0x2B0;
// sp44 = temp_a1_3;
Collider_InitCylinder(play, &this->collider);
Collider_SetCylinder(play, &this->collider, &this->dyna.actor, &D_80A88CB4);
this->dyna.actor.colChkInfo.mass = 0xFF;
return;
}
if (temp_v0 == 0) {
DynaPolyActor_Init(&this->dyna, 0);
CollisionHeader_GetVirtual(&D_06001830, &sp4C);
// temp_a1_2 = &play->colCtx.dyna;
// sp44 = temp_a1_2;
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
func_8003ECA8(play, &play->colCtx.dyna, this->dyna.bgId);
this->dyna.actor.update = &func_80A87F44;
this->dyna.actor.draw = NULL;
Actor_SetScale(&this->dyna.actor, 0.087f);
return;
}
if (temp_v0 != 1) {
return;
}
DynaPolyActor_Init(&this->dyna, 0);
CollisionHeader_GetVirtual(&D_0600BA8C, &sp4C);
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
this->dyna.actor.update = &func_80A87F44;
this->dyna.actor.draw = NULL;
Actor_SetScale(&this->dyna.actor, 0.087f);
}
```
</details>
This will still not compile without errors: we need to know what the functions it calls are.
### Functions called
Function pointers do not need `&`, so remove all those. There are three functions that are called in this actor. Firstly, `this->dyna.actor.update = func_80A87F44;` tells us that `func_80A87F44` is an alternative update function for this actor. We therefore give it a prototype similar to the original Update:
```C
void EnJj_Init(Actor* thisx, PlayState* play);
void EnJj_Destroy(Actor* thisx, PlayState* play);
void EnJj_Update(Actor* thisx, PlayState* play);
void EnJj_Draw(Actor* thisx, PlayState* play);
void func_80A87F44(Actor* thisx, PlayState* play);
```
Unfortunately the others are not so easy to deal with. In order to find out what type the functions called by `func_80A87800`, we have to look at `func_80A87800` itself. But fortunately, this is the entire MIPS for `func_80A87800`:
```MIPS
glabel func_80A87800
/* 00000 80A87800 03E00008 */ jr $ra
/* 00004 80A87804 AC8502FC */ sw $a1, 0x02FC($a0) ## 000002FC
```
This is simple enough to read that we don't even need to appeal to mips2c: it saves its second argument into its first argument `+ 0x2FC`. Many actors use this type of function, which we call `SetupAction`: it simply changes the action function.
*Action functions* are the main other kind of function in most actors: they are usually run by Update every frame, and carry out the main actions that the actor does (hence the name). They all have the same arguments, and so we have a typedef for such things: it is
```C
typedef void (*EnJjActionFunc)(struct EnJj*, PlayState*);
```
Put this between `struct EnJj;` and the actor struct in the header file. This also gives us another bit of the struct, conveniently plugging the gap at `0x2FC`:
```C
/* 0x02FC */ EnJjActionFunc actionFunc;
```
We have actually learnt three useful pieces of information from this, the other two being that the function above Init is simply
```C
void func_80A87800(EnJj* this, EnJjActionFunc actionFunc) {
this->actionFunc = actionFunc;
}
```
and that `func_80A87BEC` and `func_80A87C30`, passed to it in `EnJj_Init`, are action functions. Since they are first used above where they are defined, we prototype them at the top as well,
```C
void EnJj_Init(Actor* thisx, PlayState* play);
void EnJj_Destroy(Actor* thisx, PlayState* play);
void EnJj_Update(Actor* thisx, PlayState* play);
void EnJj_Draw(Actor* thisx, PlayState* play);
void func_80A87F44(Actor* thisx, PlayState* play);
void func_80A87BEC(EnJj* this, PlayState* play);
void func_80A87C30(EnJj* this, PlayState* play);
```
### Other pointer issues
Mips2c is bad at arrays. We see this in the `(*(&gSaveContext + 0xEDA) & 0x400) != 0`, which will actually stop the compiler working. We need to go and look up what this is actually pointing to, and replace it in the code. Following the trail, we find that:
1. `gSaveContext` is of type `SaveContext`
2. The struct `SaveContext` is defined in `z64save.h`
3. The entry in `SaveContext` that contains `0xEDA` is `/* 0x0ED4 */ u16 eventChkInf[14];`
4. Since `0xEDA - 0xED4 = 0x6`, and `u16`s take up 2 bytes each, we conclude that it is `eventChkInf[3]` that is being referenced.
Therefore, the condition should be `(gSaveContext.save.info.eventChkInf[3] & 0x400) != 0`. This is a flag comparison, so we can also leave off the `!= 0`.
With all of this implemented, the function should now compile without errors. The parts of the file that we have changed now look like
<details>
<summary>
Large code block, click to show.
</summary>
```C
void EnJj_Init(Actor* thisx, PlayState* play);
void EnJj_Destroy(Actor* thisx, PlayState* play);
void EnJj_Update(Actor* thisx, PlayState* play);
void EnJj_Draw(Actor* thisx, PlayState* play);
void func_80A87F44(Actor* thisx, PlayState* play);
void func_80A87BEC(EnJj* this, PlayState* play);
void func_80A87C30(EnJj* this, PlayState* play);
#if 0
ActorInit En_Jj_InitVars = {
/**/ ACTOR_EN_JJ,
/**/ ACTORTYPE_ITEMACTION,
/**/ FLAGS,
/**/ OBJECT_JJ,
/**/ sizeof(EnJj),
/**/ EnJj_Init,
/**/ EnJj_Destroy,
/**/ EnJj_Update,
/**/ EnJj_Draw,
};
#endif
extern ColliderCylinderInit D_80A88CB4;
// static ColliderCylinderInit sCylinderInit = {
// {
// COLTYPE_NONE,
// AT_NONE,
// AC_ON | AC_TYPE_PLAYER,
// OC1_ON | OC1_TYPE_ALL,
// OC2_TYPE_1,
// COLSHAPE_CYLINDER,
// },
// {
// ELEMTYPE_UNK0,
// { 0x00000000, 0x00, 0x00 },
// { 0x00000004, 0x00, 0x00 },
// ATELEM_NONE,
// ACELEM_ON,
// OCELEM_ON,
// },
// { 170, 150, 0, { 0, 0, 0 } },
// };
extern InitChainEntry D_80A88CE0[];
// static InitChainEntry sInitChain[] = {
// ICHAIN_VEC3F_DIV1000(scale, 87, ICHAIN_CONTINUE),
// ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
// ICHAIN_F32(uncullZoneScale, 3300, ICHAIN_CONTINUE),
// ICHAIN_F32(uncullZoneDownward, 1100, ICHAIN_STOP),
// };
// glabel D_80A88CF0
// .word 0xC4C6A000, 0x42540000, 0xC22C0000
// glabel D_80A88CFC
// .word 0x06007698, 0x06007A98, 0x06007E98, 0x00000000, 0x00000000
extern UNK_TYPE D_06000A1C;
extern UNK_TYPE D_06001830;
extern AnimationHeader D_06001F4C;
extern FlexSkeletonHeader D_0600B9A8;
extern UNK_TYPE D_0600BA8C;
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Jj/func_80A87800.s")
void func_80A87800(EnJj* this, EnJjActionFunc actionFunc) {
this->actionFunc = actionFunc;
}
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Jj/EnJj_Init.s")
void EnJj_Init(Actor *thisx, PlayState *play) {
EnJj* this = THIS;
CollisionHeader *sp4C;
// DynaCollisionContext *sp44;
// DynaCollisionContext *temp_a1_2;
// DynaCollisionContext *temp_a1_3;
// char *temp_a1;
s16 temp_v0;
// u32 temp_v0_2;
sp4C = NULL;
Actor_ProcessInitChain(&this->dyna.actor, D_80A88CE0);
ActorShape_Init(&this->dyna.actor.shape, 0.0f, NULL, 0.0f);
temp_v0 = this->dyna.actor.params;
// temp_a1 = this->unk_164;
if (temp_v0 == -1) {
// sp44 = (DynaCollisionContext *) temp_a1;
SkelAnime_InitFlex(play, &this->skelAnime, &D_0600B9A8, &D_06001F4C, this->jointTable, this->morphTable, 22);
Animation_PlayLoop(&this->skelAnime, &D_06001F4C);
this->unk_30A = 0;
this->unk_30E = 0;
this->unk_30F = 0;
this->unk_310 = 0;
this->unk_311 = 0;
if ((gSaveContext.save.info.eventChkInf[3] & 0x400) != 0) {
func_80A87800(this, func_80A87BEC);
} else {
func_80A87800(this, func_80A87C30);
}
this->childActor = Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_EN_JJ, this->dyna.actor.world.pos.x - 10.0f, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, this->dyna.actor.world.rot.y, 0, 0);
DynaPolyActor_Init(&this->dyna, 0);
CollisionHeader_GetVirtual(&D_06000A1C, &sp4C);
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
// temp_a1_3 = this + 0x2B0;
// sp44 = temp_a1_3;
Collider_InitCylinder(play, &this->collider);
Collider_SetCylinder(play, &this->collider, &this->dyna.actor, &D_80A88CB4);
this->dyna.actor.colChkInfo.mass = 0xFF;
return;
}
if (temp_v0 == 0) {
DynaPolyActor_Init(&this->dyna, 0);
CollisionHeader_GetVirtual(&D_06001830, &sp4C);
// temp_a1_2 = &play->colCtx.dyna;
// sp44 = temp_a1_2;
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
func_8003ECA8(play, &play->colCtx.dyna, this->dyna.bgId);
this->dyna.actor.update = func_80A87F44;
this->dyna.actor.draw = NULL;
Actor_SetScale(&this->dyna.actor, 0.087f);
return;
}
if (temp_v0 != 1) {
return;
}
DynaPolyActor_Init(&this->dyna, 0);
CollisionHeader_GetVirtual(&D_0600BA8C, &sp4C);
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
this->dyna.actor.update = func_80A87F44;
this->dyna.actor.draw = NULL;
Actor_SetScale(&this->dyna.actor, 0.087f);
}
```
</details>
## Diff
Once preliminary cleanup and struct filling is done, most time spent matching functions is done by comparing the original code with the code you have compiled. This is aided by a program called `diff.py`.
In order to use `diff.py` with the symbol names, we need a copy of the code to compare against. This is done by copying the `build` directory into a directory called `expected`. Copying in Windows on WSL is very slow, so run
```
$ mkdir expected
cp -r build expected/
```
from the main directory of the repository. You should end up with the directory structure `expected/build/...`.
You may want to do this again when you start renaming functions. *Make sure that you copy an OK build, or you are going to get very confused.* You should also do this again after needing to do a `make clean`.
Now, we run diff on the function name: in the main directory,
```
$ ./diff.py -mwo3 EnJj_Init
```
(To see what these arguments do, run it with `./diff.py -h` or look in the scripts documentation.)
This gives the following:
<details>
<summary>
Large image, click to show.
</summary>
![Init diff 1](images/init_diff1.png)
</details>
The code we want is on the left, current code on the right. To spot where the function ends, either look for where stuff is added and subtracted from the stack pointer in successive lines, or for a
```MIPS
jr ra
nop
```
The colours mean the following:
- White/gray is matching lines
- Red is lines missing
- Green is extra lines
- Blue denotes significant differences in instructions, be they just numerical ones, or whole instructions
- Yellow/Gold denotes that instructions are correct but register usage is wrong
- Other colors are used to distinguish incorrectly used registers or stack variables, to make it easy to follow where they are used.
- The colored arrows denote branching. An arrow of one color on the right leads to the arrow of the same color on the left.
Obviously we want to make the whole thing white. This is the tricky bit: you have to have the imagination to try different things until you get the diff to match. You learn these with experience.
Generally, the order of what to fix should be:
1. Control flow (conditionals, where branches go)
2. Instruction ordering and type (functions cannot change order, which is a useful indicator)
3. Regalloc (register allocation) differences
4. Stack differences
(It is this order because the things that happen earlier can influence the things that happen later.)
You can keep the diff open in the terminal, and it will refresh when the C file (but not the H file) is changed with these settings.
In this case, we see that various branches are happening in the wrong place. Here I fear experience is necessary: notice that the function has three blocks that look quite similar, and three separate conditionals that depend on the same variable. This is a good indicator of a switch. Changing the function to use a switch,
```C
void EnJj_Init(Actor* thisx, PlayState* play) {
EnJj* this = THIS;
s32 sp4C;
s16 temp_v0;
sp4C = 0;
Actor_ProcessInitChain(&this->dyna.actor, D_80A88CE0);
ActorShape_Init(&this->dyna.actor.shape, 0.0f, NULL, 0.0f);
temp_v0 = this->dyna.actor.params;
switch (temp_v0) {
case -1:
SkelAnime_InitFlex(play, &this->skelAnime, &D_0600B9A8, &D_06001F4C, this->jointTable,
this->morphTable, 22);
Animation_PlayLoop(&this->skelAnime, &D_06001F4C);
this->unk_30A = 0;
this->unk_30E = 0;
this->unk_30F = 0;
this->unk_310 = 0;
this->unk_311 = 0;
if ((gSaveContext.save.info.eventChkInf[3] & 0x400) != 0) {
func_80A87800(this, func_80A87BEC);
} else {
func_80A87800(this, func_80A87C30);
}
this->childActor = Actor_SpawnAsChild(
&play->actorCtx, &this->dyna.actor, play, ACTOR_EN_JJ, this->dyna.actor.world.pos.x - 10.0f,
this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, this->dyna.actor.world.rot.y, 0, 0);
DynaPolyActor_Init(&this->dyna, 0);
CollisionHeader_GetVirtual(&D_06000A1C, &sp4C);
this->dyna.bgId =
DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
Collider_InitCylinder(play, &this->collider);
Collider_SetCylinder(play, &this->collider, &this->dyna.actor, &D_80A88CB4);
this->dyna.actor.colChkInfo.mass = 0xFF;
break;
case 0:
DynaPolyActor_Init(&this->dyna, 0);
CollisionHeader_GetVirtual(&D_06001830, &sp4C);
// temp_a1_2 = &play->colCtx.dyna;
// sp44 = temp_a1_2;
this->dyna.bgId =
DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
func_8003ECA8(play, &play->colCtx.dyna, this->dyna.bgId);
this->dyna.actor.update = func_80A87F44;
this->dyna.actor.draw = NULL;
Actor_SetScale(&this->dyna.actor, 0.087f);
break;
case 1:
DynaPolyActor_Init(&this->dyna, 0);
CollisionHeader_GetVirtual(&D_0600BA8C, &sp4C);
this->dyna.bgId =
DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
this->dyna.actor.update = func_80A87F44;
this->dyna.actor.draw = NULL;
Actor_SetScale(&this->dyna.actor, 0.087f);
break;
}
}
```
we see that the diff is nearly correct (note that `-3` lets you compare current with previous):
<details>
<summary>
Large image, click to show.
</summary>
![Init diff 2](images/init_diff2.png)
</details>
except we still have some stack issues. Now that `temp_v0` is only used once, it looks fake. Eliminating it actually seems to make the stack worse. To fix this, we employ something that we have evidence that the developers did: namely, we make a copy of `play` (the theory is that they actually used `gameState` as an argument of the main 4 functions, just like we used `Actor* thisx` as the first argument.) The quick way to do this is to change the top of the function to
```C
void EnJj_Init(Actor* thisx, PlayState* play2) {
PlayState* play = play2;
EnJj* this = THIS;
...
```
It turns out that this is enough to completely fix the diff:
![Init diff 2](images/init_diff3top.png)
(last two edits, only top shown for brevity)
Everything *looks* fine, but we only know for sure when we run `make`. Thankfully doing so gives
```
oot-gc-eu-mq-dbg.z64: OK
```
which is either a sense of triumph or relief depending on how long you've spent on a function.
And with that, we have successfully matched our first function. (Or first two counting `func_80A87800`)
**N.B** Notice that we don't yet have much idea of what this code actually does: this should be clarified by going through the rest of the actor's functions, which is discussed in the next document.
Next: [Other functions in the actor](other_functions.md)

View file

@ -1,62 +0,0 @@
# Getting started
## [Introduction to decomp](introduction.md)
- What we are doing
- Structure of the code
## Pre-decompilation
- Building the repo (follow the instructions in the README.md)
- Most of us use VSCode. (You can watch Fig's video to get an idea of how this can be used). Some useful information is [here](../vscode.md).
- Choosing a first actor (You want something small that has simple interactions with the environment. But OoT is far enough in that there are basically no unreserved actors left anyway now.)
## Decompilation
- [Begining decompilation: order, Init and the actor struct](beginning_decomp.md)
- Order of decompilation
- Init and common actor features
- Initchains
- Actors and dynapoly actors
- Colliders
- Skelanime
- Matching
- Using diff
- control flow (branches) -> instruction ordering -> register allocation -> stack
- [The rest of the functions in the actor](other_functions.md)
- Order of decompilation
- Action Functions and other functions
- More on matching: the permuter
- [Draw functions](draw_functions.md)
- [Data, migration and non-migration](data.md)
- Importing the data: early and late
- Fake symbols
- Inlining
## [Object Decompilation](object_decomp.md)
- Object files
- How we decompile objects
- [Example](object_decomp_example.md)
## After Decompilation
- [Preparing to merge](merging.md)
- Preliminary documentation
- Preparing to PR
- Pull Requests
- Trello
## Appendices
- [Types, Structs and Padding](types_structs_padding.md) (a miscellany of useful stuff)
- [Helper scripts](helper_scripts.md)
To be written, maybe
- How we use git and GitHub
- Some notes on the basic structure of N64 MIPS
- Glossary
- Conventions

View file

@ -1,648 +0,0 @@
# Data
## Table of Contents
- [Data first](#data-first)
* [Example: `EnTg`](#example-entg)
- [Extern and data last](#extern-and-data-last)
- [Fake symbols](#fake-symbols)
- [Inlining](#inlining)
Each actor's data is stored in a separate file. EnJj's data is in `data/overlays/actors/z_en_jj.data.s`, for example. At some point in the decompilation process we need to convert this raw data into recognisable information for the C to use.
There are two main ways to do this: either
1. import the data first and type it later, or
2. wait until the data appears in functions, extern it, then import it at the end
Sometimes something between these two is appropriate: wait until the largest or strangest bits of data appear in functions, get some typing information out of that, and then import it, but for now, let's stick to both of these.
Both approaches have their advantages and disadvantages.
## Data first
<!-- Fig shows how to do this in his video. -->
This way is good for smaller actors with little data. It is not really suitable for EnJj, for example, because of the enormous section of data labelled as `D_80A88164`.
### Example: `EnTg`
We give a simple example of this approach with a small NPC actor, EnTg, that is, the spinning couple.
The data file looks like
<details>
<summary>
Large code block, click to show
</summary>
```
.include "macro.inc"
/* assembler directives */
.set noat /* allow manual use of $at */
.set noreorder /* don't insert nops after branches */
.set gp=64 /* allow use of 64-bit general purpose registers */
.section .data
.balign 16
glabel D_80B18910
.word 0x0A000039, 0x20010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00140040, 0x00000000, 0x00000000
glabel D_80B1893C
.word 0x00000000, 0x00000000, 0xFF000000
glabel En_Tg_InitVars
.word 0x01AC0400, 0x00000009, 0x01820000, 0x0000020C
.word EnTg_Init
.word EnTg_Destroy
.word EnTg_Update
.word EnTg_Draw
glabel D_80B18968
.word 0x00000000, 0x44480000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
```
</details>
We transfer this data into the actor file by pretending it is an array of words. The InitVars have already been processed and inserted into the C file, so just need to be uncommented. Data cannot change order, so the two pieces above the InitVars must stay there. At the end of this process, the top of the file will look like
<details>
<summary>
Large code block, click to show
</summary>
```C
/*
* File: z_en_tg.c
* Overlay: ovl_En_Tg
* Description: Honey & Darling
*/
#include "z_en_tg.h"
#define FLAGS 0x00000009
#define THIS ((EnTg*)thisx)
void EnTg_Init(Actor* thisx, PlayState* play);
void EnTg_Destroy(Actor* thisx, PlayState* play);
void EnTg_Update(Actor* thisx, PlayState* play);
void EnTg_Draw(Actor* thisx, PlayState* play);
s32 D_80B18910[] = { 0x0A000039, 0x20010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000100, 0x00140040, 0x00000000, 0x00000000 };
s32 D_80B1893C[] = { 0x00000000, 0x00000000, 0xFF000000 };
ActorInit En_Tg_InitVars = {
/**/ ACTOR_EN_TG,
/**/ ACTORTYPE_NPC,
/**/ FLAGS,
/**/ OBJECT_MU,
/**/ sizeof(EnTg),
/**/ EnTg_Init,
/**/ EnTg_Destroy,
/**/ EnTg_Update,
/**/ EnTg_Draw,
};
s32 D_80B18968[] = { 0x00000000, 0x44480000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
extern UNK_TYPE D_06005040;
extern UNK_TYPE D_0600AE40;
```
</details>
Now, open the file called `spec` in the base directory, find the section corresponding to EnTg:
```
beginseg
name "ovl_En_Tg"
include "$(BUILD_DIR)/src/overlays/actors/ovl_En_Tg/z_en_tg.o"
include "$(BUILD_DIR)/data/overlays/actors/z_en_tg.data.o"
include "$(BUILD_DIR)/data/overlays/actors/z_en_tg.reloc.o"
endseg
```
and comment out the .data line,
```
beginseg
name "ovl_En_Tg"
include "$(BUILD_DIR)/src/overlays/actors/ovl_En_Tg/z_en_tg.o"
//include "$(BUILD_DIR)/data/overlays/actors/z_en_tg.data.o"
include "$(BUILD_DIR)/data/overlays/actors/z_en_tg.reloc.o"
endseg
```
to tell the compiler not to look for the data in that file any more. Now run `make -j`, and if you did both steps correctly, you should get `OK`.
Now carry out the usual steps to decompile `Init`. The usual cleanup and struct population gets us to
```C
void EnTg_Init(Actor *thisx, PlayState *play) {
EnTg *this = THIS;
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Circle, 28.0f);
SkelAnime_InitFlex(play, &this->skelAnime, &D_0600AE40, &D_06005040, 0, 0, 0);
Collider_InitCylinder(play, &this->collider);
Collider_SetCylinder(play, &this->collider, &this->actor, (ColliderCylinderInit *) D_80B18910);
func_80061EFC(&this->actor.colChkInfo, NULL, (CollisionCheckInfoInit2 *) D_80B1893C);
this->actor.unk_1F = 6;
Actor_SetScale(&this->actor, 0.01f);
this->actionFunc = func_80B185C0;
this->unk_208 = play->state.frames & 1;
}
```
and it remains to deal with the data. mips2c has told us what the types should be. We run `colliderinit` on `D_80B18910` as usual, which gives
```
$ ./tools/overlayhelpers/colliderinit.py 80B18910 ColliderCylinderInit
ovl_En_Tg: Rom 00ECE1F0:00ECE910 VRam 80B18360:80B18A80 Offset 0005B0
static ColliderCylinderInit sCylinderInit =
{
{ COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 },
{ 20, 64, 0, { 0, 0, 0 } },
};
```
Copy this in below `D_80B18910`, delete the original words of data, change the name back to `D_80B18910`, and put `sCylinderInit` commented out above it:
```C
// sCylinderInit
static ColliderCylinderInit D_80B18910 =
{
{ COLTYPE_UNK10, 0x00, 0x00, 0x39, 0x20, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, 0x00, 0x00, 0x01 },
{ 20, 64, 0, { 0, 0, 0 } },
};
```
For the `CollisionCheckInfoInit2`, we don't have a script to separate it, but you can look in other files to see that it should be separated as
```C
// sColChkInit
CollisionCheckInfoInit2 D_80B1893C = { 0, 0, 0, 0, 0xFF };
```
One more thing needs to change: since both are no longer arrays, we need to make the uses in the functions pointers:
```C
Collider_SetCylinder(play, &this->collider, &this->actor, &D_80B18910);
func_80061EFC(&this->actor.colChkInfo, NULL, &D_80B1893C);
```
A quick check of the diff shows that we just need to put the action function set to last, and it matches.
Following the function tree as usual, we find the only other place any data is used is in `func_80B1871C`. From its use in `EnTg_Draw`, we realise that this is a `PostLimbDraw` function. Giving mips2c the correct prototype, it comes out as
```C
void func_80B1871C(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
? sp18;
sp18.unk0 = (s32) D_80B18968->unk0;
sp18.unk4 = (s32) D_80B18968[1];
sp18.unk8 = (s32) D_80B18968[2];
if (limbIndex == 9) {
Matrix_MultVec3f((Vec3f *) &sp18, thisx + 0x38);
}
}
```
which clearly doesn't like the words we fed it. We see that `sp18` should be a `Vec3f` from the cast in the `Matrix_MultVec3f`, so the last three words are padding (a `Vec3f` has size `0xC`, and it's not using it like an array), and we can convert it to
```C
Vec3f D_80B18968 = { 0.0f, 800.0f, 0.0f };
```
and the function matches as
```C
void func_80B1871C(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
EnTg* this = THIS;
Vec3f sp18 = D_80B18968;
if (limbIndex == 9) {
Matrix_MultVec3f(&sp18, &this->actor.world2.pos);
}
}
```
(we can see from the assembly doing `lw` and `sw` rather than `lwc1` and `swc1` that it is doing a struct copy, rather than setting it componentwise).
## Extern and data last
Externing is explained in detail in the document about the [Init function](beginning_decomp.md). To summarize, every time a `D_address` appears that is in the data file, we put a
```C
extern UNK_TYPE D_address;
```
at the top of the file, in the same order that the data appears in the data file. We can also give it a type if we know what the type actually is (e.g. for colliders, initchains, etc.), and convert the actual data and place it commented-out under the corresponding line. This means we don't have to do everything at once at the end.
Once we have decompiled enough things to know what the data is, we can import it. The advantage of doing it this way is we should know what type everything is already: in our work on EnJj, for example, we ended up with the following data at the top of the file
```C
extern UNK_TYPE D_80A88164;
extern ColliderCylinderInit D_80A88CB4;
// static ColliderCylinderInit sCylinderInit =
// {
// { COLTYPE_UNK10, 0x00, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
// { 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000004, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
// { 170, 150, 0, { 0, 0, 0 } },
// };
extern InitChainEntry D_80A88CE0[];
// static InitChainEntry sInitChain[] = {
// ICHAIN_VEC3F_DIV1000(scale, 87, ICHAIN_CONTINUE),
// ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
// ICHAIN_F32(uncullZoneScale, 3300, ICHAIN_CONTINUE),
// ICHAIN_F32(uncullZoneDownward, 1100, ICHAIN_STOP),
// };
extern Vec3f D_80A88CF0;
// static Vec3f D_80A88CF0 = { -1589.0f, 53.0f, -43.0f };
extern Gfx* D_80A88CFC[];
// static Gfx* D_80A88CFC[] = { 0x06007698, 0x06007A98, 0x06007E98, }
```
and the only thing we don't know about is the cutscene data `D_80A88164`.
*Before doing anything else, make sure `make` gives `OK`.*
First, we tell the compiler to ignore the original data file. To do this, open the file called `spec` in the main directory of the repository, and search for the actor name. You will find a section that looks like
```
beginseg
name "ovl_En_Jj"
include "$(BUILD_DIR)/src/overlays/actors/ovl_En_Jj/z_en_jj.o"
include "$(BUILD_DIR)/data/overlays/actors/z_en_jj.data.o"
include "$(BUILD_DIR)/data/overlays/actors/z_en_jj.reloc.o"
endseg
```
We will eventually remove both of the bottom two lines and replace them with our own reloc file, but for now, just comment out the data line:
```
beginseg
name "ovl_En_Jj"
include "$(BUILD_DIR)/src/overlays/actors/ovl_En_Jj/z_en_jj.o"
//include "$(BUILD_DIR)/data/overlays/actors/z_en_jj.data.o"
include "$(BUILD_DIR)/data/overlays/actors/z_en_jj.reloc.o"
endseg
```
Next remove all the externs, and uncomment their corresponding commented data:
```C
extern UNK_TYPE D_80A88164;
static ColliderCylinderInit sCylinderInit =
{
{ COLTYPE_UNK10, 0x00, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000004, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
{ 170, 150, 0, { 0, 0, 0 } },
};
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 87, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 3300, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1100, ICHAIN_STOP),
};
static Vec3f D_80A88CF0 = { -1589.0f, 53.0f, -43.0f };
static Gfx* D_80A88CFC[] = { 0x06007698, 0x06007A98, 0x06007E98, }
```
Find-and-replace `D_80A88CB4` and `D_80A88CE0` by `sCylinderInit` and `sInitChain` respectively. Notice the naming scheme: static data symbols always start with `s` in our style. (Unless they are inlined, but we'll worry about that later.)
We still need to deal with the cutscene data. This is special: because it's so large, it goes in its own file. Make a new file called `z_en_jj_cutscene_data.c` in the same directory as `z_en_jj.c`. Include the actor's header file and `z64cutscene_commands.h`, and put `// clang-format off` and `// clang-format on` in the file (this is so that our formatting script doesn't wreak havoc with the formatting of the cutscene macros). Thus the contents of the file is currently
```C
#include "z_en_jj.h"
#include "z64cutscene_commands.h"
// clang-format off
// clang-format on
```
Finally, we have a script to convert the cutscene data into macros, namely `csdis.py` in the tools folder. We can just give it the VRAM address that the `D_address` is referring to, and it will output the cs macros:
<details>
<summary>
(Very) long code block, click to view
</summary>
```
$ ./tools/csdis.py 80A88164
ovl_En_Jj: Rom 00E3E3D0:00E3F9E0 VRam 80A87800:80A88E10 Offset 000964
static CutsceneData D_80A88164[] = {
CS_BEGIN_CUTSCENE(26, 1629),
CS_PLAYER_CUE_LIST(4),
CS_PLAYER_CUE(PLAYER_CUEID_5, 0, 240, 0x0000, 0x4000, 0x0000, -1732, 52, -44, -1732, 52, -44, 1.1393037197548209e-29f, 0.0f, 1.401298464324817e-45f),
CS_PLAYER_CUE(PLAYER_CUEID_3, 240, 255, 0x0000, 0x4000, 0x0000, -1732, 52, -44, -1732, 52, -44, 1.1393037197548209e-29f, 0.0f, 1.401298464324817e-45f),
CS_PLAYER_CUE(PLAYER_CUEID_6, 255, 285, 0x0000, 0x4000, 0x0000, -1732, 52, -44, -1732, 52, -44, 1.1393037197548209e-29f, 0.0f, 1.401298464324817e-45f),
CS_PLAYER_CUE(PLAYER_CUEID_32, 285, 300, 0x0000, 0xC000, 0x0000, -1732, 52, -44, -1537, 109, -44, 1.1393037197548209e-29f, 0.0f, 1.401298464324817e-45f),
CS_ACTOR_CUE_LIST(68, 4),
CS_ACTOR_CUE(0x0001, 0, 234, 0x0000, 0x4000, 0x0000, -1665, 52, -44, -1665, 52, -44, 1.1393037197548209e-29f, 0.0f, 1.401298464324817e-45f),
CS_ACTOR_CUE(0x0002, 234, 241, 0x41F8, 0x0000, 0x0000, -1665, 52, -44, -1603, 130, -47, 8.857142448425293f, 11.142857551574707f, -8.857142448425293f),
CS_ACTOR_CUE(0x0002, 241, 280, 0x4031, 0x0000, 0x0000, -1603, 130, -47, -549, 130, -52, 27.0256404876709f, 0.0f, -27.0256404876709f),
CS_ACTOR_CUE(0x0003, 280, 300, 0x0000, 0x0000, 0x0000, -549, 130, -52, -549, 130, -52, 0.0f, 0.0f, 0.0f),
CS_ACTOR_CUE_LIST(67, 5),
CS_ACTOR_CUE(0x0001, 0, 93, 0x0000, 0x0000, 0x0000, 0, 51, 124, 0, 51, 124, 0.0f, 0.0f, 0.0f),
CS_ACTOR_CUE(0x0003, 93, 121, 0x0000, 0x0000, 0x0000, 0, 51, 124, 0, 51, 124, 0.0f, 0.0f, 0.0f),
CS_ACTOR_CUE(0x0001, 121, 146, 0x0000, 0x0000, 0x0000, 0, 51, 124, 0, 51, 124, 0.0f, 0.0f, 0.0f),
CS_ACTOR_CUE(0x0002, 146, 241, 0x0000, 0x0000, 0x0000, 0, 51, 124, 0, 51, 124, 0.0f, 0.0f, 0.0f),
CS_ACTOR_CUE(0x0001, 241, 441, 0x0000, 0x0000, 0x0000, 0, 51, 124, 0, 51, 124, 0.0f, 0.0f, 0.0f),
CS_ACTOR_CUE_LIST(69, 3),
CS_ACTOR_CUE(0x0001, 0, 90, 0x0000, 0x0000, 0x0000, 0, -33, 9, 0, -33, 9, 0.0f, 0.0f, 0.0f),
CS_ACTOR_CUE(0x0002, 90, 330, 0x0000, 0x0000, 0x0000, 0, -33, 9, 0, -62, 22, 0.0f, -0.12083332985639572f, 0.0f),
CS_ACTOR_CUE(0x0003, 330, 380, 0x0000, 0x0000, 0x0000, 0, -62, 22, 0, -62, 22, 0.0f, 0.0f, 0.0f),
CS_MISC_LIST(1),
CS_MISC(0x000C, 1095, 1161, 0x0000, 0x00000000, 0xFFFFFFD2, 0x00000000, 0xFFFFFFD0, 0xFFFFFFD2, 0x00000000, 0xFFFFFFD0, 0x00000000, 0x00000000, 0x00000000),
CS_TRANSITION(0x0009, 0, 10),
CS_PLAYER_CUE_LIST(1),
CS_PLAYER_CUE(PLAYER_CUEID_53, 300, 1629, 0x0000, 0x0000, 0x0000, -1630, 52, -52, -1630, 52, -52, 0.0f, 0.0f, 0.0f),
CS_CAM_EYE_SPLINE(0, 1091),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x015C),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x016D),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x017E),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x0223),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x7065),
CS_CAM_EYE_SPLINE(60, 1151),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1532, 251, 222, 0x015C),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1532, 251, 222, 0x016D),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1532, 251, 222, 0x017E),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1532, 251, 222, 0x0223),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 0, 45.39994430541992f, -1532, 251, 222, 0x7065),
CS_CAM_EYE_SPLINE(90, 351),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1698, 382, 455, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1698, 382, 455, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1698, 382, 455, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1694, 380, 451, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 32.99989700317383f, -1694, 380, 451, 0xAC10),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 32.99989700317383f, -1694, 380, 451, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 32.99989700317383f, -1694, 380, 451, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 32.99989700317383f, -1694, 380, 451, 0x0164),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 0, 32.99989700317383f, -1694, 380, 451, 0xAD78),
CS_CAM_EYE_SPLINE(220, 392),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0xAC10),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 0, 45.39994430541992f, -1641, 95, -41, 0x0000),
CS_CAM_EYE_SPLINE(240, 1331),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.599945068359375f, -1810, 65, -15, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.599945068359375f, -1810, 65, -15, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.599945068359375f, -1810, 65, -15, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.599945068359375f, -1810, 65, -15, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 0, 45.599945068359375f, -1810, 65, -15, 0xAC10),
CS_CAM_EYE_SPLINE(280, 1371),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.599945068359375f, -1531, 95, -7, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.599945068359375f, -1531, 95, -7, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.599945068359375f, -1531, 95, -7, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.599945068359375f, -1531, 95, -7, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 0, 45.599945068359375f, -1531, 95, -7, 0xAC10),
CS_CAM_EYE_SPLINE(310, 1421),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1717, 83, -59, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1717, 83, -59, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1649, 177, -59, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1533, 224, -59, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -1243, 180, -59, 0xAC10),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -953, 71, -55, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -953, 71, -55, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 45.39994430541992f, -953, 71, -55, 0x0164),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 0, 45.39994430541992f, -953, 71, -55, 0xAD78),
CS_CAM_EYE_SPLINE(355, 1466),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 60.60000228881836f, -1830, 103, 18, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 60.60000228881836f, -1830, 103, 18, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 60.60000228881836f, -1830, 103, 18, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 60.60000228881836f, -1830, 103, 18, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 60.60000228881836f, -1830, 103, 18, 0xAC10),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 0, 60.60000228881836f, -1830, 103, 18, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 0, 60.60000228881836f, -1830, 103, 18, 0x0000),
CS_CAM_AT_SPLINE(0, 1120),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1724, -5, -45, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1724, -5, -45, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 1000, 45.39994430541992f, -1724, -5, -45, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1724, -5, -45, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 30, 45.39994430541992f, -1724, -5, -45, 0xAC10),
CS_CAM_AT_SPLINE(60, 1180),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1440, 241, 134, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1440, 241, 134, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 1000, 45.39994430541992f, -1440, 241, 134, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1440, 241, 134, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 30, 45.39994430541992f, -1440, 241, 134, 0xAC10),
CS_CAM_AT_SPLINE(90, 380),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1610, 348, 373, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1610, 348, 373, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 50, 45.39994430541992f, -1610, 348, 373, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 35.399906158447266f, -1614, 338, 367, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 32.99989700317383f, -1614, 338, 367, 0xAC10),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 32.99989700317383f, -1614, 338, 367, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 32.99989700317383f, -1614, 338, 367, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 32.99989700317383f, -1614, 338, 367, 0x0164),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 30, 32.99989700317383f, -1614, 338, 367, 0xAD78),
CS_CAM_AT_SPLINE(220, 421),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1724, -5, -45, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 70, 45.39994430541992f, -1724, -5, -45, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 5, 45.39994430541992f, -1724, -5, -45, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 6, 45.79994583129883f, -1593, 150, -146, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1531, 152, -75, 0xAC10),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -1531, 152, -75, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 30, 45.39994430541992f, -1531, 152, -75, 0x0000),
CS_CAM_AT_SPLINE(240, 1360),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.599945068359375f, -1712, 74, -37, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.599945068359375f, -1712, 74, -37, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 1000, 45.599945068359375f, -1712, 74, -37, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.599945068359375f, -1712, 74, -37, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 30, 45.599945068359375f, -1712, 74, -37, 0xAC10),
CS_CAM_AT_SPLINE(280, 1400),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.599945068359375f, -1619, 99, -50, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.599945068359375f, -1619, 99, -50, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 1000, 45.599945068359375f, -1619, 99, -50, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.599945068359375f, -1619, 99, -50, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 30, 45.599945068359375f, -1619, 99, -50, 0xAC10),
CS_CAM_AT_SPLINE(310, 1450),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x0B, 30, 90.99960327148438f, -1610, 141, -59, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x09, 10, 90.79960632324219f, -1599, 114, -57, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0xFC, 10, 90.39961242675781f, -1528, 192, -54, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 10, 90.599609375f, -1427, 164, -54, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0xCB, 10, 90.39961242675781f, -1138, 119, -37, 0xAC10),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x20, 10, 90.39961242675781f, -832, 50, -51, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 1000, 45.39994430541992f, -836, 35, -51, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 45.39994430541992f, -836, 35, -51, 0x0164),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 30, 45.39994430541992f, -836, 35, -51, 0xAD78),
CS_CAM_AT_SPLINE(355, 1495),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 60.60000228881836f, -1706, 111, -6, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 60.60000228881836f, -1706, 111, -6, 0xAC34),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 10, 60.60000228881836f, -1706, 111, -6, 0x4428),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 10, 60.60000228881836f, -1721, 82, -42, 0x0000),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 1000, 60.60000228881836f, -1721, 82, -42, 0xAC10),
CS_CAM_POINT(CS_CAM_CONTINUE, 0x00, 30, 60.60000228881836f, -1721, 82, -42, 0x0000),
CS_CAM_POINT(CS_CAM_STOP, 0x00, 30, 60.60000228881836f, -1721, 82, -42, 0x0000),
CS_TRANSITION(0x000B, 335, 342),
CS_DESTINATION(CS_DEST_JABU_JABU, 345, 395),
CS_ACTOR_CUE_LIST(62, 1),
CS_ACTOR_CUE(0x0001, 305, 494, 0x0000, 0x0000, 0x0000, -1399, 452, -53, -1399, 452, -53, 0.0f, 0.0f, 0.0f),
CS_END(),
};
```
</details>
Copy this into the file we just made (given the length, you may prefer to `>` it into a file and copy it from there, rather than the terminal itself). Save and close that file: we won't need it any more.
To replace the `extern`, because the data is in a separate file, we include the file in a particular way:
```C
#include "z_en_jj_cutscene_data.c" EARLY
```
(`EARLY` is required specifically for cutscene data. See [the definition of the CutsceneData struct](../include/z64cutscene.h) for exactly why.)
Lastly, uncomment the InitVars block that's been sitting there the whole time. The data section of the file now looks like
```C
ActorInit En_Jj_InitVars = {
/**/ ACTOR_EN_JJ,
/**/ ACTORTYPE_ITEMACTION,
/**/ FLAGS,
/**/ OBJECT_JJ,
/**/ sizeof(EnJj),
/**/ EnJj_Init,
/**/ EnJj_Destroy,
/**/ EnJj_Update,
/**/ EnJj_Draw,
};
#include "en_jj_cutscene_data.c" EARLY
static ColliderCylinderInit sCylinderInit =
{
{ COLTYPE_UNK10, 0x00, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000004, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
{ 170, 150, 0, { 0, 0, 0 } },
};
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 87, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 3300, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1100, ICHAIN_STOP),
};
static Vec3f D_80A88CF0 = { -1589.0f, 53.0f, -43.0f };
static Gfx* D_80A88CFC[] = { 0x06007698, 0x06007A98, 0x06007E98, };
```
That should be everything, and we should now be able to `make` without the data file with no issues
But running `make`, we get the dreaded Error 1:
```
md5sum: WARNING: 1 computed checksum did NOT match
make: *** [Makefile:172: all] Error 1
```
Oh no! What went wrong?
To find out what went wrong, we need to use `firstdiff.py`. This tells us where our ROM starts to differ:
```
$ ./firstdiff.py
First difference at ROM addr 0x144F4, gDmaDataTable (RAM 0x80016DA0, ROM 0x12F70, build/asm/dmadata.o)
Bytes: 00:E3:F9:D0 vs 00:E3:F9:E0
Instruction difference at ROM addr 0xE3ED48, En_Jj_InitVars (RAM 0x80A88140, ROM 0xE3ED10, build/src/overlays/actors/ovl_En_Jj/z_en_jj.o)
Bytes: 40:00:00:00 vs 00:F0:00:00
Instruction difference at ROM addr 0xE3F900, D_80A88D40 (RAM 0x80A88D30, ROM 0xE3F900, build/data/overlays/actors/z_en_jj.reloc.o)
Bytes: 00:00:09:40 vs C4:89:80:00
Instruction difference at ROM addr 0xE3F9D4, En_Js_SetupAction (RAM 0x80A88E00, ROM 0xE3F9D0, build/src/overlays/actors/ovl_En_Js/z_en_js.o)
Bytes: AC:85:02:8C vs 00:00:00:00
Instruction difference at ROM addr 0xE3F9D8, EnJs_Init (RAM 0x80A88E08, ROM 0xE3F9D8, build/src/overlays/actors/ovl_En_Js/z_en_js.o)
Bytes: 27:BD:FF:B0 vs 00:00:00:00
Instruction difference at ROM addr 0xE3FAFC, EnJs_Destroy (RAM 0x80A88F2C, ROM 0xE3FAFC, build/src/overlays/actors/ovl_En_Js/z_en_js.o)
Bytes: 27:BD:FF:E8 vs 8F:B0:00:34
Over 1000 differing words, must be a shifted ROM.
Map appears to have shifted just before D_80A88D40 (build/data/overlays/actors/z_en_jj.reloc.o) -- in En_Jj_InitVars?
```
Ignore the first line: `gDmaDataTable` is always different if the ROM is shifted. The useful lines are usually the next line, and the guess it makes at the end.
To fix this, we use a binary diff program. A suitable one is `vbindiff`: run it on the baserom and the zelda_whatever one the compiler generates:
```
vbindiff baseroms/gc-eu-mq-dbg/baserom-decompressed.z64 oot-gc-eu-mq-dbg.z64
```
In this, press `g` to open up goto position, and paste in the address `0xE3ED10` from the first important line of the `first_diff` output. This gives us the following:
![vbindiff for data](images/vbindiff_data_1.png)
Notice that the numbers in the bottom pane is all shifted one word to the left. We therefore need some extra padding somewhere. The real issue is where. Thankfully the guess at the bottom gives us a hint: let's try just under `InitVars`. Just put a padding variable straight after them:
```C
ActorInit En_Jj_InitVars = {
/**/ ACTOR_EN_JJ,
/**/ ACTORTYPE_ITEMACTION,
/**/ FLAGS,
/**/ OBJECT_JJ,
/**/ sizeof(EnJj),
/**/ EnJj_Init,
/**/ EnJj_Destroy,
/**/ EnJj_Update,
/**/ EnJj_Draw,
};
s32 usused = 0;
#include "z_en_jj_cutscene_data.c" EARLY
```
This isn't good enough: we still get Error 1, but:
```
$ ./first_diff.py
First difference at ROM addr 0x144F4, gDmaDataTable (RAM 0x80016DA0, ROM 0x12F70, build/asm/dmadata.o)
Bytes: 00:E3:F9:D0 vs 00:E3:F9:E0
Instruction difference at ROM addr 0xE3F87C, unused (RAM 0x80A88160, ROM 0xE3ED30, build/src/overlays/actors/ovl_En_Jj/z_en_jj.o)
Bytes: 0A:00:09:39 vs 00:00:00:00
Instruction difference at ROM addr 0xE3F900, D_80A88D40 (RAM 0x80A88D30, ROM 0xE3F900, build/data/overlays/actors/z_en_jj.reloc.o)
Bytes: 00:00:09:40 vs C4:89:80:00
Instruction difference at ROM addr 0xE3F9D4, En_Js_SetupAction (RAM 0x80A88E00, ROM 0xE3F9D0, build/src/overlays/actors/ovl_En_Js/z_en_js.o)
Bytes: AC:85:02:8C vs 00:00:00:00
Instruction difference at ROM addr 0xE3F9D8, EnJs_Init (RAM 0x80A88E08, ROM 0xE3F9D8, build/src/overlays/actors/ovl_En_Js/z_en_js.o)
Bytes: 27:BD:FF:B0 vs 00:00:00:00
Instruction difference at ROM addr 0xE3FAFC, EnJs_Destroy (RAM 0x80A88F2C, ROM 0xE3FAFC, build/src/overlays/actors/ovl_En_Js/z_en_js.o)
Bytes: 27:BD:FF:E8 vs 8F:B0:00:34
Over 1000 differing words, must be a shifted ROM.
Map appears to have shifted just before D_80A88D40 (build/data/overlays/actors/z_en_jj.reloc.o) -- in unused?
(Base map file expected/build/z64.map out of date due to new or renamed symbols, so result may be imprecise.)
```
We've managed to get rid of one issue, but there's still another one. Looking in vbindiff again,
![vbindiff data 2](images/vbindiff_data_2.png)
we see that everything is shifted left by 2 words. Guessing based on the hint from `first_diff`, we put two words after the cutscene include:
```C
#include "z_en_jj_cutscene_data.c" EARLY
s32 usused2[] = { 0, 0 };
static ColliderCylinderInit sCylinderInit =
{
{ COLTYPE_UNK10, 0x00, 0x09, 0x39, 0x10, COLSHAPE_CYLINDER },
{ 0x00, { 0x00000000, 0x00, 0x00 }, { 0x00000004, 0x00, 0x00 }, 0x00, 0x01, 0x01 },
{ 170, 150, 0, { 0, 0, 0 } },
};
```
Running `make -j` again,
```
oot-gc-eu-mq-dbg.z64: OK
```
Hooray, we won!
## Fake symbols
Some symbols in the data have been decompiled wrongly, being incorrectly separated from the previous symbol due to how it was accessed by the actor's functions. However, most of these have now been fixed. Some more detail is given in [Types, structs and padding](types_structs_padding.md) If you are unsure, ask!
## Inlining
After the file is finished, it is possible to move some static data into functions. This requires that:
1. The data is used in only one function
2. The ordering of the data can be maintained
Additionally, we prefer to keep larger data (more than a line or two) out of functions anyway.
# Finally: .bss
A .bss contains data that is uninitialised (actually initialised to `0`). For most actors all you need to do is declare it at the top of the actor file without giving it a value, once you find out what type it is.

View file

@ -1,476 +0,0 @@
# Draw functions
Up: [Contents](contents.md)
Previous: [The rest of the functions in the actor](other_functions.md)
Draw functions behave completely differently from the other functions in an actor. They often use a lot of macros.
For this tutorial we will first look at the `EnJj` draw function, `EnJj_Draw`, then some more complicated examples.
## A first example
Unless it is completely invisible, an actor usually has a draw function as one of the main four actor functions. Hence its prototype looks like
```C
EnJj_Draw(Actor* thisx, PlayState* play);
```
As in Init, Destroy and Update, it is much more convenient to feed mips2c the fake prototype
```C
EnJj_Draw(EnJj* this, PlayState* play);
```
so that it fills out the struct fields from the actuar actor; we then put a
```C
EnJj* this = THIS;
```
in the declarations as before. From now on, the process is rather different from the decompilation process used for the other functions. Here is the output of mips2c after sorting out the actor struct from Init, and with the arguments set back to `Actor* thisx`:
```C
void EnJj_Draw(Actor *thisx, PlayState *play) {
EnJj* this = THIS;
GraphicsContext *sp4C;
Gfx *sp3C;
EnJj *sp18;
Gfx *temp_v1;
GraphicsContext *temp_a1;
s32 temp_a0;
temp_a1 = play->state.gfxCtx;
sp4C = temp_a1;
Graph_OpenDisps(&sp3C, temp_a1, (const char *) "../z_en_jj.c", 0x36F);
Gfx_SetupDL_37Opa(play->state.gfxCtx);
Matrix_Translate(0.0f, (cosf(this->skelAnime.curFrame * 0.076624215f) * 10.0f) - 10.0f, 0.0f, (u8)1U);
Matrix_Scale(10.0f, 10.0f, 10.0f, (u8)1U);
temp_v1 = temp_a1->polyOpa.p;
temp_a1->polyOpa.p = temp_v1 + 8;
temp_v1->words.w0 = 0xDB060020;
temp_a0 = *(&D_80A88CFC + (this->unk_30E * 4));
temp_v1->words.w1 = (temp_a0 & 0xFFFFFF) + gSegments[(u32) (temp_a0 * 0x10) >> 0x1C] + 0x80000000;
sp18 = this;
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, (s32) this->skelAnime.dListCount, 0, 0);
Graph_CloseDisps(&sp3C, play->state.gfxCtx, (const char *) "../z_en_jj.c", 0x382);
}
```
Notable features are the Open and Close Disps functions, and blocks of the form
```C
temp_v1 = temp_a1->polyOpa.p;
temp_a1->polyOpa.p = temp_v1 + 8;
temp_v1->words.w0 = 0xDB060020;
temp_a0 = *(&D_80A88CFC + (this->unk_30E * 4));
temp_v1->words.w1 = (temp_a0 & 0xFFFFFF) + gSegments[(u32) (temp_a0 * 0x10) >> 0x1C] + 0x80000000;
```
(This is a particularly simple example, since there's only one of these blocks. We will give a more involved example later.)
Each of these blocks converts into a graphics macro. They are usually (but not always) straightforward, but manually converting them is a pain, and there are sometimes special cases. To deal with them easily, we will use a tool from glank's N64 tools. To install these, follow the instructions [here](https://practicerom.com/public/packages/debian/howto.txt).
For our purposes, we only need one of the programs this provides: `gfxdis.f3dex2`.
Graphics are actually 64-bit on the Nintendo 64. This code block is a result of instructions telling the processor what to do with the graphics pointer. There are two types of graphics pointer,
- polyOpa for solid textures
- polyXlu for translucent textures
Our example is polyOpa, not surprisingly since Jabu is solid.
`words.w0` and `words.w1` contain the actual graphics instruction, in hex format. Usually, `w0` is constant and `w1` contains the arguments. To find out what sort of macro we are dealing with, we use `gfxdis.f3dex2`. `w1` is variable, but we need to give the program a constant placeholder. A common word to use is 12345678, so in this case we run
```
gfxdis.f3dex2 -x -g "POLY_OPA_DISP++" -d DB06002012345678
```
- `-x` uses hex instead of the default qu macros (never mind what those are, OoT doesn't have them)
- `-g` is used to specify which graphics pointer macro to use
- `-d` is for the graphics dword
Our standard now is to use decimal colors. If you have a constant second argument rather than a variable one, you can also use `-dc` to get decimal colors instead of the default hex.
The output looks like
```
gSPSegment(POLY_OPA_DISP++, 0x08, 0x12345678);
```
We can now replace the `0x12345678` by the actual second word. Or we could, if we had worked out what it was.
Firstly, `*(&D_80A88CFC + (this->unk_30E * 4))` is referring to a piece of data we haven't externed yet. It looks like
```
glabel D_80A88CFC
.word 0x06007698, 0x06007A98, 0x06007E98, 0x00000000, 0x00000000
```
The first three words look like pointers to assets in the actor segment, which would make sense if we're looking for textures to draw. The last two words are 0, which is strange. A check in the rest of the actor file shows that `unk_30E` only takes the values `0,1,2`. We conclude that the last two words are just padding, and can be removed. Because this data is used in a graphics macro, it will be either a displaylist or a texture. We therefore set it up to be an array of unknown pointers for now:
```C
extern UNK_PTR D_80A88CFC[];
// static Gfx* D_80A88CFC[] = { 0x06007698, 0x06007A98, 0x06007E98, }
```
It goes through further processing before it is used in the macro: `(temp_a0 & 0xFFFFFF) + gSegments[(u32) (temp_a0 * 0x10) >> 0x1C] + 0x80000000` is a conversion of a segmented address into a VRAM address. We have a macro for this too: `SEGMENTED_TO_VIRTUAL`. So after all this, the second word is
```C
SEGMENTED_TO_VIRTUAL(D_80A88CFC[this->unk_30E]);
```
and the whole macro is
```C
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_80A88CFC[this->unk_30E]));
```
The contents of a desegmentation macro used like this are almost always textures in this context, so we can replace `UNK_PTR` by `u64*`, the type for textures.
You repeat this for every block in the function.
We also have macros for Graph_OpenDisps and Graph_CloseDisps: you can replace
```C
Graph_OpenDisps(&sp3C, temp_a1, (const char *) "../z_en_jj.c", 0x36F);
```
by
```C
OPEN_DISPS(temp_a1, "../z_en_jj.c", 879);
```
(the last argument is a line number, so should be in decimal).
The function may or may not use a temp for `play->state.gfxCtx`: you have to work it out using the diff.
Once you've replaced all the blocks and the open and close with macros, you proceed with the function as usual.
Two last things: the last argument of the matrix functions tells the compiler whether to use the previously stored matrix or not, so we have the enums `MTXMODE_NEW` and `MTXMODE_APPLY` for these. And the rather weird-looking float `0.076624215f` is, of all things, `(M_PI/41.0f)` (try Wolfram Alpha for these things, and if that doesn't produce anything sensible, ask in Discord).
(The actual reason is probably that the animation is 41 frames long, but you won't necessarily spot this sort of thing for most floats)
After all that, it turns out that
```C
void EnJj_Draw(Actor *thisx, PlayState *play) {
EnJj *this = THIS;
OPEN_DISPS(play->state.gfxCtx, "../z_en_jj.c", 879);
Gfx_SetupDL_37Opa(play->state.gfxCtx);
Matrix_Translate(0.0f, (cosf(this->skelAnime.curFrame * (M_PI/41.0f)) * 10.0f) - 10.0f, 0.0f, 1);
Matrix_Scale(10.0f, 10.0f, 10.0f, 1);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_80A88CFC[this->unk_30E]));
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
this->skelAnime.dListCount, 0, 0, this);
CLOSE_DISPS(play->state.gfxCtx, "../z_en_jj.c", 898);
}
```
matches apart from a couple of stack differences. This can be resolved by giving it `PlayState* play = play2;` at the top of the function and changing the second argument to `play2` as usual.
We have enums for the last argument of the matrix functions: `0` is `MTXMODE_NEW`, `1` is `MTXMODE_APPLY`.
Lastly, the penultimate and antepenultimate arguments of `SkelAnime_DrawFlexOpa` are actually pointers to functions, so they should be `NULL` instead of `0`.
## More examples: OverrideLimbDraw and PostLimbDraw
For more examples of graphics macros and the structure of Draw functions, we look at a function from `EnDntNormal`, which is some Deku Scrubs used in the minigame stuff in Lost Woods. This has a good selection of macros, and two functions that are commonly combined with Draw, namely OverrideLimbDraw and PostLimbDraw.
The mips2c output for
```C
void func_809F5A6C(Actor *thisx, PlayState *play) {
? sp60;
Gfx *sp48;
Gfx *sp38;
Actor *sp14;
Gfx *temp_v0;
Gfx *temp_v0_2;
Gfx *temp_v0_3;
Gfx *temp_v0_4;
Gfx *temp_v0_5;
GraphicsContext *temp_a1;
GraphicsContext *temp_s0;
s32 temp_a0;
void *temp_v1;
sp60.unk0 = (s32) D_809F5E94.unk0;
sp60.unk4 = (s32) D_809F5E94.unk4;
sp60.unk8 = (s32) D_809F5E94.unk8;
temp_a1 = play->state.gfxCtx;
temp_s0 = temp_a1;
Graph_OpenDisps(&sp48, temp_a1, (const char *) "../z_en_dnt_nomal.c", 0x6FE);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
temp_v0 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0 + 8;
temp_v0->words.w0 = 0xDB060020;
temp_a0 = *(&D_809F5EA0 + (thisx->unk268 * 4));
temp_v0->words.w1 = (temp_a0 & 0xFFFFFF) + gSegments[(u32) (temp_a0 * 0x10) >> 0x1C] + 0x80000000;
sp14 = thisx;
SkelAnime_DrawOpa(play, thisx->unk150, thisx->unk16C, &func_809F58E4, &func_809F59E4);
Matrix_Translate(thisx->unk21C, thisx->unk220, (bitwise f32) thisx->unk224, (u8)0U);
Matrix_Scale(0.01f, 0.01f, 0.01f, (u8)1U);
temp_v0_2 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0_2 + 8;
temp_v0_2->words.w0 = 0xE7000000;
temp_v0_2->words.w1 = 0;
temp_v0_3 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0_3 + 8;
temp_v0_3->words.w0 = 0xFB000000;
temp_v1 = (thisx->unk26A * 4) + &D_809F5E4C;
temp_v0_3->words.w1 = (temp_v1->unk-2 << 8) | (temp_v1->unk-4 << 0x18) | (temp_v1->unk-3 << 0x10) | 0xFF;
temp_v0_4 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0_4 + 8;
temp_v0_4->words.w0 = 0xDA380003;
sp38 = temp_v0_4;
sp38->words.w1 = Matrix_NewMtx(play->state.gfxCtx, (char *) "../z_en_dnt_nomal.c", 0x716);
temp_v0_5 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0_5 + 8;
temp_v0_5->words.w1 = (u32) &D_06001B00;
temp_v0_5->words.w0 = 0xDE000000;
Graph_CloseDisps(&sp48, play->state.gfxCtx, (const char *) "../z_en_dnt_nomal.c", 0x719);
if (&func_809F49A4 == thisx->unk214) {
func_80033C30((Vec3f *) &thisx->world, (Vec3f *) &sp60, (u8)0xFFU, play);
}
}
```
### Graphics macros
There are 5 graphics macro blocks here:
```C
temp_v0 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0 + 8;
temp_v0->words.w0 = 0xDB060020;
temp_a0 = *(&D_809F5EA0 + (thisx->unk268 * 4));
temp_v0->words.w1 = (temp_a0 & 0xFFFFFF) + gSegments[(u32) (temp_a0 * 0x10) >> 0x1C] + 0x80000000;
```
We've seen one of these before: gfxdis gives
```C
$ gfxdis.f3dex2 -g "POLY_OPA_DISP++" -d DB06002012345678
gSPSegment(POLY_OPA_DISP++, 0x08, 0x12345678);
```
and looking at the data shows
```
glabel D_809F5EA0
.word 0x060027D0, 0x060025D0, 0x06002750, 0x00000000
```
which is an array of pointers to something again. It is used inside a `SEGMENTED_TO_VIRTUAL`, so they are most likely textures, and this block becomes
```C
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_809F5EA0[this->unk_268]));
```
Next,
```C
temp_v0_2 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0_2 + 8;
temp_v0_2->words.w0 = 0xE7000000;
temp_v0_2->words.w1 = 0;
```
which we can find immediately using
```
$ gfxdis.f3dex2 -g "POLY_OPA_DISP++" -d E700000000000000
gDPPipeSync(POLY_OPA_DISP++);
```
Third,
```C
temp_v0_3 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0_3 + 8;
temp_v0_3->words.w0 = 0xFB000000;
temp_v1 = (thisx->unk26A * 4) + &D_809F5E4C;
temp_v0_3->words.w1 = (temp_v1->unk-2 << 8) | (temp_v1->unk-4 << 0x18) | (temp_v1->unk-3 << 0x10) | 0xFF;
```
this looks more troublesome. We find
```
$ gfxdis.f3dex2 -g "POLY_OPA_DISP++" -d FB00000012345678
gDPSetEnvColor(POLY_OPA_DISP++, 0x12, 0x34, 0x56, 0x78);
```
Now we need to work out what the last four arguments are. Two things are going on here: `D_809F5E4C` is an array of something:
```
glabel D_809F5E4C
.word 0xFFFFFFFF, 0xFFC3AFFF, 0xD2FF00FF, 0xFFFFFFFF, 0xD2FF00FF, 0xFFC3AFFF, 0xFFFFFFFF, 0xFFC3AFFF, 0xD2FF00FF
```
Worse, this is being accessed with pointer subtraction in the second word. `temp_v1 = (thisx->unk26A * 4) + &D_809F5E4C;` tells us that the array has elements of size 4 bytes, and the graphics macro implies the elements are colors. Colors of size 4 bytes are `Color_RGBA8`. Usually, we write colors in decimal, so `D_809F5E4C` becomes
```C
static Color_RGBA8 D_809F5E4C[] = {
{ 255, 255, 255, 255 }, { 255, 195, 175, 255 }, { 210, 255, 0, 255 },
{ 255, 255, 255, 255 }, { 210, 255, 0, 255 }, { 255, 195, 175, 255 },
{ 255, 255, 255, 255 }, { 255, 195, 175, 255 }, { 210, 255, 0, 255 },
};
```
Now, we have two things to worry about: how to implement the negative pointer access, and how the second word is built. Negative accesses can be done by just subtracting 1, so that
```C
temp_v1 = D_809F5E4C[this->unk_26A - 1];
```
and then
```C
temp_v0_3->words.w1 = (temp_v1->unk2 << 8) | (temp_v1->unk0 << 0x18) | (temp_v1->unk3 << 0x10) | 0xFF;
```
or rather, since it is a `Color_RGB8`,
```C
temp_v0_3->words.w1 = (temp_v1.b << 8) | (temp_v1.r << 0x18) | (temp_v1.g << 0x10) | 0xFF;
```
The last thing to worry about is how to put this word into the macro. Let's think about what the word actually is in a concrete case; it is easiest to see what is going on in hex, so suppose we are in the case
```C
temp_v1 = { 0xFF, 0xC3, 0xAF, 0xFF };
```
Then the calculation is
```
(0xAF << 8) | (0xFF << 0x18) | (0xC3 << 0x10) | 0xFF = 0xAF00 | 0xC30000 | 0xFF0000000 | 0xFF = 0xFFC3AFFF
```
and so all this calculation is doing is turning `temp_v1` back into a word, with the last byte replaced by `0xFF` (that all the elements of `D_809F5E4C` have `0xFF` as their last element anyway is irrelevant here). Looking back at the output of gfxdis, we see that this actually means that the r,g,b just slot into the penultimate three arguments, the last being `0xFF`, leaving
```C
temp_v1 = D_809F5E4C[this->unk_26A - 1];
gDPSetEnvColor(POLY_OPA_DISP++, temp_v1.r, temp_v1.g, temp_v1.b, 0xFF);
```
as the residue of this block; it may turn out later that we can eliminate the temp.
The last two are much easier:
```C
temp_v0_4 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0_4 + 8;
temp_v0_4->words.w0 = 0xDA380003;
sp38 = temp_v0_4;
sp38->words.w1 = Matrix_NewMtx(play->state.gfxCtx, (char *) "../z_en_dnt_nomal.c", 0x716);
```
The macro is
```
$ gfxdis.f3dex2 -g "POLY_OPA_DISP++" -d DA38000312345678
gSPMatrix(POLY_OPA_DISP++, 0x12345678, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
```
and the second argument is filled by the `Matrix_NewMtx` function:
```C
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_en_dnt_nomal.c", 1814), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
```
Lastly,
```C
temp_v0_5 = temp_s0->polyOpa.p;
temp_s0->polyOpa.p = temp_v0_5 + 8;
temp_v0_5->words.w1 = (u32) &D_06001B00;
temp_v0_5->words.w0 = 0xDE000000;
```
The macro is
```
$ gfxdis.f3dex2 -g "POLY_OPA_DISP++" -d DE00000012345678
gSPDisplayList(POLY_OPA_DISP++, 0x12345678);
```
and so `D_06001B00` is a displaylist, so the type in the externed data at the top of the file can be changed to `Gfx D_06001B00[]`. Arrays act like pointers, so we don't need the `&` in the macro:
```C
gSPDisplayList(POLY_OPA_DISP++, D_06001B00);
```
Putting this all together
```C
void func_809F5A6C(Actor *thisx, PlayState *play) {
EnDntNormal *this = THIS;
? sp60;
Actor *sp14;
Color_RGBA8 temp_v1;
sp60.unk0 = (s32) D_809F5E94.unk0;
sp60.unk4 = (s32) D_809F5E94.unk4;
sp60.unk8 = (s32) D_809F5E94.unk8;
OPEN_DISPS(play->state.gfxCtx, "../z_en_dnt_nomal.c", 1790);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_809F5EA0[this->unk_268]));
sp14 = this;
SkelAnime_DrawOpa(play, thisx->unk150, thisx->unk16C, &func_809F58E4, &func_809F59E4);
Matrix_Translate(thisx->unk21C, thisx->unk220, (bitwise f32) thisx->unk224, (u8)0U);
Matrix_Scale(0.01f, 0.01f, 0.01f, (u8)1U);
gDPPipeSync(POLY_OPA_DISP++);
temp_v1 = D_809F5E4C[this->unk_26A - 1];
gDPSetEnvColor(POLY_OPA_DISP++, temp_v1.r, temp_v1.g, temp_v1.r, 0xFF);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, "../z_en_dnt_nomal.c", 1814), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, D_06001B00);
CLOSE_DISPS(play->state.gfxCtx, "../z_en_dnt_nomal.c", 1817);
if (&func_809F49A4 == this->unk214) {
func_80033C30((Vec3f *) &this.actor->world, (Vec3f *) &sp60, (u8)0xFFU, play);
}
}
```
### SkelAnime_Draw and the LimbDraws
Some more general tidying up can be done here (`sp60` and so `D_809F5E94` are `Vec3f`, for example, and under normal circumstances we'd know that ), but the big remaining issue is
```C
sp14 = this;
SkelAnime_DrawOpa(play, thisx->unk150, thisx->unk16C, func_809F58E4, func_809F59E4);
```
If we look at the definition of `SkelAnime_DrawOpa`, we find that it's missing the last argument. This is mips2c not noticing why `this` has been put on the stack: this code should actually be
```C
SkelAnime_DrawOpa(play, thisx->unk150, thisx->unk16C, func_809F58E4, func_809F59E4, this);
```
mips2c doing this is not especially unusual, so bear it in mind.
The other thing this tells us is that `func_809F58E4` is of type `OverrideLimbDraw`, and `func_809F59E4` of type `PostLimbDraw`. Their names are fairly self-explanatory. Filling in the prototypes as
```C
s32 func_809F58E4(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx);
void func_809F59E4(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx);
```
and running mips2c gives
```C
s32 func_809F58E4(PlayState *play, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, void *thisx) {
GraphicsContext *sp38;
Gfx *sp28;
Gfx *temp_v1;
Gfx *temp_v1_2;
GraphicsContext *temp_a1;
void *temp_v0;
if ((limbIndex == 1) || (limbIndex == 3) || (limbIndex == 4) || (limbIndex == 5) || (limbIndex == 6)) {
temp_a1 = play->state.gfxCtx;
sp38 = temp_a1;
Graph_OpenDisps(&sp28, temp_a1, (const char *) "../z_en_dnt_nomal.c", 0x6C5);
temp_v1 = sp38->polyOpa.p;
sp38->polyOpa.p = temp_v1 + 8;
temp_v1->words.w1 = 0;
temp_v1->words.w0 = 0xE7000000;
temp_v1_2 = sp38->polyOpa.p;
sp38->polyOpa.p = temp_v1_2 + 8;
temp_v1_2->words.w0 = 0xFB000000;
temp_v0 = (thisx->unk26A * 4) + &D_809F5E4C;
temp_v1_2->words.w1 = (temp_v0->unk-2 << 8) | (temp_v0->unk-4 << 0x18) | (temp_v0->unk-3 << 0x10) | 0xFF;
Graph_CloseDisps(&sp28, play->state.gfxCtx, (const char *) "../z_en_dnt_nomal.c", 0x6CF);
}
return 0;
}
void func_809F59E4(PlayState *play, s32 limbIndex, Gfx **dList, Vec3s *rot, void *thisx) {
? sp18;
sp18.unk0 = (s32) D_809F5E88.unk0;
sp18.unk4 = (s32) D_809F5E88.unk4;
sp18.unk8 = (s32) D_809F5E88.unk8;
if (thisx->unk26A == 0) {
if (limbIndex == 5) {
Matrix_MultVec3f((Vec3f *) &sp18, thisx + 0x27C);
return;
}
} else if (limbIndex == 7) {
Matrix_MultVec3f((Vec3f *) &sp18, thisx + 0x27C);
}
}
```
This structure is pretty typical: both edit what certain limbs do. Both also usually need a `ActorName *this = THIS;` at the top. We have seen both of the macros in the former before: applying the usual procedure, we find that it becomes
```C
s32 func_809F58E4(PlayState *play, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, void *thisx) {
EnDntNormal *this = THIS;
if ((limbIndex == 1) || (limbIndex == 3) || (limbIndex == 4) || (limbIndex == 5) || (limbIndex == 6)) {
OPEN_DISPS(play->state.gfxCtx, "../z_en_dnt_nomal.c", 1733);
gDPPipeSync(POLY_OPA_DISP++);
gDPSetEnvColor(POLY_OPA_DISP++, D_809F5E4C[this->type - 1].r, D_809F5E4C[this->type - 1].g, D_809F5E4C[this->type - 1].b, 255);
CLOSE_DISPS(play->state.gfxCtx, "../z_en_dnt_nomal.c", 1743);
}
return 0;
}
```
Notice that this function returns `0`. OverrideLimbDraw almost always returns `0`.
The latter function is easier, and it is probably unnecessary to explain to the reader what it is necessary to do to it to clean it up.

View file

@ -1,202 +0,0 @@
# List of helper scripts
This list gives brief information on the most common usage cases. For more information, first try using `-h` or `--help` as an argument, and failing that, ask in #oot-decomp-help or #tools-other in the Discord.
Many tools require activating a Python virtual environment that contains Python
dependencies. This virtual environment is automatically installed into the
`.venv` directory by `make setup`, but you need to **activate** it in your
current terminal session in order to run Python tools. To start using the
virtual environment in your current terminal run:
```bash
source .venv/bin/activate
```
Keep in mind that for each new terminal session, you will need to activate the
Python virtual environment again. That is, run the above `source .venv/bin/activate` command.
To deactivate the virtual environment, run
```bash
deactivate
```
and your terminal session state will be restored to what it was before.
## m2ctx
This generates the context for mips2c to use to type objects in its output. It lives in the tools directory. Running
```sh
./tools/m2ctx.py <path_to_c>
```
will produce a file in the root directory called `ctx.c`. You open this file and copy it into the mips2c context box.
The rule of thumb is to rerun this every time you change something significant to other functions, like the struct in the header or a function prototype, and probably after every function, at least at first. As with most other things on this project, you will develop intuition for when this is required.
## diff
This is in the repo's root directory. It is the main comparison tool to check your C code generates the right MIPS.
The usual way diff is used is
```sh
./diff.py -mwo3 <function_name>
```
- `m` automatically runs make as necessary
- `o` allows using symbol names
- `w` refreshes the diff output when the c file is saved (only the c file, not the header)
- `3` allows comparison of the previous and current saves of the file.
Many other options exist, use the `-h` to see them.
In order to use `diff.py` with the symbol names (with `o`), we need a copy of the code to compare against. This is done by copying the `build` folder into a folder called `expected`. Copying in Windows on WSL is very slow, so run
```sh
mkdir expected
cp -r build/ expected/
```
from the main directory of the repository. You should end up with the folder structure `expected/build/...`.
![Example of a diff](images/func_80A87B9C_diff1.png)
The colors have the following meanings:
- Red is lines missing
- Green is extra lines
- Blue denotes significant differences in instructions, be they just numerical ones, or whole instructions
- Yellow/Gold denotes that register usage is wrong
- Other colors are used to distinguish incorrectly used registers or stack variables, to make it easy to follow where they are used.
## decomp-permuter
This is linked in #resources in the Discord.
For inspiration when you run out of ideas to match a function. It is unlikely to match it completely by itself, but if you can't see from the MIPS or your code where you have issues, it will often tell you where to start looking.
First, import the C file and MIPS of the function to compare using
```sh
./import.py <path_to_c> <path_to_func_name.s>
```
It will put it in a subdirectory of `nonmatchings`. You then run
```sh
./permuter.py nonmatchings/<function_name>/
```
to produce suggestions. There are various arguments that can be used, of which the most important initially is `-j`: `-jN` tells it to use `N` CPU threads.
Suggestions are saved in the function directory it imported the function into.
## first_diff
Tells you where your built rom first differs from the baserom. It gives you a memory address that you can use to do, e.g. a binary diff, and also tries too find what function or data this address is in. Run with
```C
./first_diff.py
```
If the rom is shifted, the first problem will be in gDMADataTable. Ignore this and look at the next one for where you actually need to look to see what's happened. The last line makes a guess on this location you need to edit to fix the problem.
## sym_info
Gives information about a `D_address` symbol (ROM address, RAM address, file). Run
```C
./sym_info.py <D_number>
```
## ichaindis
This is used to convert the data associated to the `D_address` in
```C
Actor_ProcessInitChain(&this->actor, &D_address);
```
into an InitChain. It lives in the tools directory. Run
```sh
./tools/ichaindis.py <path_to_baserom> <D_address>
```
and copy the output. (This used to only take the ROM address, which you would need to get from `sym_info.py`. Now you can just give it the RAM address, or even the raw `D_address`.)
## colliderinit
This is used to convert data `D_address` in the various ColliderInit functions into the format of a collider. It lives in `tools/overlayhelpers`. Because there are different types of collider, you need to give it the type of collider as well. This does not need the baserom path, and a recent update allows it to be run from anywhere. You also have to give it the `<address>` without the leading `D_`.
```sh
./colliderinit.py <address> <type> <num>
```
Collider types supported are
- `ColliderJntSphInit`
- `ColliderCylinderInit`
- `ColliderTrisInit`
- `ColliderQuadInit`
- `ColliderJntSphElementInit`
- `ColliderTrisElementInit`
and `num` is used only for `ColliderJntSphElementInit`.
## sfxconvert
Automatically converts sound effect numbers in a file into their corresponding `#defines`, taking into account if `SFX_FLAG` is used. Run on a specific C file,
```sh
./tools/sfxconvert.py <path_to_file> <path_to_repo>
```
Optional arguments are `-o output` to output to a different file and `-v` to give verbose output (i.e. tell you what changes it has made).
## vt_fmt
This turns the strange strings in the `PRINTF`s into the human-readable equivalent instructions. Copy the contents, including the quotation marks, and run
```sh
./tools/vt_fmt.py "contents"
```
and replace the contents of the printf with the output.
## Glank's N64 tools
In particular, the ones used to decompile graphics macros. Their use is discussed in the section on [decompiling Draw functions](draw_functions.md).
## graphovl
This generates a directed graph showing an actor's function. Search for `graphovl.py` in the Discord. Put it in the root directory of the project, and run
```sh
./graphovl.py Actor_Name
```
to produce a png in the `graphs` subdirectory.
## format
Shell script that does a standardised format to the C code. Can be run on a file, a directory, or the whole codebase. Run this before you submit a PR.
## find_unused_asm
Tracks down any `.s` files no longer used by the project. Does not ignore comments, so you have to actually remove any `#pragma` lines for it to consider the file unused.
```sh
./tools/find_unused_asm.sh
```
will output a list of all such files, while adding `-d` deletes the files.
## csdis
This converts the cutscene data into macros that the cutscene system uses. Cutscenes are generally very long, so I recommend sending the output straight to a file with `>`, rather than trying to copy it all from the terminal. Run
```sh
./tools/csdis.py <address>
```
on the address from the `D_address` containing the cutscene data.
## regconvert
This converts the direct memory references, of the form `gRegEditor->data[index]` or `gRegEditor + 0x<offset>`, into the corresponding REG macros defined in [regs.h](../include/regs.h). Run
```sh
./tools/regconvert.py <index>
```
if you have it in the form `gRegEditor->data[index]`, or
```sh
./tools/regconvert.py --offset <offset>
```
if you have it in the form `gRegEditor + 0x<offset>`. You can also run it on a whole file using `--file <path/to/file>`.
## assist
This takes a function name, and looks for functions with very similar assembly code. It outputs the best matches, and tells you if there is a decompiled one.
```sh
./tools/assist.py <function_name>
```
It has two optional arguments:
- `--threshold` adjust how high the matching threshold is, 1.0 being highest, 0.0 lowest
- `--num-out` change the number of matches to output

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

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