Browse Source

init2

master
n64 2 years ago
commit
89e8690857
  1. 15
      .clang-format
  2. 72
      .gitignore
  3. 2482
      Doxyfile
  4. 45
      Jenkinsfile
  5. 466
      Makefile
  6. 293
      Makefile.split
  7. 82
      README.md
  8. 2
      actors/amp/collision.s
  9. 54
      actors/amp/geo.s
  10. 503
      actors/amp/model.s
  11. 2
      actors/bird/collision.s
  12. 23
      actors/bird/geo.s
  13. 254
      actors/bird/model.s
  14. 2
      actors/blargg/collision.s
  15. 18
      actors/blargg/geo.s
  16. 545
      actors/blargg/model.s
  17. 27
      actors/blue_coin_switch/collision.s
  18. 8
      actors/blue_coin_switch/geo.s
  19. 79
      actors/blue_coin_switch/model.s
  20. 2
      actors/blue_fish/collision.s
  21. 28
      actors/blue_fish/geo.s
  22. 137
      actors/blue_fish/model.s
  23. 2
      actors/bobomb/collision.s
  24. 95
      actors/bobomb/geo.s
  25. 393
      actors/bobomb/model.s
  26. 2
      actors/bomb/collision.s
  27. 13
      actors/bomb/geo.s
  28. 186
      actors/bomb/model.s
  29. 2
      actors/boo/collision.s
  30. 15
      actors/boo/geo.s
  31. 319
      actors/boo/model.s
  32. 2
      actors/boo_castle/collision.s
  33. 15
      actors/boo_castle/geo.s
  34. 319
      actors/boo_castle/model.s
  35. 2
      actors/book/collision.s
  36. 6
      actors/book/geo.s
  37. 83
      actors/book/model.s
  38. 2
      actors/bookend/collision.s
  39. 27
      actors/bookend/geo.s
  40. 455
      actors/bookend/model.s
  41. 2
      actors/bowling_ball/collision.s
  42. 23
      actors/bowling_ball/geo.s
  43. 5
      actors/bowling_ball/model.s
  44. 2
      actors/bowser/collision.s
  45. 411
      actors/bowser/geo.s
  46. 9294
      actors/bowser/model.s
  47. 2
      actors/bowser_flame/collision.s
  48. 22
      actors/bowser_flame/geo.s
  49. 386
      actors/bowser_flame/model.s
  50. 2
      actors/bowser_key/collision.s
  51. 27
      actors/bowser_key/geo.s
  52. 521
      actors/bowser_key/model.s
  53. 32
      actors/breakable_box/collision.s
  54. 24
      actors/breakable_box/geo.s
  55. 87
      actors/breakable_box/model.s
  56. 2
      actors/bub/collision.s
  57. 20
      actors/bub/geo.s
  58. 417
      actors/bub/model.s
  59. 2
      actors/bubba/collision.s
  60. 10
      actors/bubba/geo.s
  61. 531
      actors/bubba/model.s
  62. 2
      actors/bubble/collision.s
  63. 13
      actors/bubble/geo.s
  64. 47
      actors/bubble/model.s
  65. 2
      actors/bullet_bill/collision.s
  66. 9
      actors/bullet_bill/geo.s
  67. 306
      actors/bullet_bill/model.s
  68. 2
      actors/bully/collision.s
  69. 87
      actors/bully/geo.s
  70. 688
      actors/bully/model.s
  71. 2
      actors/burn_smoke/collision.s
  72. 6
      actors/burn_smoke/geo.s
  73. 45
      actors/burn_smoke/model.s
  74. 2
      actors/butterfly/collision.s
  75. 24
      actors/butterfly/geo.s
  76. 117
      actors/butterfly/model.s
  77. 2
      actors/cannon_barrel/collision.s
  78. 6
      actors/cannon_barrel/geo.s
  79. 144
      actors/cannon_barrel/model.s
  80. 2
      actors/cannon_base/collision.s
  81. 6
      actors/cannon_base/geo.s
  82. 157
      actors/cannon_base/model.s
  83. 15
      actors/cannon_lid/collision.s
  84. 3
      actors/cannon_lid/geo.s
  85. 44
      actors/cannon_lid/model.s
  86. 53
      actors/capswitch/collision.s
  87. 13
      actors/capswitch/geo.s
  88. 218
      actors/capswitch/model.s
  89. 2
      actors/chain_ball/collision.s
  90. 6
      actors/chain_ball/geo.s
  91. 33
      actors/chain_ball/model.s
  92. 2
      actors/chain_chomp/collision.s
  93. 20
      actors/chain_chomp/geo.s
  94. 530
      actors/chain_chomp/model.s
  95. 2
      actors/chair/collision.s
  96. 27
      actors/chair/geo.s
  97. 315
      actors/chair/model.s
  98. 29
      actors/checkerboard_platform/collision.s
  99. 6
      actors/checkerboard_platform/geo.s
  100. 85
      actors/checkerboard_platform/model.s

15
.clang-format

@ -0,0 +1,15 @@
IndentWidth: 4
AlignAfterOpenBracket: Align
SortIncludes: false
ColumnLimit: 104
PointerAlignment: Right
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
BinPackArguments: true
BinPackParameters: true
SpaceAfterCStyleCast: true
BreakBeforeTernaryOperators: true
BreakBeforeBinaryOperators: NonAssignment
Cpp11BracedListStyle: false
IndentCaseLabels: true
AlignTrailingComments: true

72
.gitignore

@ -0,0 +1,72 @@
# Object files
*.o
*.obj
*.elf
# Linker output
*.ilk
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# datadump
/tools/ddump/*
# Text editor remnants
*.swp
.vscode/*
# General project-specific ignores
doxygen/doxygen/*
build/*
*.dump
*.mio0
*.z64
*.map
.assets-local.txt
# Assets. Generally ignored, but ones with "custom" in the name are fine.
/levels/**/*.png
/actors/**/*.png
/textures/**/*.png
/assets/**/*.bin
/sound/**/*.m64
/sound/**/*.aiff
!/levels/**/*custom*.png
!/levels/**/*custom*/**/*.png
!/actors/**/*custom*.png
!/actors/**/*custom*/**/*.png
!/textures/**/*custom*.png
!/textures/**/*custom*/**/*.png
!/sound/**/*custom*.m64
!/sound/**/*custom*/**/*.m64
!/sound/**/*custom*.aiff
!/sound/**/*custom*/**/*.aiff
!/assets/**/*custom*.bin
!/assets/**/*custom*/**/*.bin

2482
Doxyfile

File diff suppressed because it is too large

45
Jenkinsfile

@ -0,0 +1,45 @@
pipeline {
agent any
stages {
stage('Build Tools') {
steps {
sh 'make -j4 -C tools/'
}
}
stage('Extract Assets') {
steps {
sh 'ln -s "$ROMS_DIR/Super Mario 64 (J) [!].z64" baserom.jp.z64'
sh 'ln -s "$ROMS_DIR/Super Mario 64 (U) [!].z64" baserom.us.z64'
sh 'ln -s "$ROMS_DIR/Super Mario 64 (E) (M3) [!].z64" baserom.eu.z64'
// verify no assets were committed to repo
sh '[ -z "$(find {actors,levels,textures}/ -name \'*.png\')" ]'
sh '[ -z "$(find assets/ -name \'*.m64\' -or \'*.bin\')" ]'
sh './extract_assets.py jp us eu'
}
}
stage('Build J Source') {
steps {
sh 'make -j4 VERSION=jp'
}
}
stage('Build U Source') {
steps {
sh 'make -j4 VERSION=us'
}
}
stage('Build J Source, NON_MATCHING') {
steps {
sh 'make -j4 VERSION=jp NON_MATCHING=1'
}
}
stage('Build U Source, NON_MATCHING') {
steps {
sh 'make -j4 VERSION=us NON_MATCHING=1'
}
}
}
environment {
QEMU_IRIX = credentials('qemu-irix')
ROMS_DIR = credentials('roms')
}
}

466
Makefile

