2020-10-23 02:28:24 +02:00
### Build Options ###
# Override these options in settings.mk or with `make SETTING=value'.
BASEROM = baserom.z64
TARGET = papermario
COMPARE = 1
NON_MATCHING = 0
2020-10-28 22:34:04 +01:00
WATCH_INCLUDES = 1
2020-10-23 02:28:24 +02:00
- i n c l u d e s e t t i n g s . m k
# Fail early if baserom does not exist
i f e q ( $( wildcard $ ( BASEROM ) ) , )
$( error Baserom `$ ( BASEROM ) ' not found .)
e n d i f
2020-05-12 07:04:13 +02:00
2020-10-28 21:57:00 +01:00
# NON_MATCHING=1 implies COMPARE=0
i f e q ( $( NON_MATCHING ) , 1 )
o v e r r i d e COMPARE = 0
e n d i f
2020-10-23 02:28:24 +02:00
2020-10-29 18:45:40 +01:00
# PERMUTER=1 implies WATCH_INCLUDES=0
i f e q ( $( PERMUTER ) , 1 )
o v e r r i d e WATCH_INCLUDES = 0
e n d i f
2020-10-23 02:28:24 +02:00
### Output ###
2019-03-07 00:33:29 +01:00
2020-10-28 21:57:00 +01:00
BUILD_DIR := build
ROM := $( TARGET) .z64
ELF := $( BUILD_DIR) /$( TARGET) .elf
LD_SCRIPT := $( TARGET) .ld
LD_MAP := $( BUILD_DIR) /$( TARGET) .map
ASSETS_BIN := $( BUILD_DIR) /bin/assets/assets.bin
2020-11-07 13:06:38 +01:00
MSG_BIN := $( BUILD_DIR) /msg.bin
2020-11-11 14:52:04 +01:00
NPC_BIN := $( BUILD_DIR) /sprite/npc.bin
2020-11-11 17:33:55 +01:00
GENERATED_HEADERS := include/ld_addrs.h include/sprite
2020-04-28 02:22:56 +02:00
2020-10-23 02:28:24 +02:00
### Tools ###
2020-10-28 21:57:00 +01:00
PYTHON := python3
N64CKSUM := tools/n64crc
SPLAT_YAML := tools/splat.yaml
2020-10-23 02:28:24 +02:00
SPLAT = $( PYTHON) tools/n64splat/split.py $( BASEROM) $( SPLAT_YAML) .
YAY0COMPRESS = tools/Yay0compress
EMULATOR = mupen64plus
2019-03-07 00:33:29 +01:00
2020-10-23 02:28:24 +02:00
### Compiler Options ###
2020-10-28 21:57:00 +01:00
CROSS := mips-linux-gnu-
AS := $( CROSS) as
OLD_AS := tools/mips-nintendo-nu64-as
CC := tools/cc1
2020-12-05 23:23:18 +01:00
CPP := cpp
2020-10-28 21:57:00 +01:00
LD := $( CROSS) ld
OBJCOPY := $( CROSS) objcopy
2020-05-12 05:00:21 +02:00
2020-12-05 23:17:55 +01:00
UNAME_S := $( shell uname -s)
i f e q ( $( UNAME_S ) , L i n u x )
OS = linux
ICONV := iconv --from UTF-8 --to SHIFT-JIS
e n d i f
i f e q ( $( UNAME_S ) , D a r w i n )
OS = mac
ICONV := tools/iconv.py UTF-8 SHIFT-JIS
e n d i f
OLD_AS = tools/$( OS) /mips-nintendo-nu64-as
CC = tools/$( OS) /cc1
2020-10-29 18:45:40 +01:00
CPPFLAGS := -Iinclude -Isrc -D _LANGUAGE_C -ffreestanding -DF3DEX_GBI_2 -D_MIPS_SZLONG= 32 -Wundef -Wcomment
2020-10-28 21:57:00 +01:00
ASFLAGS := -EB -Iinclude -march= vr4300 -mtune= vr4300
OLDASFLAGS := -EB -Iinclude -G 0
CFLAGS := -O2 -quiet -G 0 -mcpu= vr4300 -mfix4300 -mips3 -mgp32 -mfp32 -Wimplicit -Wuninitialized -Wshadow
2020-11-29 18:05:24 +01:00
LDFLAGS := -T undefined_syms.txt -T undefined_syms_auto.txt -T undefined_funcs.txt -T undefined_funcs_auto.txt -T $( BUILD_DIR) /$( LD_SCRIPT) -Map $( LD_MAP) --no-check-sections
2020-04-28 12:45:56 +02:00
2020-10-29 18:45:40 +01:00
i f e q ( $( WATCH_INCLUDES ) , 1 )
CPPMFLAGS = -MP -MD -MF $@ .mk -MT $( BUILD_DIR) /$* .d
MDEPS = $( BUILD_DIR) /%.d
e n d i f
2020-10-23 11:36:00 +02:00
i f e q ( $( NON_MATCHING ) , 1 )
CPPFLAGS += -DNON_MATCHING
e n d i f
2019-03-07 00:33:29 +01:00
2020-10-28 21:57:00 +01:00
### Sources ###
i n c l u d e s o u r c e s . m k
2020-11-22 01:34:13 +01:00
i f e q ( $( PERMUTER ) , 1 )
override OBJECTS : =$( filter %.c .o , $ ( OBJECTS ) )
e n d i f
2020-10-28 23:08:14 +01:00
%.d : ;
2020-10-28 22:34:04 +01:00
i f e q ( $( WATCH_INCLUDES ) , 1 )
2020-10-28 23:08:14 +01:00
- i n c l u d e $( foreach obj , $ ( OBJECTS ) , $ ( obj ) .mk )
2020-10-28 22:34:04 +01:00
e n d i f
2020-10-28 21:57:00 +01:00
2020-10-23 02:28:24 +02:00
### Targets ###
2019-03-07 00:33:29 +01:00
clean :
2020-12-03 22:06:15 +01:00
rm -rf $( BUILD_DIR) bin msg img sprite .splat_cache
2020-08-13 04:13:48 +02:00
2020-10-23 11:36:20 +02:00
clean-code :
rm -rf $( BUILD_DIR) /src
2020-11-30 05:14:01 +01:00
tools :
2020-10-23 14:47:07 +02:00
make -C tools
2020-08-13 04:13:48 +02:00
2020-11-30 05:14:01 +01:00
setup : clean submodules tools split $( LD_SCRIPT )
2020-08-13 04:13:48 +02:00
submodules :
git submodule update --init --recursive
split :
2020-12-02 23:26:08 +01:00
$( SPLAT) --modes ld bin Yay0 PaperMarioMapFS PaperMarioMessages img PaperMarioNpcSprites --new
2020-08-13 04:13:48 +02:00
2020-10-31 19:30:16 +01:00
split-% :
2020-12-02 23:26:08 +01:00
$( SPLAT) --modes ld $* --verbose --new
2020-10-28 21:57:00 +01:00
2020-10-16 00:11:56 +02:00
split-all :
2020-12-03 22:06:15 +01:00
$( SPLAT) --modes all
2020-10-23 02:28:24 +02:00
test : $( ROM )
$( EMULATOR) $<
2020-10-12 20:46:04 +02:00
2020-10-28 21:57:00 +01:00
# Compressed files
%.Yay0 : %
@mkdir -p $( shell dirname $@ )
$( YAY0COMPRESS) $< $@
$(BUILD_DIR)/%.bin.Yay0 : %.bin
@mkdir -p $( shell dirname $@ )
$( YAY0COMPRESS) $< $@
2020-04-28 02:22:56 +02:00
2020-10-28 21:57:00 +01:00
# Data objects
$(BUILD_DIR)/%.bin.o : %.bin
@mkdir -p $( shell dirname $@ )
$( LD) -r -b binary -o $@ $<
2020-10-23 02:28:24 +02:00
2020-10-28 21:57:00 +01:00
# Compressed data objects
$(BUILD_DIR)/%.Yay0.o : $( BUILD_DIR ) /%.bin .Yay 0
@mkdir -p $( shell dirname $@ )
$( LD) -r -b binary -o $@ $<
2020-10-23 02:28:24 +02:00
2020-10-28 21:57:00 +01:00
# Compile C files
2020-11-07 02:09:11 +01:00
$(BUILD_DIR)/%.c.o : %.c $( MDEPS ) | $( GENERATED_HEADERS )
2020-10-23 02:28:24 +02:00
@mkdir -p $( shell dirname $@ )
2020-12-05 23:17:55 +01:00
$( CPP) $( CPPFLAGS) -o - $( CPPMFLAGS) $< | $( ICONV) | $( CC) $( CFLAGS) -o - | $( OLD_AS) $( OLDASFLAGS) -o $@ -
2020-10-23 22:06:06 +02:00
2020-10-28 21:57:00 +01:00
# Compile C files (with DSL macros)
2020-11-11 17:33:55 +01:00
$(foreach cfile, $(DSL_C_FILES), $(BUILD_DIR)/$(cfile).o) : $( BUILD_DIR ) /%.c .o : %.c $( MDEPS ) tools /compile_dsl_macros .py | $( GENERATED_HEADERS )
2020-10-28 21:57:00 +01:00
@mkdir -p $( shell dirname $@ )
2020-12-05 23:17:55 +01:00
$( CPP) $( CPPFLAGS) -o - $< $( CPPMFLAGS) | $( PYTHON) tools/compile_dsl_macros.py | $( ICONV) | $( CC) $( CFLAGS) -o - | $( OLD_AS) $( OLDASFLAGS) -o $@ -
2020-04-28 02:22:56 +02:00
2020-10-28 21:57:00 +01:00
# Assemble handwritten ASM
$(BUILD_DIR)/%.s.o : %.s
2020-10-23 02:28:24 +02:00
@mkdir -p $( shell dirname $@ )
$( AS) $( ASFLAGS) -o $@ $<
2020-11-29 06:22:33 +01:00
# Data
$(BUILD_DIR)/data/%.data.o : asm /data /%.data .s
@mkdir -p $( shell dirname $@ )
$( AS) $( ASFLAGS) -o $@ $<
2020-11-29 20:37:53 +01:00
# Rodata
$(BUILD_DIR)/rodata/%.rodata.o : asm /data /%.rodata .s
@mkdir -p $( shell dirname $@ )
$( AS) $( ASFLAGS) -o $@ $<
2020-10-31 19:30:16 +01:00
# Images
$(BUILD_DIR)/%.png.o : $( BUILD_DIR ) /%.png
$( LD) -r -b binary -o $@ $<
$(BUILD_DIR)/%.rgba16.png : %.png
@mkdir -p $( shell dirname $@ )
$( PYTHON) tools/convert_image.py rgba16 $< $@ $( IMG_FLAGS)
$(BUILD_DIR)/%.rgba32.png : %.png
@mkdir -p $( shell dirname $@ )
$( PYTHON) tools/convert_image.py rgba32 $< $@ $( IMG_FLAGS)
$(BUILD_DIR)/%.ci8.png : %.png
@mkdir -p $( shell dirname $@ )
$( PYTHON) tools/convert_image.py ci8 $< $@ $( IMG_FLAGS)
$(BUILD_DIR)/%.ci4.png : %.png
@mkdir -p $( shell dirname $@ )
$( PYTHON) tools/convert_image.py ci4 $< $@ $( IMG_FLAGS)
2020-11-02 17:39:29 +01:00
$(BUILD_DIR)/%.palette.png : %.png
2020-10-31 19:30:16 +01:00
@mkdir -p $( shell dirname $@ )
2020-11-02 17:39:29 +01:00
$( PYTHON) tools/convert_image.py palette $< $@ $( IMG_FLAGS)
2020-10-31 19:30:16 +01:00
$(BUILD_DIR)/%.ia4.png : %.png
@mkdir -p $( shell dirname $@ )
$( PYTHON) tools/convert_image.py ia4 $< $@ $( IMG_FLAGS)
$(BUILD_DIR)/%.ia8.png : %.png
@mkdir -p $( shell dirname $@ )
$( PYTHON) tools/convert_image.py ia8 $< $@ $( IMG_FLAGS)
$(BUILD_DIR)/%.ia16.png : %.png
@mkdir -p $( shell dirname $@ )
$( PYTHON) tools/convert_image.py ia16 $< $@ $( IMG_FLAGS)
$(BUILD_DIR)/%.i4.png : %.png
@mkdir -p $( shell dirname $@ )
$( PYTHON) tools/convert_image.py i4 $< $@ $( IMG_FLAGS)
$(BUILD_DIR)/%.i8.png : %.png
@mkdir -p $( shell dirname $@ )
$( PYTHON) tools/convert_image.py i8 $< $@ $( IMG_FLAGS)
2020-11-07 02:09:11 +01:00
# Assets
2020-10-28 21:57:00 +01:00
ASSET_FILES := $( foreach asset, $( ASSETS) , $( BUILD_DIR) /bin/assets/$( asset) )
YAY0_ASSET_FILES := $( foreach asset, $( filter-out %_tex, $( ASSET_FILES) ) , $( asset) .Yay0)
$(BUILD_DIR)/bin/assets/% : bin /assets /%.bin
2020-10-23 02:28:24 +02:00
@mkdir -p $( shell dirname $@ )
2020-10-28 21:57:00 +01:00
@cp $< $@
2020-10-31 03:28:18 +01:00
$(ASSETS_BIN) : $( ASSET_FILES ) $( YAY 0_ASSET_FILES ) sources .mk
2020-10-23 02:28:24 +02:00
@mkdir -p $( shell dirname $@ )
2020-10-28 21:57:00 +01:00
@echo " building $@ "
@$( PYTHON) tools/build_assets_bin.py $@ $( ASSET_FILES)
$(ASSETS_BIN : .bin =.o ): $( ASSETS_BIN )
$( LD) -r -b binary -o $@ $<
2020-10-18 05:54:32 +02:00
2020-11-07 02:09:11 +01:00
# Messages
$(MSG_BIN) : $( MESSAGES )
@mkdir -p $( shell dirname $@ )
@echo " building $@ "
@$( PYTHON) tools/compile_messages.py $@ /dev/null $( MESSAGES)
$(MSG_BIN : .bin =.o ): $( MSG_BIN )
2020-11-11 14:52:04 +01:00
$( LD) -r -b binary -o $@ $<
# Sprites
2020-12-02 23:26:08 +01:00
$(foreach npc, $(NPC_SPRITES), $(eval $(BUILD_DIR)/sprite/npc/$(npc) :: $( shell find sprite /npc /$ ( npc ) -type f 2> /dev /null ) )) # dependencies
2020-11-11 17:33:55 +01:00
NPC_DIRS := $( foreach npc, $( NPC_SPRITES) , sprite/npc/$( npc) )
NPC_YAY0 := $( foreach npc, $( NPC_SPRITES) , $( BUILD_DIR) /sprite/npc/$( npc) .Yay0)
$(BUILD_DIR)/sprite/npc/% :: sprite /npc /% tools /compile_npc_sprite .py
2020-11-07 02:09:11 +01:00
@mkdir -p $( shell dirname $@ )
2020-11-11 14:52:04 +01:00
$( PYTHON) tools/compile_npc_sprite.py $@ $<
2020-11-11 17:33:55 +01:00
$(NPC_BIN) : $( NPC_YAY 0) tools /compile_npc_sprites .py
2020-11-07 02:09:11 +01:00
@mkdir -p $( shell dirname $@ )
2020-11-11 14:52:04 +01:00
@echo " building $@ "
2020-11-11 17:33:55 +01:00
@$( PYTHON) tools/compile_npc_sprites.py $@ $( NPC_YAY0)
2020-11-11 14:52:04 +01:00
$(NPC_BIN : .bin =.o ): $( NPC_BIN )
2020-11-07 02:09:11 +01:00
$( LD) -r -b binary -o $@ $<
2020-11-11 17:33:55 +01:00
include/sprite/npc/%.h : sprite /npc /%/SpriteSheet .xml tools /gen_sprite_animations_h .py
@mkdir -p $( shell dirname $@ )
@echo " building $@ "
@$( PYTHON) tools/gen_sprite_animations_h.py $@ sprite/npc/$* $( NPC_DIRS)
include/sprite : $( foreach dir , $ ( NPC_DIRS ) , include /$ ( dir ) .h )
2020-11-07 02:09:11 +01:00
2020-10-28 21:57:00 +01:00
$(LD_SCRIPT) : $( SPLAT_YAML )
$( SPLAT) --modes ld
2020-10-18 05:54:32 +02:00
2020-10-28 21:57:00 +01:00
$(BUILD_DIR)/$(LD_SCRIPT) : $( LD_SCRIPT )
@mkdir -p $( shell dirname $@ )
$( CPP) -P -DBUILD_DIR= $( BUILD_DIR) -o $@ $<
2020-10-19 23:29:40 +02:00
2020-10-28 21:57:00 +01:00
$(ROM) : $( BUILD_DIR ) /$( TARGET ) .bin
@cp $< $@
i f e q ( $( COMPARE ) , 1 )
@sha1sum -c checksum.sha1 || ( echo 'The build succeeded, but did not match the base ROM. This is expected if you are making changes to the game. To skip this check, use "make COMPARE=0".' && false )
2020-10-23 02:28:24 +02:00
e n d i f
2020-10-19 23:29:40 +02:00
2020-10-28 21:57:00 +01:00
$(BUILD_DIR)/$(TARGET).elf : $( BUILD_DIR ) /$( LD_SCRIPT ) $( OBJECTS )
$( LD) $( LDFLAGS) -o $@
2019-03-07 00:33:29 +01:00
2020-10-29 18:45:40 +01:00
$(BUILD_DIR)/$(TARGET).bin : $( BUILD_DIR ) /$( TARGET ) .elf
$( OBJCOPY) $< $@ -O binary
2020-11-02 20:18:21 +01:00
include/ld_addrs.h : $( BUILD_DIR ) /$( LD_SCRIPT )
2020-11-29 19:32:02 +01:00
grep -E "[^\. ]+ =" $< -o | sed 's/^/extern void* /; s/ =/;/' > $@
2020-04-25 07:52:11 +02:00
2020-10-23 02:28:24 +02:00
### Make Settings ###
2020-11-30 05:14:01 +01:00
.PHONY : clean tools test setup submodules split $( ROM ) include /sprite
2020-10-28 21:57:00 +01:00
.DELETE_ON_ERROR :
.SECONDARY :
.PRECIOUS : $( ROM ) %.Yay 0
2020-10-23 02:28:24 +02:00
.DEFAULT_GOAL := $( ROM)
# Remove built-in implicit rules to improve performance
MAKEFLAGS += --no-builtin-rules
2020-10-29 18:45:40 +01:00
# Fail targets if any command in the pipe exits with error
SHELL = /bin/bash -e -o pipefail