################################################################################ # Options # ROMID - The ROM version to build. # # Can be set in your environment using # $ export ROMID=... # # Supported values: # * ntsc-beta # * ntsc-1.0 # * ntsc-final # * pal-beta # * pal-final # * jpn-final ROMID ?= ntsc-final # MATCHING - Whether to build a matching ROM (1) or a custom one (0). # # Build a matching ROM to prove that the decompilation is accurate. # # If enabled, all further options are ignored and are set automatically. MATCHING = 1 # COMPILER - Choose which compiler to use. # # A matching build uses ido. For non-matching builds, use gcc for performance. # # gcc is currently only supported when ROMID is ntsc-1.0 or ntsc-final. # # Supported values: ido, gcc COMPILER = gcc # GCC_OPT_LVL - the optimisation level if building with gcc. # # Supported values: -O0, -O1, -O2, -Os GCC_OPT_LVL = -Os # PAL - Whether to use the PAL television standard (1) or NTSC (0). # # PAL runs at 50Hz while NTSC is 60Hz, and PAL uses different screen dimensions. PAL = 0 # ROMALLOCATION # # The lib, data and game segments are compressed in the final ROM. # # These options define how much space is allocated for the compressed segments. # # If any value is not big enough, the build system will tell you which one needs # to be changed and what to change it to. ROMALLOCATION_DATA = 0x015000 ROMALLOCATION_LIB = 0x038800 ROMALLOCATION_GAME = 0x144ee0 # ROM_SIZE - The desired ROM size in megabytes. # # All versions of the retail ROM are 32MB. # # If this is too low you might get this error from ld: # "final link failed: memory exhausted" ROM_SIZE := 32 ################################################################################ # The VERSION constant is used in the source to handle version-specific code. ifeq ($(ROMID), ntsc-beta) VERSION = 0 endif ifeq ($(ROMID), ntsc-1.0) VERSION = 1 endif ifeq ($(ROMID), ntsc-final) VERSION = 2 endif ifeq ($(ROMID), pal-beta) VERSION = 3 endif ifeq ($(ROMID), pal-final) VERSION = 4 endif ifeq ($(ROMID), jpn-final) VERSION = 5 endif # Set runtime piracy checks off. We turn this on for matching builds if needed. PIRACYCHECKS = 0 # A magic value that's only used to produce a matching ROM. # It's required because old-school zlib was influenced by uninitialised data. # ZIPMAGIC is the value of the uninitialised data. We set it per version for # matching builds, otherwise 0 is fine. ZIPMAGIC = 0x0000 # This is also a value that's only used to produce a matching ROM. # The final ROM has some duplicate bytes, and there doesn't seem to be any logic # for determining how many bytes are duplicated. COPYLEN = 2 # If a matching build has been requested, override directives as needed. ifeq ($(MATCHING), 1) COMPILER = ido ROMALLOCATION_DATA = 0x015000 ROMALLOCATION_LIB = 0x038800 ROM_SIZE = 32 ifeq ($(ROMID), ntsc-beta) PAL = 0 PIRACYCHECKS = 0 ROMALLOCATION_DATA = 0x012000 ROMALLOCATION_LIB = 0x02f800 ROMALLOCATION_GAME = 0x105000 endif ifeq ($(ROMID), ntsc-1.0) PAL = 0 PIRACYCHECKS = 1 ROMALLOCATION_GAME = 0x144ee0 ZIPMAGIC = 0xffff endif ifeq ($(ROMID), ntsc-final) PAL = 0 PIRACYCHECKS = 1 ROMALLOCATION_GAME = 0x144ee0 ZIPMAGIC = 0xffff endif ifeq ($(ROMID), pal-beta) PAL = 1 PIRACYCHECKS = 1 ROMALLOCATION_GAME = 0x1306f0 ZIPMAGIC = 0x0c00 COPYLEN = 6 endif ifeq ($(ROMID), pal-final) PAL = 1 PIRACYCHECKS = 1 ROMALLOCATION_GAME = 0x1306f0 ZIPMAGIC = 0xaf00 endif ifeq ($(ROMID), jpn-final) PAL = 0 PIRACYCHECKS = 1 ROMALLOCATION_GAME = 0x1296f0 ZIPMAGIC = 0x0002 COPYLEN = 4 endif endif DEFINES := \ VERSION=$(VERSION) \ MATCHING=$(MATCHING) \ PAL=$(PAL) \ PIRACYCHECKS=$(PIRACYCHECKS) \ ROM_SIZE=$(ROM_SIZE) C_DEFINES := $(foreach d,$(DEFINES),-D$(d)) AS_DEFINES := $(foreach d,$(DEFINES),--defsym $(d)) --defsym _LANGUAGE_ASSEMBLY=1 A_DIR := src/assets/$(ROMID) B_DIR := build/$(ROMID) E_DIR := extracted/$(ROMID) ifneq ($(strip $(MIPS_BINUTILS_PREFIX)),) TOOLCHAIN := $(MIPS_BINUTILS_PREFIX) else ifeq ($(shell type mips-elf-ld >/dev/null 2>/dev/null; echo $$?), 0) TOOLCHAIN := mips-elf else ifeq ($(shell type mips-linux-gnu-ld >/dev/null 2>/dev/null; echo $$?), 0) TOOLCHAIN := mips-linux-gnu else ifeq ($(shell type mips64-elf-ld >/dev/null 2>/dev/null; echo $$?), 0) TOOLCHAIN := mips64-elf else ifeq ($(shell type mips64-linux-gnu-ld >/dev/null 2>/dev/null; echo $$?), 0) TOOLCHAIN := mips64-linux-gnu else $(error You need to install a suitable MIPS binutils toolchain (eg. mips-elf-ld)) endif # Asset files are files which are included in the "files" segment of the ROM. # This excludes animations, fonts, SFX, MIDI and textures. # And because setup files are part of the files segment they are included here, # despite them being written in C. # # Create names such as $(B_DIR)/assets/files/PfooZ. # These names (with .o added) will be dependenices for ld. ASSET_FILES := \ $(patsubst $(A_DIR)/files/audio/%.mp3, $(B_DIR)/assets/files/A%M, $(shell find $(A_DIR) -path '*/files/audio/*.mp3')) \ $(patsubst $(A_DIR)/files/chrs/%.bin, $(B_DIR)/assets/files/C%Z, $(shell find $(A_DIR) -path '*/files/chrs/*.bin')) \ $(patsubst $(A_DIR)/files/guns/%.bin, $(B_DIR)/assets/files/G%Z, $(shell find $(A_DIR) -path '*/files/guns/*.bin')) \ $(patsubst $(A_DIR)/files/props/%.bin, $(B_DIR)/assets/files/P%Z, $(shell find $(A_DIR) -path '*/files/props/*.bin')) \ $(patsubst src/setups/%.c, $(B_DIR)/assets/files/U%Z, $(shell find src/setups -name '*.c')) \ $(patsubst $(A_DIR)/files/bgdata/%.seg, $(B_DIR)/assets/files/bgdata/%.seg, $(shell find $(A_DIR) -path '*/files/bgdata/*.seg')) \ $(B_DIR)/assets/files/ob/ob_mid.seg.o LANG_JSON_FILES := $(shell find $(A_DIR) -path '*/lang/*.json') PADS_JSON_FILES := $(shell find $(A_DIR) -path '*/pads/*.json') TILES_JSON_FILES := $(shell find $(A_DIR) -path '*/tiles/*.json') LANG_O_FILES := \ $(patsubst $(A_DIR)/lang/%.json, $(B_DIR)/assets/files/L%E.o, $(LANG_JSON_FILES)) \ $(patsubst $(A_DIR)/lang/%.json, $(B_DIR)/assets/files/L%J.o, $(LANG_JSON_FILES)) \ $(patsubst $(A_DIR)/lang/%.json, $(B_DIR)/assets/files/L%P.o, $(LANG_JSON_FILES)) \ $(patsubst $(A_DIR)/lang/%.json, $(B_DIR)/assets/files/L%_str_f.o, $(LANG_JSON_FILES)) \ $(patsubst $(A_DIR)/lang/%.json, $(B_DIR)/assets/files/L%_str_g.o, $(LANG_JSON_FILES)) \ $(patsubst $(A_DIR)/lang/%.json, $(B_DIR)/assets/files/L%_str_i.o, $(LANG_JSON_FILES)) \ $(patsubst $(A_DIR)/lang/%.json, $(B_DIR)/assets/files/L%_str_s.o, $(LANG_JSON_FILES)) PADS_O_FILES := $(patsubst $(A_DIR)/pads/%.json, $(B_DIR)/assets/files/bgdata/bg_%_padsZ.o, $(PADS_JSON_FILES)) TILES_O_FILES := $(patsubst $(A_DIR)/tiles/%.json, $(B_DIR)/assets/files/bgdata/bg_%_tilesZ.o, $(TILES_JSON_FILES)) C_FILES := $(shell find src/lib src/game src/inflate -name '*.c') S_FILES := $(shell find src/lib src/game src/preamble -name '*.s') C_O_FILES := $(patsubst src/%.c, $(B_DIR)/%.o, $(C_FILES)) S_O_FILES := $(patsubst src/%.s, $(B_DIR)/%.o, $(S_FILES)) O_FILES := \ $(C_O_FILES) \ $(S_O_FILES) \ $(patsubst %, %.o, $(ASSET_FILES)) \ $(LANG_O_FILES) \ $(PADS_O_FILES) \ $(TILES_O_FILES) \ $(B_DIR)/assets/animations.o \ $(B_DIR)/assets/copyrightZ.o \ $(B_DIR)/assets/files/list.o \ $(B_DIR)/assets/fonts/bankgothic.o \ $(B_DIR)/assets/fonts/handelgothiclg.o \ $(B_DIR)/assets/fonts/handelgothicmd.o \ $(B_DIR)/assets/fonts/handelgothicsm.o \ $(B_DIR)/assets/fonts/handelgothicxs.o \ $(B_DIR)/assets/fonts/numeric.o \ $(B_DIR)/assets/fonts/ocralg.o \ $(B_DIR)/assets/fonts/ocramd.o \ $(B_DIR)/assets/fonts/tahoma.o \ $(B_DIR)/assets/fonts/zurich.o \ $(B_DIR)/assets/mpstrings/mpstringsE.o \ $(B_DIR)/assets/mpstrings/mpstringsF.o \ $(B_DIR)/assets/mpstrings/mpstringsG.o \ $(B_DIR)/assets/mpstrings/mpstringsI.o \ $(B_DIR)/assets/mpstrings/mpstringsJ.o \ $(B_DIR)/assets/mpstrings/mpstringsP.o \ $(B_DIR)/assets/mpstrings/mpstringsS.o \ $(B_DIR)/assets/seq.ctl.o \ $(B_DIR)/assets/seq.tbl.o \ $(B_DIR)/assets/sequences.o \ $(B_DIR)/assets/sfx.ctl.o \ $(B_DIR)/assets/sfx.tbl.o \ $(B_DIR)/assets/textureslist.o \ $(B_DIR)/bootloader.o \ $(B_DIR)/firingrange.o \ $(B_DIR)/getitle.o \ $(B_DIR)/mpconfigs.o \ $(B_DIR)/romheader.o \ $(B_DIR)/rsp/asp.data.o \ $(B_DIR)/rsp/asp.text.o \ $(B_DIR)/rsp/gsp.data.o \ $(B_DIR)/rsp/gsp.text.o \ $(B_DIR)/rsp/rspboot.text.o \ $(B_DIR)/textureconfig.o # ntsc-beta doesn't have this segment ifneq ($(ROMID), ntsc-beta) O_FILES := $(O_FILES) $(B_DIR)/assets/accessingpakZ.o endif ifeq ($(ROMID), jpn-final) O_FILES := $(O_FILES) $(B_DIR)/assets/fonts/jpn.o else O_FILES := $(O_FILES) \ $(B_DIR)/assets/fonts/jpnsingle.o \ $(B_DIR)/assets/fonts/jpnmulti.o endif INCLUDES = \ -I include \ -I include/PR \ -I src/include \ -I src/generated/$(ROMID) \ -I src/lib/ultra/audio \ AS := $(TOOLCHAIN)-as ASFLAGS = -march=vr4300 -mabi=32 $(INCLUDES) $(AS_DEFINES) ifeq ($(COMPILER), ido) RECOMP_FILES := \ build/recomp/5.3/as1 \ build/recomp/5.3/cc \ build/recomp/5.3/cfe \ build/recomp/5.3/err.english.cc \ build/recomp/5.3/ugen \ build/recomp/5.3/ujoin \ build/recomp/5.3/uld \ build/recomp/5.3/umerge \ build/recomp/5.3/uopt \ build/recomp/5.3/usplit \ build/recomp/7.1/as1 \ build/recomp/7.1/cc \ build/recomp/7.1/cfe \ build/recomp/7.1/err.english.cc \ build/recomp/7.1/ugen \ build/recomp/7.1/uopt LOOPUNROLL_C_FILES := \ src/lib/ultra/gu/frustum.c \ src/lib/ultra/gu/mtxutil.c \ src/lib/ultra/gu/ortho.c \ src/lib/ultra/io/conteepread.c \ src/lib/ultra/io/conteepwrite.c \ src/lib/ultra/io/contpfs.c \ src/lib/ultra/io/contramread.c \ src/lib/ultra/io/contramwrite.c \ src/lib/ultra/io/gbpakgetstatus.c \ src/lib/ultra/io/gbpakreadid.c \ src/lib/ultra/io/motor.c \ src/lib/ultra/io/pfschecker.c \ src/lib/ultra/io/pfsfreeblocks.c \ src/lib/ultra/io/pfsgetstatus.c \ src/lib/ultra/io/pfsinitpak2.c MIPS3_C_FILES := \ src/lib/rng_c.c \ src/lib/ultra/libc/ll.c \ src/lib/ultra/libc/llcvt.c G_C_FILES := \ $(shell find src/lib/ultra/audio -name '*.c') \ $(shell find src/lib/naudio -name '*.c') \ $(shell find src/lib/mp3 -name '*.c') \ src/lib/lib_2fc60.c \ src/lib/lib_317f0.c \ src/lib/lib_39c80.c \ src/lib/lib_3e3e0.c \ src/lib/mp3.c \ src/lib/speaker.c O1_C_FILES := \ src/lib/lib_04f60nb.c \ src/lib/ultra/io/ai.c \ src/lib/ultra/io/aisetnextbuf.c \ src/lib/ultra/io/conteeplongread.c \ src/lib/ultra/io/contquery.c \ src/lib/ultra/io/controller.c \ src/lib/ultra/io/dpctr.c \ src/lib/ultra/io/pigetcmdq.c \ src/lib/ultra/io/pidma.c \ src/lib/ultra/io/si.c \ src/lib/ultra/io/sp.c \ src/lib/ultra/io/spsetpc.c \ src/lib/ultra/io/sptaskyielded.c \ src/lib/ultra/io/vi.c \ src/lib/ultra/io/viblack.c \ src/lib/ultra/io/vigetcurrframebuf.c \ src/lib/ultra/io/vigetnextframebuf.c \ src/lib/ultra/io/visetevent.c \ src/lib/ultra/io/visetmode.c \ src/lib/ultra/io/visetxscale.c \ src/lib/ultra/io/visetyscale.c \ src/lib/ultra/io/viswapbuf.c \ src/lib/ultra/libc/ll.c \ src/lib/ultra/libc/llcvt.c \ src/lib/ultra/os/atomic.c \ src/lib/ultra/os/createmesgqueue.c \ src/lib/ultra/os/destroythread.c \ src/lib/ultra/os/getmemsize.c \ src/lib/ultra/os/gettime.c \ src/lib/ultra/os/initialize2.c \ src/lib/ultra/os/jammesg.c \ src/lib/ultra/os/recvmesg.c \ src/lib/ultra/os/resetglobalintmask.c \ src/lib/ultra/os/sendmesg.c \ src/lib/ultra/os/seteventmesg.c \ src/lib/ultra/os/setglobalintmask.c \ src/lib/ultra/os/setthreadpri.c \ src/lib/ultra/os/settimer.c \ src/lib/ultra/os/startthread.c \ src/lib/ultra/os/stopthread.c \ src/lib/ultra/os/stoptimer.c \ src/lib/ultra/os/thread.c \ src/lib/ultra/os/timerintr.c \ src/lib/ultra/os/virtualtophysical.c \ src/lib/ultra/os/yieldthread.c ifeq ($(ROMID), ntsc-beta) O1_C_FILES := $(O1_C_FILES) src/lib/ultra/io/pfsisplug.c endif O3_C_FILES := \ src/lib/ultra/gu/align.c \ src/lib/ultra/gu/frustum.c \ src/lib/ultra/gu/ortho.c \ src/lib/ultra/gu/scale.c \ src/lib/ultra/libc/xprintf.c IDO71_C_FILES := \ $(shell find src/lib/ultra/audio -name '*.c') \ $(shell find src/lib/naudio -name '*.c') \ $(shell find src/lib/mp3 -name '*.c') \ src/lib/lib_2fc60.c \ src/lib/lib_39c80.c LOOPUNROLL_O_FILES = $(patsubst src/%.c, $(B_DIR)/%.o, $(LOOPUNROLL_C_FILES)) MIPS3_O_FILES = $(patsubst src/%.c, $(B_DIR)/%.o, $(MIPS3_C_FILES)) G_O_FILES = $(patsubst src/%.c, $(B_DIR)/%.o, $(G_C_FILES)) O1_O_FILES = $(patsubst src/%.c, $(B_DIR)/%.o, $(O1_C_FILES)) O3_O_FILES = $(patsubst src/%.c, $(B_DIR)/%.o, $(O3_C_FILES)) IDO71_O_FILES = $(patsubst src/%.c, $(B_DIR)/%.o, $(IDO71_C_FILES)) LOOPUNROLL := -Wo,-loopunroll,0 MIPSISET := -mips2 OPT_LVL := -O2 CC := build/recomp/5.3/cc $(LOOPUNROLL_O_FILES): LOOPUNROLL := $(MIPS3_O_FILES): MIPSISET := -mips3 $(G_O_FILES): OPT_LVL := -g $(O1_O_FILES): OPT_LVL := -O1 $(O3_O_FILES): OPT_LVL := -O3 $(IDO71_O_FILES): CC := build/recomp/7.1/cc CFLAGS = $(C_DEFINES) $(INCLUDES) \ $(LOOPUNROLL) \ -Wab,-r4300_mul \ -non_shared \ -Olimit 2000 \ -G 0 \ -Xcpluscomm \ -w2 \ -Wab,-w \ -woff 581,649,819,820,821,838,852 \ $(MIPSISET) -32 # Files containing GLOBAL_ASM must be built with the asm_processor ifeq ($(MATCHING), 1) GLOBALASM_C_FILES != grep -rl 'GLOBAL_ASM(' $(C_FILES) GLOBALASM_O_FILES = $(patsubst src/%.c, $(B_DIR)/%.o, $(GLOBALASM_C_FILES)) $(GLOBALASM_O_FILES): CC := /usr/bin/env python3 tools/asm_processor/build.py $(CC) -- $(TOOLCHAIN)-as $(ASFLAGS) -- endif else ifeq ($(COMPILER), gcc) CC := $(TOOLCHAIN)-gcc $(C_O_FILES): OPT_LVL := $(GCC_OPT_LVL) CFLAGS := $(C_DEFINES) -DAVOID_UB=1 $(INCLUDES) \ -EB \ -march=vr4300 \ -mabi=32 \ -mfix4300 \ -mdivide-breaks \ -mno-abicalls \ -ffreestanding \ -fno-builtin \ -fno-common \ -fno-inline-functions \ -fno-merge-constants \ -fno-strict-aliasing \ -fno-zero-initialized-in-bss \ -funsigned-char \ -fwrapv \ -Wall \ -Werror \ -Wno-address \ -Wno-aggressive-loop-optimizations \ -Wno-array-bounds \ -Wno-int-in-bool-context \ -Wno-int-to-pointer-cast \ -Wno-maybe-uninitialized \ -Wno-misleading-indentation \ -Wno-missing-braces \ -Wno-multichar \ -Wno-pointer-sign \ -Wno-pointer-to-int-cast \ -Wno-tautological-compare \ -Wno-uninitialized \ -Wno-unused-but-set-variable \ -Wno-unused-value \ -Wno-unused-variable \ -G 0 $(B_DIR)/lib/ultra/libc/xldtob.o: CFLAGS += -ffast-math -fno-unsafe-math-optimizations else $(error The COMPILER option must be "ido" or "gcc") endif # Make ROMID available as an environment variable to all tooling. # (We use this a lot) export ROMID default: rom ################################################################################ # Recomp # ------------------------------------------------------------------------------ # The ido-static-recomp project is installed as a git submodule at tools/recomp. # The IRIX binaries are taken from that project and they are recompiled to # build/recomp// tools/recomp/recomp.cpp: @echo "Please install ido-static-recomp by running:" @echo @echo " git submodule update --init --recursive" @echo @exit 1 build/recomp/recomp: tools/recomp/recomp.cpp @mkdir -p build/recomp/5.3 @mkdir -p build/recomp/7.1 g++ tools/recomp/recomp.cpp -o build/recomp/recomp -g -lcapstone build/recomp/5.3/ugen: @mkdir -p build/recomp/5.3 g++ tools/recomp/recomp.cpp -o build/recomp/recomp-ugen53 -g -lcapstone -Dugen53 ./build/recomp/recomp-ugen53 tools/recomp/ido/5.3/usr/lib/ugen > build/recomp/5.3/ugen.c gcc tools/recomp/libc_impl.c build/recomp/5.3/ugen.c -Itools/recomp -o build/recomp/5.3/ugen -O2 -fno-strict-aliasing -lm -no-pie -DIDO53 build/recomp/5.3/cc: build/recomp/recomp ./build/recomp/recomp tools/recomp/ido/5.3/usr/bin/cc > build/recomp/5.3/cc.c gcc tools/recomp/libc_impl.c build/recomp/5.3/cc.c -Itools/recomp -o build/recomp/5.3/cc -O2 -fno-strict-aliasing -lm -no-pie -DIDO53 build/recomp/5.3/%: build/recomp/recomp ./build/recomp/recomp tools/recomp/ido/5.3/usr/lib/$* > build/recomp/5.3/$*.c gcc tools/recomp/libc_impl.c build/recomp/5.3/$*.c -Itools/recomp -o build/recomp/5.3/$* -O2 -fno-strict-aliasing -lm -no-pie -DIDO53 build/recomp/7.1/cc: build/recomp/recomp ./build/recomp/recomp tools/recomp/ido/7.1/usr/bin/cc > build/recomp/7.1/cc.c gcc tools/recomp/libc_impl.c build/recomp/7.1/cc.c -Itools/recomp -o build/recomp/7.1/cc -O2 -fno-strict-aliasing -lm -no-pie -DIDO71 build/recomp/7.1/%: build/recomp/recomp ./build/recomp/recomp tools/recomp/ido/7.1/usr/lib/$* > build/recomp/7.1/$*.c gcc tools/recomp/libc_impl.c build/recomp/7.1/$*.c -Itools/recomp -o build/recomp/7.1/$* -O2 -fno-strict-aliasing -lm -no-pie -DIDO71 build/recomp/%/err.english.cc: @mkdir -p build/recomp/$? cp tools/err.english.cc build/recomp/$* ################################################################################ # ROM Finalisation Stages # Link all objects together with ld to make stage1.elf. In this stage, the game, # lib and data segments are uncompressed and placed past the end of the ROM. $(B_DIR)/stage1.elf: $(O_FILES) ld/pd.ld cpp -DROMID=$(ROMID) -DVERSION=$(VERSION) -DROMALLOCATION_DATA=$(ROMALLOCATION_DATA) -DROMALLOCATION_LIB=$(ROMALLOCATION_LIB) -DROMALLOCATION_GAME=$(ROMALLOCATION_GAME) -DROM_SIZE=$(ROM_SIZE) -P ld/pd.ld -o $(B_DIR)/pd.ld $(TOOLCHAIN)-ld --no-check-sections -z muldefs -T $(B_DIR)/pd.ld --print-map -o $@ > $(B_DIR)/pd.map $(B_DIR)/stage1.bin: $(B_DIR)/stage1.elf $(TOOLCHAIN)-objcopy $< $@ -O binary # Build the final ROM from stage1.bin using mkrom # mkrom handles calculating the piracy checksums, zipping segments and # calculating the ROM checksum. $(B_DIR)/pd.z64: $(B_DIR)/stage1.bin tools/mkrom/mkrom tools/mkrom/mkrom $(B_DIR)/stage1.bin $(B_DIR)/pd.map $(PIRACYCHECKS) $(ZIPMAGIC) $(COPYLEN) $@ @echo -e "\033[0;32mROM written to $@\033[0m" tools/mkrom/mkrom: $(MAKE) -C tools/mkrom ################################################################################ # Testing Related # --------------------- # This works a little backwards, in that the ROM has to be built to at least # stage 2, then extract-segment is used to slice out the segments. CHECK_FILES := $(shell awk '{print $$2}' checksums.$(ROMID).md5) test: $(CHECK_FILES) @md5sum --quiet -c checksums.$(ROMID).md5 $(B_DIR)/segments/%.bin: $(B_DIR)/pd.z64 @B_DIR=$(B_DIR) tools/extract-segment $* ################################################################################ # Raw data segments $(B_DIR)/assets/fonts/%.o: $(A_DIR)/fonts/%.bin mkdir -p $(B_DIR)/assets/fonts TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/getitle.o: $(E_DIR)/getitle.bin TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/assets/seq.ctl.o: $(A_DIR)/seq.ctl TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/assets/seq.tbl.o: $(A_DIR)/seq.tbl TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/assets/sfx.ctl.o: $(A_DIR)/sfx.ctl TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/assets/sfx.tbl.o: $(A_DIR)/sfx.tbl TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ ################################################################################ # Asset Manager ASSETMGR_O_FILES := \ $(B_DIR)/assets/animations.o \ $(LANG_O_FILES) \ $(PADS_O_FILES) \ $(TILES_O_FILES) \ $(B_DIR)/assets/sequences.o \ $(B_DIR)/assets/textureslist.o \ # Anims $(B_DIR)/assets/animations.o: $(A_DIR)/animations.json tools/assetmgr/mkanims # Lang $(B_DIR)/assets/files/L%E.o: $(A_DIR)/lang/%.json tools/assetmgr/mklang $< en $(B_DIR)/assets/files/L%J.o: $(A_DIR)/lang/%.json tools/assetmgr/mklang $< jp $(B_DIR)/assets/files/L%P.o: $(A_DIR)/lang/%.json tools/assetmgr/mklang $< gb $(B_DIR)/assets/files/L%_str_f.o: $(A_DIR)/lang/%.json tools/assetmgr/mklang $< fr $(B_DIR)/assets/files/L%_str_g.o: $(A_DIR)/lang/%.json tools/assetmgr/mklang $< de $(B_DIR)/assets/files/L%_str_i.o: $(A_DIR)/lang/%.json tools/assetmgr/mklang $< it $(B_DIR)/assets/files/L%_str_s.o: $(A_DIR)/lang/%.json tools/assetmgr/mklang $< es # Pads $(B_DIR)/assets/files/bgdata/bg_%_padsZ.o: $(A_DIR)/pads/%.json tools/assetmgr/mkpads $< # Pads - but this is the zipped non-obj, for make test $(B_DIR)/assets/files/bgdata/bg_%_padsZ: $(A_DIR)/pads/%.json tools/assetmgr/mkpads $< # Sequences $(B_DIR)/assets/sequences.o: $(A_DIR)/sequences.json tools/assetmgr/mksequences # Textures $(B_DIR)/assets/textureslist.o: $(A_DIR)/textures.json tools/assetmgr/mktextures # Tiles $(B_DIR)/assets/files/bgdata/bg_%_tilesZ.o: $(A_DIR)/tiles/%.json tools/assetmgr/mktiles $< # Tiles - but this is the zipped non-obj, for make test $(B_DIR)/assets/files/bgdata/bg_%_tilesZ: $(A_DIR)/tiles/%.json tools/assetmgr/mktiles $< ################################################################################ # Files # Audio $(B_DIR)/assets/files/A%M: $(A_DIR)/files/audio/%.mp3 @mkdir -p $(B_DIR)/assets/files cp $< $@ # BG segs $(B_DIR)/assets/files/bgdata/bg_%.seg: $(A_DIR)/files/bgdata/bg_%.seg @mkdir -p $(B_DIR)/assets/files/bgdata cp $< $@ # Chrs $(B_DIR)/assets/files/C%Z: $(A_DIR)/files/chrs/%.bin @mkdir -p $(B_DIR)/assets/files tools/rarezip $< > $@ # Guns $(B_DIR)/assets/files/G%Z: $(A_DIR)/files/guns/%.bin @mkdir -p $(B_DIR)/assets/files tools/rarezip $< > $@ # OB seg $(B_DIR)/assets/files/ob/ob_mid.seg.o: $(B_DIR)/assets/files/ob/ob_mid.seg TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/assets/files/ob/ob_mid.seg: @mkdir -p $(B_DIR)/assets/files/ob > $@ # Props $(B_DIR)/assets/files/P%Z: $(A_DIR)/files/props/%.bin tools/rarezip $< > $@ # Stage setups # $(A_DIR)/files/setup/foo.c # -> B_DIR/assets/files/setup/foo.o (done here) # -> B_DIR/assets/files/setup/foo.elf (done here) # -> B_DIR/assets/files/setup/foo.bin (done here) # -> B_DIR/assets/files/UsetupfooZ (done here) # -> B_DIR/assets/files/UsetupfooZ.o (done elsewhere) $(B_DIR)/assets/files/setup/%.o: src/setups/%.c $(ASSETMGR_O_FILES) $(RECOMP_FILES) @mkdir -p $(dir $@) $(CC) -c $(CFLAGS) -o $@ $< $(B_DIR)/assets/files/setup/%.elf: $(B_DIR)/assets/files/setup/%.o TOOLCHAIN=$(TOOLCHAIN) tools/mksimpleelf $< $@ $(B_DIR)/files/setup/%.bin: $(B_DIR)/assets/files/setup/%.elf @mkdir -p $(dir $@) $(TOOLCHAIN)-objcopy $< $@ -O binary $(B_DIR)/assets/files/U%Z: $(B_DIR)/files/setup/%.bin tools/rarezip $< > $@ # General target to convert any finalised file into a raw object for ld $(B_DIR)/assets/files/%.o: $(B_DIR)/assets/files/% TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/assets/files/%.bin: $(B_DIR)/assets/files/%.elf $(TOOLCHAIN)-objcopy $< $@ -O binary ################################################################################ # Miscellaneous $(B_DIR)/bootloader.o: $(E_DIR)/bootloader.bin @mkdir -p $(dir $@) TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/romheader.o: src/romheader/romheader.s $(TOOLCHAIN)-as --defsym VERSION=$(VERSION) -march=vr4300 -mabi=32 -I src/include -EB -o $@ $< $(B_DIR)/assets/accessingpakZ: $(A_DIR)/accessingpak.bin tools/rarezip $< > $@ $(B_DIR)/assets/copyrightZ: $(A_DIR)/copyright.bin tools/rarezip $< > $@ $(B_DIR)/assets/accessingpakZ.o: $(B_DIR)/assets/accessingpakZ TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/assets/copyrightZ.o: $(B_DIR)/assets/copyrightZ TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ $(B_DIR)/rsp/%.text.bin $(B_DIR)/rsp/%.data.bin: src/rsp/%.s @mkdir -p $(dir $@) armips -strequ CODE_FILE $(B_DIR)/rsp/$*.text.bin -strequ DATA_FILE $(B_DIR)/rsp/$*.data.bin $< $(B_DIR)/rsp/%.o: $(B_DIR)/rsp/%.bin TOOLCHAIN=$(TOOLCHAIN) ROMID=$(ROMID) tools/mkrawobject $< $@ ifeq ($(COMPILER), ido) $(B_DIR)/lib/rng_c.o: src/lib/rng_c.c $(ASSETMGR_O_FILES) $(RECOMP_FILES) @mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(OPT_LVL) -o $@ $< tools/patchmips3 $@ || rm $@ $(B_DIR)/lib/ultra/libc/llcvt.o: src/lib/ultra/libc/llcvt.c $(ASSETMGR_O_FILES) $(RECOMP_FILES) @mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(OPT_LVL) -o $@ $< tools/patchmips3 $@ || rm $@ $(B_DIR)/lib/ultra/libc/ll.o: src/lib/ultra/libc/ll.c $(ASSETMGR_O_FILES) $(RECOMP_FILES) @mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(OPT_LVL) $< -o $@ tools/patchmips3 $@ || rm $@ endif $(B_DIR)/%.o: src/%.c $(ASSETMGR_O_FILES) $(RECOMP_FILES) @mkdir -p $(dir $@) $(CC) -c $(CFLAGS) $(OPT_LVL) -o $@ $< $(B_DIR)/%.o: src/%.s @mkdir -p $(dir $@) cpp -P -Wno-trigraphs -I include -I include/PR -I src/include $(C_DEFINES) -D_LANGUAGE_ASSEMBLY -D_MIPSEB $< | $(AS) $(ASFLAGS) -o $@ $(B_DIR)/assets/%.o: $(A_DIR)/%.c $(RECOMP_FILES) @mkdir -p $(dir $@) $(CC) -c $(CFLAGS) -o $@ $< extract: ROMID=$(ROMID) tools/extract rom: $(B_DIR)/pd.z64 clean: rm -rf build/$(ROMID) src/generated/$(ROMID) allclean: rm -rf build/* src/generated codeclean: find $(B_DIR)/game $(B_DIR)/inflate $(B_DIR)/lib -name '*.o' -delete