@ -0,0 +1,466 @@
# Makefile to rebuild SM64 split image
### Default target ###
default: all
### Build Options ###
# Version of the game to build
VERSION ?= us
# Graphics microcode used
GRUCODE ?= f3d_old
# If COMPARE is 1, check the output sha1sum when building 'all'
COMPARE ?= 1
# If NON_MATCHING is 1, define the NON_MATCHING macro when building
NON_MATCHING ?= 0
# If ENDIAN_IND is 1, enable non-matching code changes that try to ensure
# endianness independence
ENDIAN_IND ?= 0
# Release
ifeq ($(VERSION),jp)
VERSION_CFLAGS := -DVERSION_JP=1
VERSION_ASFLAGS := --defsym VERSION_JP=1
GRUCODE_CFLAGS := -DF3D_OLD
GRUCODE_ASFLAGS := --defsym F3D_OLD=1
TARGET := sm64.jp
else
ifeq ($(VERSION),us)
VERSION_CFLAGS := -DVERSION_US=1
VERSION_ASFLAGS := --defsym VERSION_US=1
GRUCODE_CFLAGS := -DF3D_OLD
GRUCODE_ASFLAGS := --defsym F3D_OLD=1
TARGET := sm64.us
else
ifeq ($(VERSION),eu)
$(warning Building EU is experimental and is prone to breaking. Try at your own risk.)
VERSION_CFLAGS := -DVERSION_EU=1
VERSION_ASFLAGS := --defsym VERSION_EU=1
GRUCODE_CFLAGS := -DF3D_NEW
GRUCODE_ASFLAGS := --defsym F3D_NEW=1
TARGET := sm64.eu
else
$(error unknown version "$(VERSION)")
endif
endif
endif
# Microcode
ifeq ($(GRUCODE),f3dex) # Fast3DEX
GRUCODE_CFLAGS := -DF3DEX_GBI=1
GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1 --defsym F3DEX_GBI=1
TARGET := $(TARGET).f3dex
COMPARE := 0
else
ifeq ($(GRUCODE), f3dex2) # Fast3DEX2
GRUCODE_CFLAGS := -DF3DEX_GBI_2=1
GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1 --defsym F3DEX_GBI_2=1
TARGET := $(TARGET).f3dex2
COMPARE := 0
else
ifeq ($(GRUCODE),f3d_new) # Fast3D 2.0H (Shindou)
GRUCODE_CFLAGS := -DF3D_NEW
GRUCODE_ASFLAGS := --defsym F3D_NEW=1
TARGET := $(TARGET).f3d_new
COMPARE := 0
else
ifeq ($(GRUCODE),f3dzex) # Fast3DZEX (2.0J / Animal Forest - Dōbutsu no Mori)
$(warning Fast3DZEX is experimental. Try at your own risk.)
GRUCODE_CFLAGS := -DF3DEX_GBI_2=1
GRUCODE_ASFLAGS := --defsym F3DEX_GBI_SHARED=1 --defsym F3DZEX_GBI=1
TARGET := $(TARGET).f3dzex
COMPARE := 0
endif
endif
endif
endif
ifeq ($(NON_MATCHING),1)
VERSION_CFLAGS := $(VERSION_CFLAGS) -DNON_MATCHING=1
COMPARE := 0
endif
ifeq ($(ENDIAN_IND),1)
VERSION_CFLAGS := $(VERSION_CFLAGS) -DENDIAN_IND=1
COMPARE := 0
endif
################### Universal Dependencies ###################
# (This is a bit hacky, but a lot of rules implicitly depend
# on tools and assets, and we use directory globs further down
# in the makefile that we want should cover assets.)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),distclean)
# Make sure assets exist
NOEXTRACT ?= 0
ifeq ($(NOEXTRACT),0)
DUMMY != ./extract_assets.py $(VERSION) >&2 || echo FAIL
ifeq ($(DUMMY),FAIL)
$(error Failed to extract assets)
endif
endif
# Make tools if out of date
DUMMY != make -s -C tools >&2 || echo FAIL
ifeq ($(DUMMY),FAIL)
$(error Failed to build tools)
endif
endif
endif
################ Target Executable and Sources ###############
# BUILD_DIR is location where all build artifacts are placed
BUILD_DIR_BASE := build
BUILD_DIR := $(BUILD_DIR_BASE)/$(VERSION)
LIBULTRA := $(BUILD_DIR)/libultra.a
ROM := $(BUILD_DIR)/$(TARGET).z64
ELF := $(BUILD_DIR)/$(TARGET).elf
LD_SCRIPT := sm64.ld
MIO0_DIR := $(BUILD_DIR)/mio0
SOUND_BIN_DIR := $(BUILD_DIR)/sound
TEXTURE_DIR := textures
ACTOR_DIR := actors
# Directories containing source files
SRC_DIRS := src src/engine src/game src/audio
ASM_DIRS := asm actors lib data levels assets sound text
BIN_DIRS := bin bin/$(VERSION)
ULTRA_SRC_DIRS := lib/src lib/src/math
ULTRA_ASM_DIRS := lib/asm lib/data
ULTRA_BIN_DIRS := lib/bin
GODDARD_SRC_DIRS := src/goddard src/goddard/dynlists
LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.s)))
MIPSISET := -mips2 -32
ifeq ($(VERSION),eu)
OPT_FLAGS := -O2
else
OPT_FLAGS := -g
endif
# File dependencies and variables for specific files
include Makefile.split
# Source code files
C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c))
S_FILES := $(foreach dir,$(ASM_DIRS),$(wildcard $(dir)/*.s))
ULTRA_C_FILES := $(foreach dir,$(ULTRA_SRC_DIRS),$(wildcard $(dir)/*.c))
GODDARD_C_FILES := $(foreach dir,$(GODDARD_SRC_DIRS),$(wildcard $(dir)/*.c))
ULTRA_S_FILES := $(foreach dir,$(ULTRA_ASM_DIRS),$(wildcard $(dir)/*.s))
LEVEL_S_FILES := $(addsuffix header.s,$(addprefix bin/,$(LEVEL_DIRS)))
SOUND_BANK_FILES := $(wildcard sound/sound_banks/*.json)
SOUND_SEQUENCE_FILES := $(wildcard sound/sequences/$(VERSION)/*.m64) \
$(wildcard sound/sequences/*.m64) \
$(foreach file,$(wildcard sound/sequences/$(VERSION)/*.s),$(BUILD_DIR)/$(file:.s=.m64)) \
$(foreach file,$(wildcard sound/sequences/*.s),$(BUILD_DIR)/$(file:.s=.m64))
SOUND_SAMPLE_DIRS := $(wildcard sound/samples/*)
SOUND_SAMPLE_AIFFS := $(foreach dir,$(SOUND_SAMPLE_DIRS),$(wildcard $(dir)/*.aiff))
SOUND_SAMPLE_TABLES := $(foreach file,$(SOUND_SAMPLE_AIFFS),$(BUILD_DIR)/$(file:.aiff=.table))
SOUND_SAMPLE_AIFCS := $(foreach file,$(SOUND_SAMPLE_AIFFS),$(BUILD_DIR)/$(file:.aiff=.aifc))
SOUND_OBJ_FILES := $(SOUND_BIN_DIR)/sound_data.ctl.o \
$(SOUND_BIN_DIR)/sound_data.tbl.o \
$(SOUND_BIN_DIR)/sequences.bin.o
# Object files
O_FILES := $(foreach file,$(C_FILES),$(BUILD_DIR)/$(file:.c=.o)) \
$(foreach file,$(S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \
$(foreach file,$(LEVEL_S_FILES),$(BUILD_DIR)/$(file:.s=.o))
ULTRA_O_FILES := $(foreach file,$(ULTRA_S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \
$(foreach file,$(ULTRA_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
GODDARD_O_FILES := $(foreach file,$(GODDARD_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
# Automatic dependency files
DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d) $(GODDARD_O_FILES:.o=.d) $(BUILD_DIR)/$(LD_SCRIPT).d
# Files with NON_MATCHING ifdefs
NON_MATCHING_C_FILES != grep -rl NON_MATCHING $(wildcard src/audio/*.c) $(wildcard src/game/*.c)
NON_MATCHING_O_FILES = $(foreach file,$(NON_MATCHING_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
NON_MATCHING_DEP = $(BUILD_DIR)/src/audio/non_matching_dep
# Segment elf files
SEG_FILES := $(SEGMENT_ELF_FILES) $(ACTOR_ELF_FILES) $(LEVEL_ELF_FILES)
##################### Compiler Options #######################
IRIX_ROOT := tools/ido5.3_compiler
ifeq ($(shell type mips-linux-gnu-ld >/dev/null 2>/dev/null; echo $$?), 0)
CROSS := mips-linux-gnu-
else
CROSS := mips64-elf-
endif
AS := $(CROSS)as
CC := $(QEMU_IRIX) -silent -L $(IRIX_ROOT) $(IRIX_ROOT)/usr/bin/cc
CPP := cpp -P
LD := $(CROSS)ld
AR := $(CROSS)ar
OBJDUMP := $(CROSS)objdump
OBJCOPY := $(CROSS)objcopy
PYTHON := python3
# Check code syntax with host compiler
CC_CHECK := gcc -fsyntax-only -fsigned-char -nostdinc -fno-builtin -I include -I $(BUILD_DIR)/include -I src -std=gnu90 -Wall -Wextra -Wno-format-security -D_LANGUAGE_C $(VERSION_CFLAGS) $(GRUCODE_CFLAGS)
ASFLAGS := -march=vr4300 -mabi=32 -I include -I $(BUILD_DIR) $(VERSION_ASFLAGS) $(GRUCODE_ASFLAGS)
CFLAGS = -Wab,-r4300_mul -non_shared -G 0 -Xcpluscomm -Xfullwarn $(OPT_FLAGS) -signed -I include -I $(BUILD_DIR)/include -I src -D_LANGUAGE_C $(VERSION_CFLAGS) $(MIPSISET) $(GRUCODE_CFLAGS)
OBJCOPYFLAGS := --pad-to=0x800000 --gap-fill=0xFF
SYMBOL_LINKING_FLAGS := $(addprefix -R ,$(SEG_FILES))
LDFLAGS := -T undefined_syms.txt -T $(BUILD_DIR)/$(LD_SCRIPT) -Map $(BUILD_DIR)/sm64.map --no-check-sections $(SYMBOL_LINKING_FLAGS)
ifeq ($(shell getconf LONG_BIT), 32)
# Work around memory allocation bug in QEMU
export QEMU_GUEST_BASE := 1
else
# Ensure that gcc treats the code as 32-bit
CC_CHECK += -m32
endif
####################### Other Tools #########################
# N64 tools
TOOLS_DIR = tools
MIO0TOOL = $(TOOLS_DIR)/mio0
N64CKSUM = $(TOOLS_DIR)/n64cksum
N64GRAPHICS = $(TOOLS_DIR)/n64graphics
N64GRAPHICS_CI = $(TOOLS_DIR)/n64graphics_ci
TEXTCONV = $(TOOLS_DIR)/textconv
IPLFONTUTIL = $(TOOLS_DIR)/iplfontutil
AIFF_EXTRACT_CODEBOOK = $(TOOLS_DIR)/aiff_extract_codebook
VADPCM_ENC = $(TOOLS_DIR)/vadpcm_enc
EMULATOR = mupen64plus
EMU_FLAGS = --noosd
LOADER = loader64
LOADER_FLAGS = -vwf
SHA1SUM = sha1sum
###################### Dependency Check #####################
BINUTILS_VER_MAJOR := $(shell $(LD) --version | grep ^GNU | sed 's/^.* //; s/\..*//g')
BINUTILS_VER_MINOR := $(shell $(LD) --version | grep ^GNU | sed 's/^[^.]*\.//; s/\..*//g')
BINUTILS_DEPEND := $(shell expr $(BINUTILS_VER_MAJOR) \>= 2 \& $(BINUTILS_VER_MINOR) \>= 27)
ifeq ($(BINUTILS_DEPEND),0)
$(error binutils version 2.27 required, version $(BINUTILS_VER_MAJOR).$(BINUTILS_VER_MINOR) detected)
endif
ifndef QEMU_IRIX
$(error env variable QEMU_IRIX should point to the qemu-mips binary)
endif
######################## Targets #############################
all: $(ROM)
ifeq ($(COMPARE),1)
@$(SHA1SUM) -c $(TARGET).sha1
endif
clean:
$(RM) -r $(BUILD_DIR_BASE)
distclean:
$(RM) -r $(BUILD_DIR_BASE)
./extract_assets.py --clean
test: $(ROM)
$(EMULATOR) $(EMU_FLAGS) $<
load: $(ROM)
$(LOADER) $(LOADER_FLAGS) $<
libultra: $(BUILD_DIR)/libultra.a
asm/boot.s: $(BUILD_DIR)/lib/bin/ipl3_font.bin
$(BUILD_DIR)/lib/bin/ipl3_font.bin: lib/ipl3_font.png | $(BUILD_DIR)
$(IPLFONTUTIL) e $< $@
$(BUILD_DIR)/include/text_strings.h: include/text_strings.h.in | $(BUILD_DIR)
$(TEXTCONV) charmap.txt $< $@
$(BUILD_DIR)/text/%.s: text/$(VERSION)/%.s.in | $(BUILD_DIR)
$(TEXTCONV) charmap.txt $< $@
ifeq ($(VERSION),eu)
ASM_DIRS += text/de text/en text/fr
# EU encoded text inserted into individual segment 0x19 files
$(BUILD_DIR)/bin/$(VERSION)/translation_de.o: $(BUILD_DIR)/text/de/dialog.s $(BUILD_DIR)/text/de/level.s $(BUILD_DIR)/text/de/star.s
$(BUILD_DIR)/bin/$(VERSION)/translation_en.o: $(BUILD_DIR)/text/en/dialog.s $(BUILD_DIR)/text/en/level.s $(BUILD_DIR)/text/en/star.s
$(BUILD_DIR)/bin/$(VERSION)/translation_fr.o: $(BUILD_DIR)/text/fr/dialog.s $(BUILD_DIR)/text/fr/level.s $(BUILD_DIR)/text/fr/star.s
else
# non-EU encoded text inserted into segment 0x02
$(BUILD_DIR)/bin/segment2.o: $(BUILD_DIR)/text/debug.s $(BUILD_DIR)/text/dialog.s $(BUILD_DIR)/text/level.s $(BUILD_DIR)/text/star.s
endif
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) $(addprefix bin/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(LEVEL_DIRS)) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION)
# Make sure build directory exists before compiling anything
DUMMY != mkdir -p $(ALL_DIRS)
$(BUILD_DIR)/src/game/star_select.o: $(BUILD_DIR)/include/text_strings.h
$(BUILD_DIR)/src/game/file_select.o: $(BUILD_DIR)/include/text_strings.h
$(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h
################################################################
# TEXTURE GENERATION #
################################################################
# RGBA32, RGBA16, IA16, IA8, IA4, IA1, I8, I4
$(BUILD_DIR)/%: %.png
$(N64GRAPHICS) -i $@ -g $< -f $(lastword $(subst ., ,$@))
# Color Index CI8
$(BUILD_DIR)/%.ci8: %.ci8.png
$(N64GRAPHICS_CI) -i $@ -g $< -f ci8
# Color Index CI4
$(BUILD_DIR)/%.ci4: %.ci4.png
$(N64GRAPHICS_CI) -i $@ -g $< -f ci4
################################################################
# compressed segment generation
$(BUILD_DIR)/bin/%.o: bin/%.s
$(AS) $(ASFLAGS) --no-pad-sections -o $@ $<
# compressed segment generation (actors)
$(BUILD_DIR)/bin/%.o: actors/%.s
$(AS) $(ASFLAGS) --no-pad-sections -o $@ $<
$(BUILD_DIR)/bin/%/leveldata.o: levels/%/leveldata.s
$(AS) $(ASFLAGS) --no-pad-sections -o $@ $<
$(BUILD_DIR)/bin/%/header.o: levels/%/header.s $(MIO0_DIR)/%/leveldata.mio0 levels/%/script.s
$(AS) $(ASFLAGS) --no-pad-sections -o $@ $<
# TODO: ideally this would be `-Trodata-segment=0x07000000` but that doesn't set the address
$(BUILD_DIR)/bin/%.elf: $(BUILD_DIR)/bin/%.o
$(LD) -e 0 -Ttext=$(SEGMENT_ADDRESS) -Map $@.map -o $@ $<
# Override for level.elf, which otherwise matches the above pattern
.SECONDEXPANSION:
$(BUILD_DIR)/bin/%/leveldata.elf: $(BUILD_DIR)/bin/%/leveldata.o $(BUILD_DIR)/bin/$$(TEXTURE_BIN).elf
$(LD) -e 0 -Ttext=$(SEGMENT_ADDRESS) -Map $@.map --just-symbols=$(BUILD_DIR)/bin/$(TEXTURE_BIN).elf -o $@ $<
$(BUILD_DIR)/bin/%.bin: $(BUILD_DIR)/bin/%.elf
$(OBJCOPY) -j .rodata $< -O binary $@
$(MIO0_DIR)/%.mio0: $(BUILD_DIR)/bin/%.bin
$(MIO0TOOL) $< $@
$(MIO0_DIR)/%.mio0.o: $(MIO0_DIR)/%.mio0.s
$(AS) $(ASFLAGS) -o $@ $<
$(MIO0_DIR)/%.mio0.s: $(MIO0_DIR)/%.mio0
printf ".section .data\n\n.incbin \"$<\"\n" > $@
$(BUILD_DIR)/%.table: %.aiff
$(AIFF_EXTRACT_CODEBOOK) $< >$@
$(BUILD_DIR)/%.aifc: $(BUILD_DIR)/%.table %.aiff
$(VADPCM_ENC) -c $^ $@
$(SOUND_BIN_DIR)/sound_data.ctl: $(SOUND_BANK_FILES) $(SOUND_SAMPLE_AIFCS)
$(PYTHON) tools/assemble_sound.py $(BUILD_DIR)/sound/samples/ sound/sound_banks/ $(SOUND_BIN_DIR)/sound_data.ctl $(SOUND_BIN_DIR)/sound_data.tbl $(VERSION_CFLAGS)
$(SOUND_BIN_DIR)/sound_data.tbl: $(SOUND_BIN_DIR)/sound_data.ctl
touch $@
$(SOUND_BIN_DIR)/sequences.bin: $(SOUND_SEQUENCE_FILES)
$(PYTHON) tools/assemble_sound.py --sequences $@ $^
$(SOUND_BIN_DIR)/%.m64: $(SOUND_BIN_DIR)/%.o
$(OBJCOPY) -j .rodata $< -O binary $@
$(SOUND_BIN_DIR)/%.o: $(SOUND_BIN_DIR)/%.s
$(AS) $(ASFLAGS) -o $@ $<
$(SOUND_BIN_DIR)/%.s: $(SOUND_BIN_DIR)/%
printf ".section .data\n\n.incbin \"$<\"\n" > $@
# Source code
$(BUILD_DIR)/src/goddard/%.o: OPT_FLAGS := -g
$(BUILD_DIR)/src/goddard/%.o: MIPSISET := -mips1
$(NON_MATCHING_O_FILES): CC := $(PYTHON) tools/asm_processor/build.py $(CC) -- $(AS) $(ASFLAGS) --
$(BUILD_DIR)/src/audio/%.o: OPT_FLAGS := -O2 -Wo,-loopunroll,0
$(BUILD_DIR)/src/audio/load.o: OPT_FLAGS := -O2 -framepointer -Wo,-loopunroll,0
$(BUILD_DIR)/lib/src/%.o: OPT_FLAGS :=
$(BUILD_DIR)/lib/src/math/ll%.o: MIPSISET := -mips3 -32
$(BUILD_DIR)/lib/src/math/%.o: OPT_FLAGS := -O2
$(BUILD_DIR)/lib/src/math/ll%.o: OPT_FLAGS :=
$(BUILD_DIR)/lib/src/ldiv.o: OPT_FLAGS := -O2
$(BUILD_DIR)/lib/src/string.o: OPT_FLAGS := -O2
$(BUILD_DIR)/lib/src/gu%.o: OPT_FLAGS := -O3
$(BUILD_DIR)/lib/src/al%.o: OPT_FLAGS := -O3
ifeq ($(VERSION),eu)
$(BUILD_DIR)/lib/src/_Litob.o: OPT_FLAGS := -O3
$(BUILD_DIR)/lib/src/_Ldtob.o: OPT_FLAGS := -O3
$(BUILD_DIR)/lib/src/_Printf.o: OPT_FLAGS := -O3
endif
# Rebuild files with '#ifdef NON_MATCHING' when that macro changes.
$(NON_MATCHING_O_FILES): $(NON_MATCHING_DEP).$(NON_MATCHING)
$(NON_MATCHING_DEP).$(NON_MATCHING):
@rm -f $(NON_MATCHING_DEP).*
touch $@
$(BUILD_DIR)/lib/src/math/%.o: lib/src/math/%.c
@$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/lib/src/math/$*.d $<
$(CC) -c $(CFLAGS) -o $@ $<
tools/patch_libultra_math $@ || rm $@
$(BUILD_DIR)/%.o: %.c
@$(CC_CHECK) -MMD -MP -MT $@ -MF $(BUILD_DIR)/$*.d $<
$(CC) -c $(CFLAGS) -o $@ $<
$(BUILD_DIR)/%.o: %.s $(MIO0_FILES)
$(AS) $(ASFLAGS) -MD $(BUILD_DIR)/$*.d -o $@ $<
$(BUILD_DIR)/$(LD_SCRIPT): $(LD_SCRIPT)
$(CPP) $(VERSION_CFLAGS) -MMD -MP -MT $@ -MF $@.d -I include/ -DBUILD_DIR=$(BUILD_DIR) -o $@ $<
$(BUILD_DIR)/libultra.a: $(ULTRA_O_FILES)
$(AR) rcs -o $@ $(ULTRA_O_FILES)
$(BUILD_DIR)/libgoddard.a: $(GODDARD_O_FILES)
$(AR) rcs -o $@ $(GODDARD_O_FILES)
$(ELF): $(O_FILES) $(MIO0_OBJ_FILES) $(SOUND_OBJ_FILES) $(SEG_FILES) $(BUILD_DIR)/$(LD_SCRIPT) undefined_syms.txt $(BUILD_DIR)/libultra.a $(BUILD_DIR)/libgoddard.a
$(LD) -L $(BUILD_DIR) $(LDFLAGS) -o $@ $(O_FILES)$(LIBS) -lultra -lgoddard
$(ROM): $(ELF)
$(OBJCOPY) $(OBJCOPYFLAGS) $< $(@:.z64=.bin) -O binary
$(N64CKSUM) $(@:.z64=.bin) $@
$(BUILD_DIR)/$(TARGET).objdump: $(ELF)
$(OBJDUMP) -D $< > $@
.PHONY: all clean distclean default diff test load libultra
.PRECIOUS: $(MIO0_DIR)/%.mio0 $(MIO0_DIR)/%.mio0.s $(BUILD_DIR)/bin/%.elf $(SOUND_BIN_DIR)/%.ctl $(SOUND_BIN_DIR)/%.tbl $(SOUND_SAMPLE_TABLES) $(SOUND_BIN_DIR)/%.s
.DELETE_ON_ERROR:
# Remove built-in rules, to improve performance
MAKEFLAGS += --no-builtin-rules
-include $(DEP_FILES)
print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true

293
Makefile.split

@ -0,0 +1,293 @@
# --------------------------------------
# General Rules
# --------------------------------------
# obtain a list of segments from the *.s files in bin directory
SEGMENTS := $(notdir $(basename $(wildcard bin/*.s))) $(addprefix $(VERSION)/,$(notdir $(basename $(wildcard bin/$(VERSION)/*.s))))
ACTORS := $(filter %/,$(wildcard actors/*/))
TEXTURE_DIRS := $(addprefix textures/,$(SEGMENTS)) $(ACTORS) textures/intro_raw
# NOTE: textures assume naming convention "texture.<encoding>.png" generates "texture.<encoding>"
ACTOR_GROUPS := \
group0 \
group1 \
group2 \
group3 \
group4 \
group5 \
group6 \
group7 \
group8 \
group9 \
group10 \
group11 \
group12 \
group13 \
group14 \
group15 \
group16 \
group17 \
common0 \
common1
LEVEL_FILES := $(addsuffix leveldata,$(LEVEL_DIRS))
MIO0_FILES := $(addprefix $(MIO0_DIR)/,$(addsuffix .mio0,$(SEGMENTS) $(ACTOR_GROUPS) $(LEVEL_FILES)))
MIO0_OBJ_FILES := $(MIO0_FILES:.mio0=.mio0.o)
SEGMENT_ELF_FILES := $(addprefix $(BUILD_DIR)/bin/,$(addsuffix .elf,$(SEGMENTS)))
ACTOR_ELF_FILES := $(addprefix $(BUILD_DIR)/bin/,$(addsuffix .elf,$(ACTOR_GROUPS)))
LEVEL_ELF_FILES := $(addprefix $(BUILD_DIR)/bin/,$(addsuffix .elf,$(LEVEL_FILES)))
# --------------------------------------
# Actor Rules
# --------------------------------------
# Actor Directories
KOOPA_DIRS := koopa_flag poundable_pole koopa piranha_plant whomp chain_ball chain_chomp
CAPSWITCH_DIRS := capswitch springboard
CHILLYCHIEF_DIRS := chillychief moneybag
BULLY_DIRS := bully blargg
SPINDRIFT_DIRS := spindrift penguin snowman
KING_BOBOMB_DIRS := king_bobomb water_bubble
BOO_DIRS := bookend book chair small_key mad_piano boo haunted_cage
MR_I_DIRS := mr_i_eyeball mr_i_iris swoop snufit dorrie scuttlebug
HOOT_DIRS := yellow_sphere_small hoot yoshi_egg thwomp bullet_bill heave_ho
COINS_DIRS := mist explosion butterfly coin warp_pipe door bowser_key flame blue_fish pebble leaves warp_collision mario_cap power_meter mushroom_1up star sand dirt transparent_star white_particle wooden_signpost tree
BUBBA_DIRS := bubba wiggler lakitu_enemy spiny_egg spiny
SKEETER_DIRS := skeeter seaweed water_mine cyan_fish bub water_ring treasure_chest
KLEPTO_DIRS := klepto eyerok pokey tornado
SEA_DIRS := clam_shell manta sushi unagi whirlpool
AMP_DIRS := blue_coin_switch amp cannon_lid cannon_base cannon_barrel chuckya purple_switch checkerboard_platform heart flyguy breakable_box exclamation_box goomba bobomb metal_box exclamation_box_outline test_platform koopa_shell
MOLE_DIRS := monty_mole_hole monty_mole smoke ukiki fwoosh
LAKITU_DIRS := lakitu_cameraman toad mips boo_castle
PEACH_DIRS := bird peach yoshi
BOWSER_DIRS := bowser_flame impact_ring yellow_sphere bowser bomb impact_smoke
MARIO_DIRS := mario bubble walk_smoke burn_smoke stomp_smoke water_waves sparkle water_splash white_particle_small sparkle_animation
# Actor Files
AMP_CHUCKYA_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(AMP_DIRS)),$(basename $(wildcard $(dir)/*.png)))
BOBOMBS_BUBBLE_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(KING_BOBOMB_DIRS)),$(basename $(wildcard $(dir)/*.png)))
BOO_BOOKEND_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(BOO_DIRS)),$(basename $(wildcard $(dir)/*.png)))
CAPSWITCH_SPRINGBOARD_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(CAPSWITCH_DIRS)),$(basename $(wildcard $(dir)/*.png)))
COINS_PIPE_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(COINS_DIRS)),$(basename $(wildcard $(dir)/*.png)))
BOWSER_FLAMES_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(BOWSER_DIRS)),$(basename $(wildcard $(dir)/*.png)))
BUBBA_WIGGLER_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(BUBBA_DIRS)),$(basename $(wildcard $(dir)/*.png)))
BULLY_BLARGG_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(BULLY_DIRS)),$(basename $(wildcard $(dir)/*.png)))
CHILLYCHIEF_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(CHILLYCHIEF_DIRS)),$(basename $(wildcard $(dir)/*.png)))
HOOT_THWOMP_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(HOOT_DIRS)),$(basename $(wildcard $(dir)/*.png)))
KOOPA_LOG_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(KOOPA_DIRS)),$(basename $(wildcard $(dir)/*.png)))
KLEPTO_EYEROK_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(KLEPTO_DIRS)),$(basename $(wildcard $(dir)/*.png)))
LAKITU_TOAD_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(LAKITU_DIRS)),$(basename $(wildcard $(dir)/*.png)))
MARIO_WATER_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(MARIO_DIRS)),$(basename $(wildcard $(dir)/*.png)))
MOLE_UKIKI_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(MOLE_DIRS)),$(basename $(wildcard $(dir)/*.png)))
MR_I_SWOOP_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(MR_I_DIRS)),$(basename $(wildcard $(dir)/*.png)))
PEACH_TOADSTOOL_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(PEACH_DIRS)),$(basename $(wildcard $(dir)/*.png)))
SEA_CREATURES_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(SEA_DIRS)),$(basename $(wildcard $(dir)/*.png)))
SKEETER_FISH_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(SKEETER_DIRS)),$(basename $(wildcard $(dir)/*.png)))
SPINDRIFT_PENGUIN_FILES := $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(SPINDRIFT_DIRS)),$(basename $(wildcard $(dir)/*.png)))
# Actor dependencies
$(BUILD_DIR)/bin/group0.o: $(addprefix $(BUILD_DIR)/,$(MARIO_WATER_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(MARIO_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group1.o: $(addprefix $(BUILD_DIR)/,$(HOOT_THWOMP_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(HOOT_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group2.o: $(addprefix $(BUILD_DIR)/,$(BULLY_BLARGG_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(BULLY_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group3.o: $(addprefix $(BUILD_DIR)/,$(BOBOMBS_BUBBLE_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(KING_BOBOMB_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group4.o: $(addprefix $(BUILD_DIR)/,$(SEA_CREATURES_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(SEA_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group5.o: $(addprefix $(BUILD_DIR)/,$(KLEPTO_EYEROK_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(KLEPTO_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group6.o: $(addprefix $(BUILD_DIR)/,$(MOLE_UKIKI_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(MOLE_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group7.o: $(addprefix $(BUILD_DIR)/,$(SPINDRIFT_PENGUIN_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(SPINDRIFT_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group8.o: $(addprefix $(BUILD_DIR)/,$(CAPSWITCH_SPRINGBOARD_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(CAPSWITCH_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group9.o: $(addprefix $(BUILD_DIR)/,$(BOO_BOOKEND_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(BOO_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group10.o: $(addprefix $(BUILD_DIR)/,$(PEACH_TOADSTOOL_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(PEACH_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group11.o: $(addprefix $(BUILD_DIR)/,$(BUBBA_WIGGLER_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(BUBBA_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group12.o: $(addprefix $(BUILD_DIR)/,$(BOWSER_FLAMES_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(BOWSER_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group13.o: $(addprefix $(BUILD_DIR)/,$(SKEETER_FISH_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(SKEETER_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group14.o: $(addprefix $(BUILD_DIR)/,$(KOOPA_LOG_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(KOOPA_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group15.o: $(addprefix $(BUILD_DIR)/,$(LAKITU_TOAD_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(LAKITU_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group16.o: $(addprefix $(BUILD_DIR)/,$(CHILLYCHIEF_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(CHILLYCHIEF_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/group17.o: $(addprefix $(BUILD_DIR)/,$(MR_I_SWOOP_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(MR_I_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/common0.o: $(addprefix $(BUILD_DIR)/,$(AMP_CHUCKYA_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(AMP_DIRS)),$(wildcard $(dir)/*.s))
$(BUILD_DIR)/bin/common1.o: $(addprefix $(BUILD_DIR)/,$(COINS_PIPE_FILES)) $(foreach dir,$(addprefix $(ACTOR_DIR)/,$(COINS_DIRS)),$(wildcard $(dir)/*.s))
# Actor Elf Files
$(BUILD_DIR)/bin/group0.elf: SEGMENT_ADDRESS := 0x04000000
$(BUILD_DIR)/bin/group1.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group2.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group3.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group4.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group5.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group6.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group7.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group8.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group9.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group10.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group11.elf: SEGMENT_ADDRESS := 0x05000000
$(BUILD_DIR)/bin/group12.elf: SEGMENT_ADDRESS := 0x06000000
$(BUILD_DIR)/bin/group13.elf: SEGMENT_ADDRESS := 0x06000000
$(BUILD_DIR)/bin/group14.elf: SEGMENT_ADDRESS := 0x06000000
$(BUILD_DIR)/bin/group15.elf: SEGMENT_ADDRESS := 0x06000000
$(BUILD_DIR)/bin/group16.elf: SEGMENT_ADDRESS := 0x06000000
$(BUILD_DIR)/bin/group17.elf: SEGMENT_ADDRESS := 0x06000000
$(BUILD_DIR)/bin/common0.elf: SEGMENT_ADDRESS := 0x08000000
$(BUILD_DIR)/bin/common1.elf: SEGMENT_ADDRESS := 0x03000000
# --------------------------------------
# Level Rules
# --------------------------------------
# Using these rules:
# When defining a level, define the 3 variables needed and copy the rules
# as-is.
# TODO: Generate these rules from the level configs?
define level_rules =
$(1)_SEG7_FILES := $$(basename $$(notdir $$(wildcard levels/$(1)/*.png)))
$(1)_SEG7_FILES_RAW := $(shell find levels/$(1)/ -type f -iname '*')
$$(BUILD_DIR)/bin/$(1)/leveldata.o: $$(addprefix $$(BUILD_DIR)/levels/$(1)/,$$($(1)_SEG7_FILES)) $$($(1)_SEG7_FILES_RAW)
$$(BUILD_DIR)/bin/$(1)/leveldata.elf: SEGMENT_ADDRESS := $(2)
$$(BUILD_DIR)/bin/$(1)/leveldata.elf: TEXTURE_BIN := $(3)
endef
$(eval $(call level_rules,bbh,0x07000000,spooky)) # BBH (Big Boo's Haunt)
$(eval $(call level_rules,ccm,0x07000000,snow)) # CCM (Cool Cool Mountain)
$(eval $(call level_rules,castle_inside,0x07000000,inside)) # Castle Inside (Inside Princess Peach's Castle)
$(eval $(call level_rules,hmc,0x07000000,cave))# HMC (Hazy Maze Cave)
$(eval $(call level_rules,ssl,0x07000000,generic)) # SSL (Shifting Sand Land)
$(eval $(call level_rules,bob,0x07000000,generic)) # BOB (Bob-Omb Battlefield)
$(eval $(call level_rules,sl,0x07000000,snow)) # SL (Snowman's Land)
$(eval $(call level_rules,wdw,0x07000000,grass)) # WDW (Wet Dry World)
$(eval $(call level_rules,jrb,0x07000000,water)) # JRB (Jolly Roger Bay)
$(eval $(call level_rules,thi,0x07000000,grass)) # THI (Tiny Huge Island)
$(eval $(call level_rules,ttc,0x07000000,machine)) # TTC (Tick Tock Clock)
$(eval $(call level_rules,rr,0x07000000,sky)) # RR (Rainbow Ride)
$(eval $(call level_rules,castle_grounds,0x07000000,outside)) # Castle Grounds (Outside Princess Peach's Castle)
$(eval $(call level_rules,bitdw,0x07000000,sky)) # BitDW (Bowser in the Dark World)
$(eval $(call level_rules,vcutm,0x07000000,outside)) # VCUTM (Vanish Cap under the Moat)
$(eval $(call level_rules,bitfs,0x07000000,sky)) # BITFS (Bowser in the Fire Sea)
$(eval $(call level_rules,sa,0x07000000,inside)) # SA (The Secret Aquarium)
$(eval $(call level_rules,bits,0x07000000,sky)) # BITS (Bowser in the Sky)
$(eval $(call level_rules,lll,0x07000000,fire)) # LLL (Lethal Lava Land)
$(eval $(call level_rules,ddd,0x07000000,water)) # DDD (Dire Dire Docks)
$(eval $(call level_rules,wf,0x07000000,grass)) # WF (Whomp's Fortress)
$(eval $(call level_rules,ending,0x07000000,generic)) # Ending
$(eval $(call level_rules,castle_courtyard,0x07000000,outside)) # Castle Courtyard (The Courtyard of Princess Peach's Castle)
$(eval $(call level_rules,pss,0x07000000,mountain)) # PSS (The Princess's Secret Slide)
$(eval $(call level_rules,cotmc,0x07000000,cave)) # COTMC (Cavern of the Metal Cap)
$(eval $(call level_rules,totwc,0x07000000,sky)) # TOTWC (Tower of the Wing Cap)
$(eval $(call level_rules,bowser_1,0x07000000,generic)) # BOWSER_1 (Bowser in the Dark World [Boss Area])
$(eval $(call level_rules,wmotr,0x07000000,generic)) # WMOTR (Wing Mario over the Rainbow)
$(eval $(call level_rules,bowser_2,0x07000000,fire)) # BOWSER_2 (Bowser in the Fire Sea [Boss Area])
$(eval $(call level_rules,bowser_3,0x07000000,generic)) # BOWSER_3 (Bowser in the Sky [Boss Area])
$(eval $(call level_rules,totwc,0x07000000,sky)) # TOTWC (Tower of the Wing Cap)
$(eval $(call level_rules,ttm,0x07000000,mountain)) # TTM (Tall Tall Mountain)
$(eval $(call level_rules,intro,0x07000000,generic)) # Intro (Super Mario 64 Logo)
$(eval $(call level_rules,menu,0x07000000,generic)) # Menu (File Select)
# --------------------------------------
# Texture Bin Rules
# --------------------------------------
# Others
SEGMENT2_FILES := $(basename $(wildcard $(TEXTURE_DIR)/segment2/*.png))
TITLE_SCREEN_BG_FILES := $(basename $(wildcard $(TEXTURE_DIR)/title_screen_bg/*.png))
SPOOKY_FILES := $(basename $(wildcard $(TEXTURE_DIR)/spooky/*.png))
GENERIC_FILES := $(basename $(wildcard $(TEXTURE_DIR)/generic/*.png))
OUTSIDE_FILES := $(basename $(wildcard $(TEXTURE_DIR)/outside/*.png))
SNOW_FILES := $(basename $(wildcard $(TEXTURE_DIR)/snow/*.png))
EFFECT_FILES := $(basename $(wildcard $(TEXTURE_DIR)/effect/*.png))
CAVE_FILES := $(basename $(wildcard $(TEXTURE_DIR)/cave/*.png))
INSIDE_FILES := $(basename $(wildcard $(TEXTURE_DIR)/inside/*.png))
WATER_FILES := $(basename $(wildcard $(TEXTURE_DIR)/water/*.png))
FIRE_TEXTURES_FILES := $(basename $(wildcard $(TEXTURE_DIR)/fire/*.png))
SKY_FILES := $(basename $(wildcard $(TEXTURE_DIR)/sky/*.png))
MACHINE_FILES := $(basename $(wildcard $(TEXTURE_DIR)/machine/*.png))
MOUNTAIN_FILES := $(basename $(wildcard $(TEXTURE_DIR)/mountain/*.png))
GRASS_FILES := $(basename $(wildcard $(TEXTURE_DIR)/grass/*.png))
# Texture Files
$(BUILD_DIR)/bin/segment2.o: $(addprefix $(BUILD_DIR)/,$(SEGMENT2_FILES))
$(BUILD_DIR)/bin/title_screen_bg.o: $(addprefix $(BUILD_DIR)/,$(TITLE_SCREEN_BG_FILES))
$(BUILD_DIR)/bin/spooky.o: $(addprefix $(BUILD_DIR)/,$(SPOOKY_FILES))
$(BUILD_DIR)/bin/generic.o: $(addprefix $(BUILD_DIR)/,$(GENERIC_FILES))
$(BUILD_DIR)/bin/outside.o: $(addprefix $(BUILD_DIR)/,$(OUTSIDE_FILES))
$(BUILD_DIR)/bin/snow.o: $(addprefix $(BUILD_DIR)/,$(SNOW_FILES))
$(BUILD_DIR)/bin/effect.o: $(addprefix $(BUILD_DIR)/,$(EFFECT_FILES))
$(BUILD_DIR)/bin/cave.o: $(addprefix $(BUILD_DIR)/,$(CAVE_FILES))
$(BUILD_DIR)/bin/inside.o: $(addprefix $(BUILD_DIR)/,$(INSIDE_FILES))
$(BUILD_DIR)/bin/water.o: $(addprefix $(BUILD_DIR)/,$(WATER_FILES))
$(BUILD_DIR)/bin/fire.o: $(addprefix $(BUILD_DIR)/,$(FIRE_TEXTURES_FILES))
$(BUILD_DIR)/bin/sky.o: $(addprefix $(BUILD_DIR)/,$(SKY_FILES))
$(BUILD_DIR)/bin/machine.o: $(addprefix $(BUILD_DIR)/,$(MACHINE_FILES))
$(BUILD_DIR)/bin/mountain.o: $(addprefix $(BUILD_DIR)/,$(MOUNTAIN_FILES))
$(BUILD_DIR)/bin/grass.o: $(addprefix $(BUILD_DIR)/,$(GRASS_FILES))
# Others
$(BUILD_DIR)/bin/segment2.elf: SEGMENT_ADDRESS := 0x02000000
$(BUILD_DIR)/bin/title_screen_bg.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/debug_level_select.elf: SEGMENT_ADDRESS := 0x07000000
$(BUILD_DIR)/bin/effect.elf: SEGMENT_ADDRESS := 0x0B000000
$(BUILD_DIR)/bin/spooky.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/generic.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/outside.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/snow.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/cave.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/inside.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/water.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/fire.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/sky.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/machine.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/mountain.elf: SEGMENT_ADDRESS := 0x09000000
$(BUILD_DIR)/bin/grass.elf: SEGMENT_ADDRESS := 0x09000000
# EU segment 19 translations
$(BUILD_DIR)/bin/$(VERSION)/translation_de.elf: SEGMENT_ADDRESS := 0x19000000
$(BUILD_DIR)/bin/$(VERSION)/translation_en.elf: SEGMENT_ADDRESS := 0x19000000
$(BUILD_DIR)/bin/$(VERSION)/translation_fr.elf: SEGMENT_ADDRESS := 0x19000000
# --------------------------------------
# Skybox Rules
# --------------------------------------
# Skybox Files
BBH_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/bbh_skybox/*.png))
BIDW_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/bidw_skybox/*.png))
BITFS_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/bitfs_skybox/*.png))
BITS_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/bits_skybox/*.png))
CCM_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/ccm_skybox/*.png))
CLOUD_FLOOR_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/cloud_floor_skybox/*.png))
CLOUDS_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/clouds_skybox/*.png))
SSL_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/ssl_skybox/*.png))
WATER_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/water_skybox/*.png))
WDW_SKYBOX_FILES := $(basename $(wildcard $(TEXTURE_DIR)/wdw_skybox/*.png))
# Skybox Files
$(BUILD_DIR)/bin/bbh_skybox.o: $(addprefix $(BUILD_DIR)/,$(BBH_SKYBOX_FILES))
$(BUILD_DIR)/bin/bidw_skybox.o: $(addprefix $(BUILD_DIR)/,$(BIDW_SKYBOX_FILES))
$(BUILD_DIR)/bin/bitfs_skybox.o: $(addprefix $(BUILD_DIR)/,$(BITFS_SKYBOX_FILES))
$(BUILD_DIR)/bin/bits_skybox.o: $(addprefix $(BUILD_DIR)/,$(BITS_SKYBOX_FILES))
$(BUILD_DIR)/bin/ccm_skybox.o: $(addprefix $(BUILD_DIR)/,$(CCM_SKYBOX_FILES))
$(BUILD_DIR)/bin/cloud_floor_skybox.o: $(addprefix $(BUILD_DIR)/,$(CLOUD_FLOOR_SKYBOX_FILES))
$(BUILD_DIR)/bin/clouds_skybox.o: $(addprefix $(BUILD_DIR)/,$(CLOUDS_SKYBOX_FILES))
$(BUILD_DIR)/bin/ssl_skybox.o: $(addprefix $(BUILD_DIR)/,$(SSL_SKYBOX_FILES))
$(BUILD_DIR)/bin/water_skybox.o: $(addprefix $(BUILD_DIR)/,$(WATER_SKYBOX_FILES))
$(BUILD_DIR)/bin/wdw_skybox.o: $(addprefix $(BUILD_DIR)/,$(WDW_SKYBOX_FILES))
# Skybox Files
$(BUILD_DIR)/bin/bbh_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/bidw_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/bitfs_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/bits_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/ccm_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/cloud_floor_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/clouds_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/ssl_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/water_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
$(BUILD_DIR)/bin/wdw_skybox.elf: SEGMENT_ADDRESS := 0x0A000000
# --------------------------------------
# Misc Rules
# --------------------------------------
# intro_raw textures are not compressed
INTRO_RAW_FILES := $(basename $(notdir $(wildcard $(TEXTURE_DIR)/intro_raw/*.png)))
$(BUILD_DIR)/data/goddard_tex_dl.o: $(addprefix $(BUILD_DIR)/textures/intro_raw/,$(INTRO_RAW_FILES))

82
README.md

@ -0,0 +1,82 @@
# Super Mario 64
This repo contains a full decompilation of Super Mario 64 (J) and (U).
The source and data have been decompiled but complete naming and documentation
all of the code and data is still a work in progress. Decompiling the (E) ROM
is also an ongoing effort.
It builds the following ROMs:
* sm64.jp.z64 `sha1: 8a20a5c83d6ceb0f0506cfc9fa20d8f438cafe51`
* sm64.us.z64 `sha1: 9bef1128717f958171a4afac3ed78ee2bb4e86ce`
This repo does not include all assets necessary for compiling the ROMs.
A prior copy of the game is required to extract the required assets.
## Installation
### Linux
1. For each version (jp/us/eu) that you want to build a ROM for, put an existing ROM at
`./baserom.<version>.z64` for asset extraction.
2. Install the following packages:
__Debian / Ubuntu__
* git
* binutils-mips-linux-gnu / mips64-elf (>= 2.27)
* python3 (>= 3.7)
* build-essential
* pkg-config
* zlib1g-dev
* libaudiofile-dev
__Arch Linux__
* base-devel
* python
* audiofile
* [mips64-elf-binutils](https://aur.archlinux.org/packages/mips64-elf-binutils) (AUR)
* [qemu-irix-git](https://aur.archlinux.org/packages/qemu-irix-git) (AUR)
3. Install qemu-irix
3.a Options:
1. Clone https://github.com/n64decomp/qemu-irix to somewhere and follow its
install instructions in the README.
2. Optionally, grab the prebuilt qemu-irix from the Releases section.
3. (Arch) Use AUR package [qemu-irix-git](https://aur.archlinux.org/packages/qemu-irix-git)
3.b (For options 1 or 2), copy executable `qemu-irix` from irix-linux-user to
somewhere convenient with a relatively short path.
```
mkdir -p /opt/qemu-irix/bin
cp irix-linux-user/qemu-irix /opt/qemu-irix/bin
```
3.c Define `QEMU_IRIX` environment variable in your `~/.bashrc` to point to
this qemu-irix executable.
```
export QEMU_IRIX=/opt/qemu-irix/bin/qemu-irix
```
6. Run `make` to build the ROM (defaults to us version). Make sure your path to
the repo is not too long or else this process will error, as the emulated
IDO compiler cannot handle paths longer than 255 characters.
Build examples:
```
make VERSION=jp -j4 # build (J) version instead with 4 jobs
make VERSION=eu COMPARE=0 # non-matching EU version still WIP
## Windows
For Windows, install WSL and a distro of your choice and follow the Linux guide.
## Contributing
Pull requests are welcome. For major changes, please open an issue first to
discuss what you would like to change.
Run clang-format on your code to ensure it meets the project's coding standards.
Official discord: https://discord.gg/27JtCWs

2
actors/amp/collision.s

@ -0,0 +1,2 @@
# Amp

54
actors/amp/geo.s

@ -0,0 +1,54 @@
glabel amp_geo # 0x0F000028
geo_shadow SHADOW_CIRCLE_4_VERTS, 0xC8, 100
geo_open_node
geo_scale 0x00, 16384
geo_open_node
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_open_node
geo_animated_part LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002C88
geo_open_node
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_open_node
geo_switch_case 2, geo_switch_anim_state
geo_open_node
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_animated_part LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002BA0
geo_close_node
geo_close_node
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_open_node
geo_switch_case 2, geo_switch_anim_state
geo_open_node
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_animated_part LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002BA0
geo_close_node
geo_close_node
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_open_node
geo_switch_case 2, geo_switch_anim_state
geo_open_node
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_animated_part LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002BA0
geo_close_node
geo_close_node
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_open_node
geo_switch_case 2, geo_switch_anim_state
geo_open_node
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_animated_part LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002BA0
geo_close_node
geo_close_node
geo_close_node
geo_animated_part LAYER_ALPHA, 0, 0, 0, amp_seg8_dl_08002D70
geo_animated_part LAYER_OPAQUE, 0, 0, 0
geo_open_node
geo_billboard
geo_open_node
geo_display_list LAYER_ALPHA, amp_seg8_dl_08002E58
geo_close_node
geo_close_node
geo_close_node
geo_close_node
geo_close_node
geo_end

503
actors/amp/model.s

@ -0,0 +1,503 @@
# Amp
amp_seg8_texture_08000F18: # 0x08000F18
.incbin "actors/amp/amp_electricity.rgba16"
amp_seg8_texture_08001318: # 0x08001318
.incbin "actors/amp/amp_eyes.rgba16"
amp_seg8_texture_08001B18: # 0x08001B18
.incbin "actors/amp/amp_body.rgba16"
amp_seg8_texture_08002318: # 0x08002318
.incbin "actors/amp/amp_mouth.rgba16"
amp_seg8_vertex_08002B18: # 0x08002B18
vertex 224, 0, -89, 0, 480, 0xFF, 0xFF, 0xFF, 0xFF
vertex 187, 149, 0, 223, 1078, 0xFF, 0xFF, 0xFF, 0xFF
vertex 224, 0, 90, 479, 478, 0xFF, 0xFF, 0xFF, 0xFF
vertex 187, -148, 0, 224, -122, 0xFF, 0xFF, 0xFF, 0xFF
vertex 224, 0, -89, 0, 478, 0xFF, 0xFF, 0xFF, 0xFF
glabel amp_seg8_dl_08002B68 # 0x08002B68 - 0x08002BA0
gsDPSetTextureImage G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, amp_seg8_texture_08000F18
gsDPLoadSync
gsDPLoadBlock 7, 0, 0, 0x1FF, 0x200
gsSPVertex amp_seg8_vertex_08002B18, 5, 0
gsSP2Triangles 0, 1, 2, 0x0, 2, 3, 4, 0x0
gsSPEndDisplayList
glabel amp_seg8_dl_08002BA0 # 0x08002BA0 - 0x08002C10
gsDPPipeSync
gsDPSetCombineModeLERP1Cycle G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_TEXEL0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_TEXEL0
gsSPClearGeometryMode G_LIGHTING | G_CULL_BACK
gsDPSetTile G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD
gsSPTexture -1, -1, 0, 0, 1
gsDPTileSync
gsDPSetTile G_IM_FMT_RGBA, G_IM_SIZ_16b, 4, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP | G_TX_NOMIRROR, 5, G_TX_NOLOD, G_TX_CLAMP | G_TX_NOMIRROR, 4, G_TX_NOLOD
gsDPSetTileSize 0, 0, 0, 60, 124
gsSPDisplayList amp_seg8_dl_08002B68
gsSPTexture -1, -1, 0, 0, 0
gsDPPipeSync
gsDPSetCombineModeLERP1Cycle G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_SHADE, G_ACMUX_0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_SHADE
gsSPSetGeometryMode G_LIGHTING | G_CULL_BACK
gsSPEndDisplayList
amp_seg8_vertex_08002C10: # 0x08002C10
vertex 68, 72, 158, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF
vertex -27, -71, 164, 990, 990, 0xFF, 0xFF, 0xFF, 0xFF
vertex 68, -71, 158, 990, 0, 0xFF, 0xFF, 0xFF, 0xFF
vertex -27, 72, 164, 0, 990, 0xFF, 0xFF, 0xFF, 0xFF
glabel amp_seg8_dl_08002C50 # 0x08002C50 - 0x08002C88
gsDPSetTextureImage G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, amp_seg8_texture_08001318
gsDPLoadSync
gsDPLoadBlock 7, 0, 0, 0x3FF, 0x100
gsSPVertex amp_seg8_vertex_08002C10, 4, 0
gsSP2Triangles 0, 1, 2, 0x0, 0, 3, 1, 0x0
gsSPEndDisplayList
glabel amp_seg8_dl_08002C88 # 0x08002C88 - 0x08002CF8
gsDPPipeSync
gsDPSetCombineModeLERP1Cycle G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_TEXEL0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_TEXEL0
gsSPClearGeometryMode G_LIGHTING
gsDPSetTile G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD
gsSPTexture -1, -1, 0, 0, 1
gsDPTileSync
gsDPSetTile G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP | G_TX_NOMIRROR, 5, G_TX_NOLOD, G_TX_CLAMP | G_TX_NOMIRROR, 5, G_TX_NOLOD
gsDPSetTileSize 0, 0, 0, 124, 124
gsSPDisplayList amp_seg8_dl_08002C50
gsSPTexture -1, -1, 0, 0, 0
gsDPPipeSync
gsDPSetCombineModeLERP1Cycle G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_SHADE, G_ACMUX_0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_SHADE
gsSPSetGeometryMode G_LIGHTING
gsSPEndDisplayList
amp_seg8_vertex_08002CF8: # 0x08002CF8
vertex -29, 72, 164, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF
vertex -124, -71, 121, 990, 990, 0xFF, 0xFF, 0xFF, 0xFF
vertex -29, -71, 164, 990, 0, 0xFF, 0xFF, 0xFF, 0xFF
vertex -124, 72, 121, 0, 990, 0xFF, 0xFF, 0xFF, 0xFF
glabel amp_seg8_dl_08002D38 # 0x08002D38 - 0x08002D70
gsDPSetTextureImage G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, amp_seg8_texture_08002318
gsDPLoadSync
gsDPLoadBlock 7, 0, 0, 0x3FF, 0x100
gsSPVertex amp_seg8_vertex_08002CF8, 4, 0
gsSP2Triangles 0, 1, 2, 0x0, 0, 3, 1, 0x0
gsSPEndDisplayList
glabel amp_seg8_dl_08002D70 # 0x08002D70 - 0x08002DE0
gsDPPipeSync
gsDPSetCombineModeLERP1Cycle G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_TEXEL0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_TEXEL0
gsSPClearGeometryMode G_LIGHTING
gsDPSetTile G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD
gsSPTexture -1, -1, 0, 0, 1
gsDPTileSync
gsDPSetTile G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP | G_TX_NOMIRROR, 5, G_TX_NOLOD, G_TX_CLAMP | G_TX_NOMIRROR, 5, G_TX_NOLOD
gsDPSetTileSize 0, 0, 0, 124, 124
gsSPDisplayList amp_seg8_dl_08002D38
gsSPTexture -1, -1, 0, 0, 0
gsDPPipeSync
gsDPSetCombineModeLERP1Cycle G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_SHADE, G_ACMUX_0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_SHADE
gsSPSetGeometryMode G_LIGHTING
gsSPEndDisplayList
amp_seg8_vertex_08002DE0: # 0x08002DE0
vertex -39, -39, 0, 0, 990, 0xFF, 0xFF, 0xFF, 0xFF
vertex 40, 40, 0, 990, 0, 0xFF, 0xFF, 0xFF, 0xFF
vertex -39, 40, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF
vertex 40, -39, 0, 990, 990, 0xFF, 0xFF, 0xFF, 0xFF
glabel amp_seg8_dl_08002E20 # 0x08002E20 - 0x08002E58
gsDPSetTextureImage G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, amp_seg8_texture_08001B18
gsDPLoadSync
gsDPLoadBlock 7, 0, 0, 0x3FF, 0x100
gsSPVertex amp_seg8_vertex_08002DE0, 4, 0
gsSP2Triangles 0, 1, 2, 0x0, 0, 3, 1, 0x0
gsSPEndDisplayList
glabel amp_seg8_dl_08002E58 # 0x08002E58 - 0x08002EC8
gsDPPipeSync
gsDPSetCombineModeLERP1Cycle G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_TEXEL0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_TEXEL0
gsSPClearGeometryMode G_LIGHTING
gsDPSetTile G_IM_FMT_RGBA, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOLOD
gsSPTexture -1, -1, 0, 0, 1
gsDPTileSync
gsDPSetTile G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 0, G_TX_RENDERTILE, 0, G_TX_CLAMP | G_TX_NOMIRROR, 5, G_TX_NOLOD, G_TX_CLAMP | G_TX_NOMIRROR, 5, G_TX_NOLOD
gsDPSetTileSize 0, 0, 0, 124, 124
gsSPDisplayList amp_seg8_dl_08002E20
gsSPTexture -1, -1, 0, 0, 0
gsDPPipeSync
gsDPSetCombineModeLERP1Cycle G_CCMUX_0, G_CCMUX_0, G_CCMUX_0, G_CCMUX_SHADE, G_ACMUX_0, G_ACMUX_0, G_ACMUX_0, G_ACMUX_SHADE
gsSPSetGeometryMode G_LIGHTING
gsSPEndDisplayList
amp_seg8_light_08002EC8: # 0x08002EC8
.byte 0x33, 0x3F, 0x00, 0x00, 0x33, 0x3F, 0x00, 0x00
amp_seg8_light_08002ED0: # 0x08002ED0
.byte 0xCF, 0xFF, 0x00, 0x00, 0xCF, 0xFF, 0x00, 0x00
.byte 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00
# //! Another malformed entry: Vertex interpreted as light
amp_seg8_vertex_08002EE0: # 0x08002EE0
vertex 280, 0, 35, 0, 0, 0x7B, 0xE2, 0x00, 0x00
vertex 240, -160, 0, 0, 0, 0x7B, 0xE2, 0x00, 0x00
vertex 280, 0, -35, 0, 0, 0x7B, 0xE2, 0x00, 0x00
vertex 280, 0, -35, 0, 0, 0x7B, 0x1E, 0x00, 0xFF
vertex 240, 160, 0, 0, 0, 0x7B, 0x1E, 0x00, 0xFF
vertex 280, 0, 35, 0, 0, 0x7B, 0x1E, 0x00, 0xFF
amp_seg8_vertex_08002F40: # 0x08002F40
vertex 280, 0, 35, 0, 0, 0x7B, 0xE2, 0x00, 0x00
vertex 240, -160, 0, 0, 0, 0x7B, 0xE2, 0x00, 0x00
vertex 280, 0, -35, 0, 0, 0x7B, 0xE2, 0x00, 0x00
vertex 280, 0, -35, 0, 0, 0x7B, 0x1E, 0x00, 0xFF
vertex 240, 160, 0, 0, 0, 0x7B, 0x1E, 0x00, 0xFF
vertex 280, 0, 35, 0, 0, 0x7B, 0x1E, 0x00, 0xFF
amp_seg8_vertex_08002FA0: # 0x08002FA0
vertex 280, 0, 35, 0, 0, 0x7B, 0xE2, 0x00, 0x00
vertex 240, -160, 0, 0, 0, 0x7B, 0xE2, 0x00, 0x00
vertex 280, 0, -35, 0, 0, 0x7B, 0xE2, 0x00, 0x00
vertex 280, 0, -35, 0, 0, 0x7B, 0x1E, 0x00, 0xFF
vertex 240, 160, 0, 0, 0, 0x7B, 0x1E, 0x00, 0xFF
vertex 280, 0, 35, 0, 0, 0x7B, 0x1E, 0x00, 0xFF
amp_seg8_vertex_08003000: # 0x08003000
vertex 280, 0, -35, 0, 0, 0x7B, 0x1E, 0x00, 0x00
vertex 240, 160, 0, 0, 0, 0x7B, 0x1E, 0x00, 0x00
vertex 280, 0, 35, 0, 0, 0x7B, 0x1E, 0x00, 0x00
vertex 280, 0, 35, 0, 0, 0x7B, 0xE2, 0x00, 0xFF
vertex 240, -160, 0, 0, 0, 0x7B, 0xE2, 0x00, 0xFF
vertex 280, 0, -35, 0, 0, 0x7B, 0xE2, 0x00, 0xFF
amp_seg8_vertex_08003060: # 0x08003060
vertex -184, -54, -54, 0, 0, 0x8B, 0xDE, 0xDE, 0x00
vertex -184, -76, 0, 0, 0, 0x8B, 0xD0, 0x00, 0x00
vertex -200, 0, 0, 0, 0, 0x81, 0x00, 0x00, 0x00
vertex -141, -100, -100, 0, 0, 0xA6, 0xC1, 0xC1, 0xFF
vertex -141, -141, 0, 0, 0, 0xA6, 0xA7, 0x00, 0xFF
vertex -76, -130, -130, 0, 0, 0xD0, 0xAE, 0xAE, 0xFF
vertex -76, -184, 0, 0, 0, 0xD0, 0x8B, 0x00, 0xFF
vertex 0, -141, -141, 0, 0, 0x00, 0xA7, 0xA7, 0xFF
vertex 0, -200, 0, 0, 0, 0x00, 0x81, 0x00, 0xFF
vertex 76, -130, -130, 0, 0, 0x30, 0xAE, 0xAE, 0xFF
vertex 76, -184, 0, 0, 0, 0x30, 0x8B, 0x00, 0xFF
vertex 141, -100, -100, 0, 0, 0x5A, 0xC1, 0xC1, 0xFF
vertex 141, -141, 0, 0, 0, 0x5A, 0xA7, 0x00, 0xFF
vertex 184, -54, -54, 0, 0, 0x75, 0xDE, 0xDE, 0xFF
vertex 184, -76, 0, 0, 0, 0x75, 0xD0, 0x00, 0xFF
vertex 200, 0, 0, 0, 0, 0x7F, 0x00, 0x00, 0xFF
amp_seg8_vertex_08003160: # 0x08003160
vertex -184, 0, -76, 0, 0, 0x8B, 0x00, 0xD0, 0xFF
vertex -184, -54, -54, 0, 0, 0x8B, 0xDE, 0xDE, 0x00
vertex -200, 0, 0, 0, 0, 0x81, 0x00, 0x00, 0x00
vertex -141, 0, -141, 0, 0, 0xA6, 0x00, 0xA7, 0xFF
vertex -141, -100, -100, 0, 0, 0xA6, 0xC1, 0xC1, 0xFF
vertex -76, 0, -184, 0, 0, 0xD0, 0x00, 0x8B, 0xFF
vertex -76, -130, -130, 0, 0, 0xD0, 0xAE, 0xAE, 0xFF
vertex 0, 0, -200, 0, 0, 0x00, 0x00, 0x81, 0xFF
vertex 0, -141, -141, 0, 0, 0x00, 0xA7, 0xA7, 0xFF
vertex 76, 0, -184, 0, 0, 0x30, 0x00, 0x8B, 0xFF
vertex 76, -130, -130, 0, 0, 0x30, 0xAE, 0xAE, 0xFF
vertex 141, 0, -141, 0, 0, 0x5A, 0x00, 0xA7, 0xFF
vertex 141, -100, -100, 0, 0, 0x5A, 0xC1, 0xC1, 0xFF
vertex 184, 0, -76, 0, 0, 0x75, 0x00, 0xD0, 0xFF
vertex 184, -54, -54, 0, 0, 0x75, 0xDE, 0xDE, 0xFF
vertex 200, 0, 0, 0, 0, 0x7F, 0x00, 0x00, 0xFF
amp_seg8_vertex_08003260: # 0x08003260
vertex -184, 54, -54, 0, 0, 0x8B, 0x22, 0xDE, 0xFF
vertex -184, 0, -76, 0, 0, 0x8B, 0x00, 0xD0, 0x00
vertex -200, 0, 0, 0, 0, 0x81, 0x00, 0x00, 0x00
vertex -141, 100, -100, 0, 0, 0xA6, 0x3F, 0xC1, 0xFF
vertex -141, 0, -141, 0, 0, 0xA6, 0x00, 0xA7, 0xFF
vertex -76, 130, -130, 0, 0, 0xD0, 0x52, 0xAE, 0xFF
vertex -76, 0, -184, 0, 0, 0xD0, 0x00, 0x8B, 0xFF
vertex 0, 141, -141, 0, 0, 0x00, 0x59, 0xA7, 0xFF
vertex 0, 0, -200, 0, 0, 0x00, 0x00, 0x81, 0xFF
vertex 76, 130, -130, 0, 0, 0x30, 0x52, 0xAE, 0xFF
vertex 76, 0, -184, 0, 0, 0x30, 0x00, 0x8B, 0xFF
vertex 141, 100, -100, 0, 0, 0x5A, 0x3F, 0xC1, 0xFF
vertex 141, 0, -141, 0, 0, 0x5A, 0x00, 0xA7, 0xFF
vertex 184, 54, -54, 0, 0, 0x75, 0x22, 0xDE, 0xFF
vertex 184, 0, -76, 0, 0, 0x75, 0x00, 0xD0, 0xFF
vertex 200, 0, 0, 0, 0, 0x7F, 0x00, 0x00, 0xFF
amp_seg8_vertex_08003360: # 0x08003360
vertex -184, 76, 0, 0, 0, 0x8B, 0x30, 0x00, 0xFF
vertex -184, 54, -54, 0, 0, 0x8B, 0x22, 0xDE, 0x00
vertex -200, 0, 0, 0, 0, 0x81, 0x00, 0x00, 0x00
vertex -141, 141, 0, 0, 0, 0xA6, 0x59, 0x00, 0xFF
vertex -141, 100, -100, 0, 0, 0xA6, 0x3F, 0xC1, 0xFF
vertex -76, 184, 0, 0, 0, 0xD0, 0x75, 0x00, 0xFF
vertex -76, 130, -130, 0, 0, 0xD0, 0x52, 0xAE, 0xFF
vertex 0, 200, 0, 0, 0, 0x00, 0x7F, 0x00, 0xFF
vertex 0, 141, -141, 0, 0, 0x00, 0x59, 0xA7, 0xFF
vertex 76, 184, 0, 0, 0, 0x30, 0x75, 0x00, 0xFF
vertex 76, 130, -130, 0, 0, 0x30, 0x52, 0xAE, 0xFF
vertex 141, 141, 0, 0, 0, 0x5A, 0x59, 0x00, 0xFF
vertex 141, 100, -100, 0, 0, 0x5A, 0x3F, 0xC1, 0xFF
vertex 184, 76, 0, 0, 0, 0x75, 0x30, 0x00, 0xFF
vertex 184, 54, -54, 0, 0, 0x75, 0x22, 0xDE, 0xFF
vertex 200, 0, 0, 0, 0, 0x7F, 0x00, 0x00, 0xFF
amp_seg8_vertex_08003460: # 0x08003460
vertex -184, 54, 54, 0, 0, 0x8B, 0x22, 0x22, 0xFF
vertex -184, 76, 0, 0, 0, 0x8B, 0x30, 0x00, 0x00
vertex -200, 0, 0, 0, 0, 0x81, 0x00, 0x00, 0x00
vertex -141, 100, 100, 0, 0, 0xA6, 0x3F, 0x3F, 0xFF
vertex -141, 141, 0, 0, 0, 0xA6, 0x59, 0x00, 0xFF
vertex -76, 130, 130, 0, 0, 0xD0, 0x52, 0x52, 0xFF
vertex -76, 184, 0, 0, 0, 0xD0, 0x75, 0x00, 0xFF
vertex 0, 141, 141, 0, 0, 0x00, 0x59, 0x59, 0xFF
vertex 0, 200, 0, 0, 0, 0x00, 0x7F, 0x00, 0xFF
vertex 76, 130, 130, 0, 0, 0x30, 0x52, 0x52, 0xFF
vertex 76, 184, 0, 0, 0, 0x30, 0x75, 0x00, 0xFF
vertex 141, 100, 100, 0, 0, 0x5A, 0x3F, 0x3F, 0xFF
vertex 141, 141, 0, 0, 0, 0x5A, 0x59, 0x00, 0xFF
vertex 184, 54, 54, 0, 0, 0x75, 0x22, 0x22, 0xFF
vertex 184, 76, 0, 0, 0, 0x75, 0x30, 0x00, 0xFF
vertex 200, 0, 0, 0, 0, 0x7F, 0x00, 0x00, 0xFF
amp_seg8_vertex_08003560: # 0x08003560
vertex -184, 0, 76, 0, 0, 0x8B, 0x00, 0x30, 0xFF
vertex -184, 54, 54, 0, 0, 0x8B, 0x22, 0x22, 0x00
vertex -200, 0, 0, 0, 0, 0x81, 0x00, 0x00, 0x00
vertex -141, 0, 141, 0, 0, 0xA6, 0x00, 0x59, 0xFF
vertex -141, 100, 100, 0, 0, 0xA6, 0x3F, 0x3F, 0xFF
vertex -76, 0, 184, 0, 0, 0xD0, 0x00, 0x75, 0xFF
vertex -76, 130, 130, 0, 0, 0xD0, 0x52, 0x52, 0xFF
vertex 0, 0, 200, 0, 0, 0x00, 0x00, 0x7F, 0xFF
vertex 0, 141, 141, 0, 0, 0x00, 0x59, 0x59, 0xFF
vertex 76, 0, 184, 0, 0, 0x30, 0x00, 0x75, 0xFF
vertex 76, 130, 130, 0, 0, 0x30, 0x52, 0x52, 0xFF
vertex 141, 0, 141, 0, 0, 0x5A, 0x00, 0x59, 0xFF
vertex 141, 100, 100, 0, 0, 0x5A, 0x3F, 0x3F, 0xFF
vertex 184, 0, 76, 0, 0, 0x75, 0x00, 0x30, 0xFF
vertex 184, 54, 54, 0, 0, 0x75, 0x22, 0x22, 0xFF
vertex 200, 0, 0, 0, 0, 0x7F, 0x00, 0x00, 0xFF
amp_seg8_vertex_08003660: # 0x08003660
vertex -184, -54, 54, 0, 0, 0x8B, 0xDE, 0x22, 0xFF
vertex -184, 0, 76, 0, 0, 0x8B, 0x00, 0x30, 0x00
vertex -200, 0, 0, 0, 0, 0x81, 0x00, 0x00, 0x00
vertex -141, -100, 100, 0, 0, 0xA6, 0xC1, 0x3F, 0xFF
vertex -141, 0, 141, 0, 0, 0xA6, 0x00, 0x59, 0xFF
vertex -76, -130, 130, 0, 0, 0xD0, 0xAE, 0x52, 0xFF
vertex -76, 0, 184, 0, 0, 0xD0, 0x00, 0x75, 0xFF
vertex 0, -141, 141, 0, 0, 0x00, 0xA7, 0x59, 0xFF
vertex 0, 0, 200, 0, 0, 0x00, 0x00, 0x7F, 0xFF
vertex 76, -130, 130, 0, 0, 0x30, 0xAE, 0x52, 0xFF
vertex 76, 0, 184, 0, 0, 0x30, 0x00, 0x75, 0xFF
vertex 141, -100, 100, 0, 0, 0x5A, 0xC1, 0x3F, 0xFF
vertex 141, 0, 141, 0, 0, 0x5A, 0x00, 0x59, 0xFF
vertex 184, -54, 54, 0, 0, 0x75, 0xDE, 0x22, 0xFF
vertex 184, 0, 76, 0, 0, 0x75, 0x00, 0x30, 0xFF
vertex 200, 0, 0, 0, 0, 0x7F, 0x00, 0x00, 0xFF
amp_seg8_vertex_08003760: # 0x08003760
vertex -184, -76, 0, 0, 0, 0x8B, 0xD0, 0x00, 0xFF
vertex -184, -54, 54, 0, 0, 0x8B, 0xDE, 0x22, 0x00
vertex -200, 0, 0, 0, 0, 0x81, 0x00, 0x00, 0x00
vertex -141, -141, 0, 0, 0, 0xA6, 0xA7, 0x00, 0xFF
vertex -141, -100, 100, 0, 0, 0xA6, 0xC1, 0x3F, 0xFF
vertex -76, -184, 0, 0, 0, 0xD0, 0x8B, 0x00, 0xFF
vertex -76, -130, 130, 0, 0, 0xD0, 0xAE, 0x52, 0xFF
vertex 0, -200, 0, 0, 0, 0x00, 0x81, 0x00, 0xFF
vertex 0, -141, 141, 0, 0, 0x00, 0xA7, 0x59, 0xFF
vertex 76, -184, 0, 0, 0, 0x30, 0x8B, 0x00, 0xFF
vertex 76, -130, 130, 0, 0, 0x30, 0xAE, 0x52, 0xFF
vertex 141, -141, 0, 0, 0, 0x5A, 0xA7, 0x00, 0xFF
vertex 141, -100, 100, 0, 0, 0x5A, 0xC1, 0x3F, 0xFF
vertex 184, -76, 0, 0, 0, 0x75, 0xD0, 0x00, 0xFF
vertex 184, -54, 54, 0, 0, 0x75, 0xDE, 0x22, 0xFF
vertex 200, 0, 0, 0, 0, 0x7F, 0x00, 0x00, 0xFF
amp_seg8_vertex_08003860: # 0x08003860
vertex -37, 90, 205, 0, 0, 0xCC, 0x00, 0x73, 0x00
vertex -129, 90, 163, 0, 0, 0xCC, 0x00, 0x73, 0x00
vertex -129, -90, 163, 0, 0, 0xCC, 0x00, 0x73, 0x00
vertex -37, -90, 205, 0, 0, 0xCC, 0x00, 0x73, 0xFF
amp_seg8_vertex_080038A0: # 0x080038A0
vertex 112, -7, 182, 0, 0, 0x4C, 0xD8, 0x5C, 0x00
vertex 66, -139, 162, 0, 0, 0x4C, 0xD8, 0x5C, 0x00
vertex 175, -77, 98, 0, 0, 0x4C, 0xD8, 0x5C, 0x00
amp_seg8_vertex_080038D0: # 0x080038D0
vertex 63, 90, 198, 0, 0, 0x08, 0x00, 0x7E, 0x00
vertex -35, 90, 205, 0, 0, 0x08, 0x00, 0x7E, 0x00
vertex -35, -90, 205, 0, 0, 0x08, 0x00, 0x7E, 0x00
vertex 63, -90, 198, 0, 0, 0x08, 0x00, 0x7E, 0xFF
glabel amp_seg8_dl_08003910 # 0x08003910 - 0x08003940
gsSPLight amp_seg8_light_08002ED0, 1
gsSPLight amp_seg8_light_08002EC8, 2
gsSPVertex amp_seg8_vertex_08002EE0, 6, 0
gsSP2Triangles 0, 1, 2, 0x0, 3, 4, 5, 0x0
gsSPEndDisplayList
glabel amp_seg8_dl_08003940 # 0x08003940 - 0x08003970
gsSPLight amp_seg8_light_08002ED0, 1
gsSPLight amp_seg8_light_08002EC8, 2
gsSPVertex amp_seg8_vertex_08002F40, 6, 0
gsSP2Triangles 0, 1, 2, 0x0, 3, 4, 5, 0x0
gsSPEndDisplayList
glabel amp_seg8_dl_08003970 # 0x08003970 - 0x080039A0
gsSPLight amp_seg8_light_08002ED0, 1
gsSPLight amp_seg8_light_08002EC8, 2
gsSPVertex amp_seg8_vertex_08002FA0, 6, 0
gsSP2Triangles 0, 1, 2, 0x0, 3, 4, 5, 0x0
gsSPEndDisplayList
glabel amp_seg8_dl_080039A0 # 0x080039A0 - 0x080039D0
gsSPLight amp_seg8_light_08002ED0, 1
gsSPLight amp_seg8_light_08002EC8, 2
gsSPVertex amp_seg8_vertex_08003000, 6, 0
gsSP2Triangles 0, 1, 2, 0x0, 3, 4, 5, 0x0
gsSPEndDisplayList
glabel amp_seg8_dl_080039D0 # 0x080039D0 - 0x08003DA8
gsSPLight amp_seg8_vertex_08002EE0 + 0x8, 1
gsSPLight amp_seg8_vertex_08002EE0, 2
gsSPVertex amp_seg8_vertex_08003060, 16, 0
gsSP2Triangles 0, 1, 2, 0x0, 1, 0, 3, 0x0
gsSP2Triangles 1, 3, 4, 0x0, 4, 3, 5, 0x0
gsSP2Triangles 4, 5, 6, 0x0, 6, 5, 7, 0x0
gsSP2Triangles 6, 7, 8, 0x0, 8, 7, 9, 0x0
gsSP2Triangles 8, 9, 10, 0x0, 10, 9, 11, 0x0
gsSP2Triangles 10, 11, 12, 0x0, 12, 11, 13, 0x0
gsSP2Triangles 12, 13, 14, 0x0, 14, 13, 15, 0x0
gsSPVertex amp_seg8_vertex_08003160, 16, 0
gsSP2Triangles 0, 1, 2, 0x0, 1, 0, 3, 0x0
gsSP2Triangles