From 27fc1b4ac8fabd72f0778bb4a8594d7c89e557e8 Mon Sep 17 00:00:00 2001 From: Henny022p Date: Sun, 26 Feb 2023 03:41:25 +0100 Subject: [PATCH 1/6] new Makefile big commit, but should be working ok now --- GBA.mk | 163 ++++++++++++++++ Jenkinsfile | 4 +- Makefile | 303 +++--------------------------- Toolchain.mk | 32 ++++ data/animations/npc/sturgeon.s | 2 +- linker.ld | 2 +- tools/src/scaninc/asm_file.cpp | 6 +- tools/src/scaninc/c_file.cpp | 4 +- tools/src/scaninc/source_file.cpp | 4 +- 9 files changed, 229 insertions(+), 291 deletions(-) create mode 100644 GBA.mk create mode 100644 Toolchain.mk diff --git a/GBA.mk b/GBA.mk new file mode 100644 index 00000000..62221d21 --- /dev/null +++ b/GBA.mk @@ -0,0 +1,163 @@ +.PHONY: default +default: + @echo do not use this directly + +include Toolchain.mk + +GAME_VERSION ?= USA +BUILD_DIR = build/$(GAME_VERSION) + +TITLE := GBAZELDA MC +MAKER_CODE := 01 +REVISION := 0 + +ifeq ($(GAME_VERSION), EU) +GAME_CODE := BZMP +BUILD_NAME := tmc_eu +GAME_LANGUAGE := ENGLISH +TRANSLATIONS := translations/English.bin translations/French.bin translations/German.bin translations/Spanish.bin translations/Italian.bin +else ifeq ($(GAME_VERSION), JP) +GAME_CODE := BZMJ +BUILD_NAME := tmc_jp +GAME_LANGUAGE := JAPANESE +TRANSLATIONS := +else ifeq ($(GAME_VERSION), USA) +GAME_CODE := BZME +BUILD_NAME := tmc +GAME_LANGUAGE := ENGLISH +TRANSLATIONS := translations/USA.bin +else ifeq ($(GAME_VERSION), DEMO_USA) +GAME_CODE := BZHE +BUILD_NAME := tmc_demo_usa +GAME_LANGUAGE := ENGLISH +TRANSLATIONS := translations/USA.bin +else ifeq ($(GAME_VERSION), DEMO_JP) +GAME_CODE := BZMJ +BUILD_NAME := tmc_demo_jp +GAME_LANGUAGE := JAPANESE +TRANSLATIONS := +else +$(error unknown version $(GAME_VERSION)) +endif + +ROM = $(BUILD_NAME).gba +ELF = $(BUILD_NAME).elf + +# Clear the default suffixes +.SUFFIXES: +# Don't delete intermediate files +.SECONDARY: +# Delete files that weren't built properly +.DELETE_ON_ERROR: +# Secondary expansion is required for dependency variables in object rules. +.SECONDEXPANSION: + +# ================== +# entrypoint targets +# ================== +CUSTOM ?= +COMPARE ?= $(if $(CUSTOM),0,1) + +.PHONY: build extract_assets build_assets +build: $(if $(CUSTOM), build_assets, $(BUILD_DIR)/extracted_assets_$(GAME_VERSION)) + @$(MAKE) -f GBA.mk $(ROM) +ifeq ($(COMPARE), 1) + @$(SHA1) $(BUILD_NAME).sha1 +endif +extract_assets: $(BUILD_DIR)/converted_assets_$(GAME_VERSION) +# TODO this is slow, especially on builds with minor/no changes +build_assets: $(BUILD_DIR)/converted_assets_$(GAME_VERSION) + $(ASSET_PROCESSOR) build $(GAME_VERSION) $(BUILD_DIR)/assets + +.PHONY: clean +clean: + rm -rf build + rm -f t*.gba + rm -f t*.elf + +# =============== +# build ASM files +# =============== + +ASINCLUDE := -I $(BUILD_DIR)/assets -I $(BUILD_DIR)/enum_include +ASFLAGS := -mcpu=arm7tdmi --defsym $(GAME_VERSION)=1 --defsym REVISION=$(REVISION) --defsym $(GAME_LANGUAGE)=1 $(ASINCLUDE) + +# TODO try solve this without the glob +ENUM_ASM_SRCS := $(wildcard include/*.h) +ENUM_ASM_HEADERS := $(patsubst include/%.h,$(BUILD_DIR)/enum_include/%.inc,$(ENUM_ASM_SRCS)) + +# if this is too broad dependency scanning will clash with C file +$(BUILD_DIR)/asm/%.o: deps = $(shell $(SCANINC) -I . $(ASINCLUDE) $*.s) +$(BUILD_DIR)/data/%.o: deps = $(shell $(SCANINC) -I . $(ASINCLUDE) $*.s) +$(BUILD_DIR)/%.o: %.s $$(deps) $(ENUM_ASM_HEADERS) + @mkdir -p $(dir $@) + $(PREPROC) $(BUILD_NAME) $< -- $(ASINCLUDE) | $(AS) $(ASFLAGS) -o $@ + +$(BUILD_DIR)/enum_include/%.inc: include/%.h + @mkdir -p $(dir $@) + $(ENUM_PROCESSOR) $< $(CC) "-D__attribute__(x)=" "-D$(GAME_VERSION)" "-E" "-nostdinc" "-Itools/agbcc" "-Itools/agbcc/include" "-iquote include" > $@ + +# ============= +# build C files +# ============= + +# agbcc includes are separate because we don't want dependency scanning on them +CINCLUDE := -I include -I $(BUILD_DIR) +CPPFLAGS := -I tools/agbcc -I tools/agbcc/include $(CINCLUDE) -nostdinc -undef -D$(GAME_VERSION) -DREVISION=$(REVISION) -D$(GAME_LANGUAGE) +CFLAGS := -O2 -Wimplicit -Wparentheses -Werror -Wno-multichar -g3 + +interwork := $(BUILD_DIR)/src/interrupts.o \ +$(BUILD_DIR)/src/collision.o \ +$(BUILD_DIR)/src/playerItem.o \ +$(BUILD_DIR)/src/object.o \ +$(BUILD_DIR)/src/manager.o \ +$(BUILD_DIR)/src/npc.o \ +$(BUILD_DIR)/src/gba/m4a.o + +$(interwork): CFLAGS += -mthumb-interwork +$(BUILD_DIR)/src/eeprom.o: CFLAGS += -O1 -mthumb-interwork + +# if this is too broad dependency scanning will clash with ASM file +$(BUILD_DIR)/src/%.o: deps = $(shell $(SCANINC) $(CINCLUDE) $*.c) +$(BUILD_DIR)/%.o : %.c $$(deps) + @mkdir -p $(dir $@) + $(CPP) $(CPPFLAGS) $< -o $(BUILD_DIR)/$*.i + $(CC1) $(CFLAGS) -o $(BUILD_DIR)/$*.s $(BUILD_DIR)/$*.i + @echo "\t.text\n\t.align\t2, 0 @ Don't pad with nop\n" >> $(BUILD_DIR)/$*.s + $(AS) $(ASFLAGS) -o $@ $(BUILD_DIR)/$*.s + +# ============== +# build binaries +# ============== + +LDFLAGS = -Map ../../$(BUILD_DIR)/$(BUILD_NAME).map +LIB := -L ../../tools/agbcc/lib -lc + +$(ROM): $(ELF) + $(OBJCOPY) -O binary --gap-fill 0xFF --pad-to 0x9000000 $< $@ + +$(ELF): objs = $(shell grep -o -E "(\w|/)+\.o" linker.ld) +$(ELF): $(BUILD_DIR)/linker.ld $$(addprefix $(BUILD_DIR)/, $$(objs)) + cd $(BUILD_DIR) && $(LD) $(LDFLAGS) -n -T linker.ld -o ../../$@ $(LIB) + $(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent + +$(BUILD_DIR)/linker.ld: linker.ld + @mkdir -p $(BUILD_DIR) + $(CPP) $(CPPFLAGS) -x c linker.ld | grep -v '^#' >$(BUILD_DIR)/linker.ld + +# ====== +# assets +# ====== + +$(BUILD_DIR)/extracted_assets_%: assets/assets.json assets/gfx.json assets/map.json assets/samples.json assets/sounds.json $(TRANSLATIONS) + @mkdir -p $(dir $@) + $(ASSET_PROCESSOR) extract $(GAME_VERSION) $(BUILD_DIR)/assets + touch $@ + +$(BUILD_DIR)/converted_assets_%: $(BUILD_DIR)/extracted_assets_% + @mkdir -p $(dir $@) + $(ASSET_PROCESSOR) convert $(GAME_VERSION) $(BUILD_DIR)/assets + touch $@ + +translations/%.bin: translations/%.json + tools/bin/tmc_strings -p --source $< --dest $@ diff --git a/Jenkinsfile b/Jenkinsfile index 603ff83a..e54bf2fb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,12 +12,12 @@ pipeline { sh 'cp /usr/local/etc/roms/tmc.demo.jp.gba baserom_demo_jp.gba' sh 'cp /usr/local/etc/roms/tmc.jp.gba baserom_jp.gba' sh 'cp /usr/local/etc/roms/tmc.eu.gba baserom_eu.gba' - sh 'make -j setup' + sh 'make setup' } } stage('Build') { steps { - sh 'make usa demo_usa jp demo_jp eu -j' + sh 'make all -j' } } stage('Report Progress') { diff --git a/Makefile b/Makefile index cdf51352..afa20588 100644 --- a/Makefile +++ b/Makefile @@ -1,294 +1,37 @@ -include $(DEVKITARM)/base_tools - -COMPARE ?= 0 - -CPP := $(CC) -E -LD := $(DEVKITARM)/bin/arm-none-eabi-ld - -GAME_VERSION ?= USA -REVISION := 0 -GAME_LANGUAGE := ENGLISH - -TITLE := GBAZELDA MC -MAKER_CODE := 01 - -ifeq ($(GAME_VERSION), USA) -GAME_CODE := BZME -BUILD_NAME := tmc -else -ifeq ($(GAME_VERSION), DEMO_USA) -GAME_CODE := BZHE -BUILD_NAME := tmc_demo_usa -else -ifeq ($(GAME_VERSION), JP) -GAME_CODE := BZMJ -BUILD_NAME := tmc_jp -GAME_LANGUAGE := JAPANESE -else -ifeq ($(GAME_VERSION), DEMO_JP) -GAME_CODE := BZMJ -BUILD_NAME := tmc_demo_jp -GAME_LANGUAGE := JAPANESE -else -ifeq ($(GAME_VERSION), EU) -GAME_CODE := BZMP -BUILD_NAME := tmc_eu -else -$(error unknown version $(GAME_VERSION)) -endif -endif -endif -endif -endif - -SHELL := /bin/bash -o pipefail - - -ROM := $(BUILD_NAME).gba -OBJ_DIR := build/$(BUILD_NAME) - -ELF = $(ROM:.gba=.elf) -MAP = $(ROM:.gba=.map) - -C_SUBDIR = src -DATA_C_SUBDIR = src/data -ASM_SUBDIR = asm -DATA_ASM_SUBDIR = data -SONG_SUBDIR = sound/songs -MID_SUBDIR = sound/songs/midi -ASSET_SUBDIR = assets -ENUM_INCLUDE_SUBDIR = enum_include - -C_BUILDDIR = $(OBJ_DIR)/$(C_SUBDIR) -ASM_BUILDDIR = $(OBJ_DIR)/$(ASM_SUBDIR) -ASM_ENUM_INCLUDE_DIR = $(ASM_BUILDDIR)/$(ENUM_INCLUDE_SUBDIR) -DATA_ASM_BUILDDIR = $(OBJ_DIR)/$(DATA_ASM_SUBDIR) -SONG_BUILDDIR = $(OBJ_DIR)/$(SONG_SUBDIR) -MID_BUILDDIR = $(OBJ_DIR)/$(MID_SUBDIR) -ASSET_BUILDDIR = $(OBJ_DIR)/$(ASSET_SUBDIR) -PREPROC_INC_PATHS = $(ASSET_BUILDDIR) $(ASM_ENUM_INCLUDE_DIR) - -ASFLAGS := -mcpu=arm7tdmi --defsym $(GAME_VERSION)=1 --defsym REVISION=$(REVISION) --defsym $(GAME_LANGUAGE)=1 -I $(ASSET_SUBDIR) -I $(ASSET_BUILDDIR) -I $(ASM_ENUM_INCLUDE_DIR) - -CC1 := tools/agbcc/bin/agbcc -override CFLAGS += -O2 -Wimplicit -Wparentheses -Werror -Wno-multichar -g3 -# -fhex-asm - -# ifeq ($(DINFO),1) -# override CFLAGS += -g -# endif - -CPPFLAGS := -I tools/agbcc -I tools/agbcc/include -iquote include -nostdinc -undef -D$(GAME_VERSION) -DREVISION=$(REVISION) -D$(GAME_LANGUAGE) -I $(OBJ_DIR) - -LDFLAGS = -Map ../../$(MAP) - -LIB := -L ../../tools/agbcc/lib -lc - -SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c -GFX := tools/bin/gbagfx -AIF := tools/bin/aif2pcm -MID := tools/bin/mid2agb -SCANINC := tools/bin/scaninc -# TODO: use charmap? -PREPROC := tools/bin/preproc -FIX := tools/bin/gbafix -ASSET_PROCESSOR := tools/bin/asset_processor -ENUM_PROCESSOR := tools/extract_include_enum.py - -ASSET_CONFIGS = assets/assets.json assets/gfx.json assets/map.json assets/samples.json assets/sounds.json -TRANSLATIONS = translations/USA.bin translations/English.bin translations/French.bin translations/German.bin translations/Spanish.bin translations/Italian.bin - -# Clear the default suffixes -.SUFFIXES: -# Don't delete intermediate files -.SECONDARY: -# Delete files that weren't built properly -.DELETE_ON_ERROR: -# Secondary expansion is required for dependency variables in object rules. -.SECONDEXPANSION: - - -$(shell mkdir -p $(C_BUILDDIR) $(ASM_BUILDDIR) $(DATA_ASM_BUILDDIR) $(SONG_BUILDDIR) $(MID_BUILDDIR)) - -infoshell = $(foreach line, $(shell $1 | sed "s/ /__SPACE__/g"), $(info $(subst __SPACE__, ,$(line)))) - -# Build tools when building the rom -# Disable dependency scanning for clean/tidy/tools -ifeq (,$(filter-out all compare target,$(MAKECMDGOALS))) -$(call infoshell, $(MAKE) tools) -else -NODEP := 1 -endif - -interwork := $(C_BUILDDIR)/interrupts.o \ -$(C_BUILDDIR)/collision.o \ -$(C_BUILDDIR)/playerItem.o \ -$(C_BUILDDIR)/object.o \ -$(C_BUILDDIR)/manager.o \ -$(C_BUILDDIR)/npc.o - -$(interwork): CFLAGS += -mthumb-interwork -$(C_BUILDDIR)/gba/m4a.o: CFLAGS = -O2 -mthumb-interwork -Wimplicit -Wparentheses -Werror -Wno-multichar -$(C_BUILDDIR)/eeprom.o: CFLAGS = -O1 -mthumb-interwork -Wimplicit -Wparentheses -Werror -Wno-multichar - -C_SRCS := $(wildcard $(C_SUBDIR)/*.c $(C_SUBDIR)/*/*.c) -C_OBJS := $(patsubst $(C_SUBDIR)/%.c,$(C_BUILDDIR)/%.o,$(C_SRCS)) - -ASM_SRCS := $(wildcard $(ASM_SUBDIR)/*.s $(ASM_SUBDIR)/*/*.s) -ASM_OBJS := $(patsubst $(ASM_SUBDIR)/%.s,$(ASM_BUILDDIR)/%.o,$(ASM_SRCS)) $(patsubst $(ASM_SUBDIR)/*/%.s,$(ASM_BUILDDIR)/**/%.o,$(ASM_SRCS)) - -DATA_ASM_SRCS := $(wildcard $(DATA_ASM_SUBDIR)/*.s $(DATA_ASM_SUBDIR)/**/*.s $(DATA_ASM_SUBDIR)/**/**/*.s) -DATA_ASM_OBJS := $(patsubst $(DATA_ASM_SUBDIR)/%.s,$(DATA_ASM_BUILDDIR)/%.o,$(DATA_ASM_SRCS)) - -SONG_SRCS := $(wildcard $(SONG_SUBDIR)/*.s) -SONG_OBJS := $(patsubst $(SONG_SUBDIR)/%.s,$(SONG_BUILDDIR)/%.o,$(SONG_SRCS)) - -MID_SRCS := $(wildcard $(MID_SUBDIR)/*.mid) -MID_OBJS := $(patsubst $(MID_SUBDIR)/%.mid,$(MID_BUILDDIR)/%.o,$(MID_SRCS)) - -ENUM_ASM_SRCS := $(wildcard include/*.h) -ENUM_ASM_HEADERS := $(patsubst include/%.h,$(ASM_ENUM_INCLUDE_DIR)/%.inc,$(ENUM_ASM_SRCS)) - -OBJS := $(C_OBJS) $(ASM_OBJS) $(DATA_ASM_OBJS) $(SONG_OBJS) $(MID_OBJS) -OBJS_REL := $(patsubst $(OBJ_DIR)/%,%,$(OBJS)) - -SUBDIRS := $(sort $(dir $(OBJS) $(ENUM_ASM_HEADERS))) - -$(shell mkdir -p $(SUBDIRS)) - -.PHONY: all setup clean-tools mostlyclean clean tidy tools extractassets buildassets custom +.PHONY: default all +default: build +all: eu jp usa demo_jp demo_usa MAKEFLAGS += --no-print-directory -AUTO_GEN_TARGETS := +.PHONY: build eu jp usa demo_jp demo_usa custom +build: GAME_VERSION ?=USA +build: tools + @$(MAKE) -f GBA.mk build GAME_VERSION=$(GAME_VERSION) -# TODO do we really need this extra step just so that the assets are always extracted at first? -all: build/extracted_assets_$(GAME_VERSION) - @$(MAKE) target GAME_VERSION=$(GAME_VERSION) +eu: GAME_VERSION=EU +jp: GAME_VERSION=JP +usa: GAME_VERSION=USA +demo_jp: GAME_VERSION=DEMO_JP +demo_usa: GAME_VERSION=DEMO_USA +eu jp usa demo_jp demo_usa: + @$(MAKE) GAME_VERSION=$(GAME_VERSION) -target: $(ROM) - @$(SHA1) $(BUILD_NAME).sha1 +custom: tools + @$(MAKE) GAME_VERSION=USA CUSTOM=1 -custom: buildassets - @$(MAKE) target GAME_VERSION=$(GAME_VERSION) +.PHONY: tools +tools: tools/bin -# kept for backwards compat -compare: $(ROM) - @$(SHA1) $(BUILD_NAME).sha1 - -setup: tools - -# all tools are build at once -# FIXME figure out why make builds multiple times when specifying all tools here -tools: $(GFX) - -$(GFX) $(AIF) $(MID) $(SCANINC) $(PREPROC) $(FIX) $(ASSET_PROCESSOR) tools/bin/agb2mid tools/bin/tmc_strings tools/bin/bin2c &: +tools/bin: mkdir -p tools/cmake-build - unset CC CXX AS LD LDFLAGS && cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=tools -S tools -B tools/cmake-build + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=tools -S tools -B tools/cmake-build cmake --build tools/cmake-build -j --target install -# Automatically extract binary data -build/extracted_assets_%: $(ASSET_CONFIGS) $(TRANSLATIONS) - $(ASSET_PROCESSOR) extract $(GAME_VERSION) $(ASSET_BUILDDIR) - touch $@ - -# Extract assets to human readable form -extractassets: - $(ASSET_PROCESSOR) convert $(GAME_VERSION) $(ASSET_BUILDDIR) - -# Build the assets from the human readable form -buildassets: - $(ASSET_PROCESSOR) build $(GAME_VERSION) $(ASSET_BUILDDIR) - -mostlyclean: tidy - rm -f sound/direct_sound_samples/*.bin - rm -f $(SONG_OBJS) $(MID_SUBDIR)/*.s - find . \( -iname '*.1bpp' -o -iname '*.4bpp' -o -iname '*.8bpp' -o -iname '*.gbapal' -o -iname '*.lz' -o -iname '*.latfont' -o -iname '*.hwjpnfont' -o -iname '*.fwjpnfont' \) -exec rm {} + - rm -f $(AUTO_GEN_TARGETS) +.PHONY: clean clean-tools +clean: + @$(MAKE) -f GBA.mk clean clean-tools: rm -rf tools/bin rm -rf tools/cmake-build - -clean: mostlyclean clean-tools - -tidy: - rm -f tmc.gba tmc.elf tmc.map - rm -f tmc_demo_usa.gba tmc_demo_usa.elf tmc_demo_usa.map - rm -f tmc_jp.gba tmc_jp.elf tmc_jp.map - rm -f tmc_demo_jp.gba tmc_demo_jp.elf tmc_demo_jp.map - rm -f tmc_eu.gba tmc_eu.elf tmc_eu.map - rm -r build/* - - -%.s: ; -%.png: ; -%.pal: ; -%.aif: ; - -%.1bpp: %.png ; $(GFX) $< $@ -%.4bpp: %.png ; $(GFX) $< $@ -%.8bpp: %.png ; $(GFX) $< $@ -%.gbapal: %.pal ; $(GFX) $< $@ -%.gbapal: %.png ; $(GFX) $< $@ -%.lz: % ; $(GFX) $< $@ -%.rl: % ; $(GFX) $< $@ - cd $(@D) && ../../$(MID) $(> $(C_BUILDDIR)/$*.s - $(AS) $(ASFLAGS) -o $@ $(C_BUILDDIR)/$*.s - -ifeq ($(NODEP),1) -$(ASM_BUILDDIR)/%.o: asm_dep := -else -$(ASM_BUILDDIR)/%.o: asm_dep = $(shell $(SCANINC) -I . $(ASM_SUBDIR)/$*.s) -endif - -$(ASM_BUILDDIR)/%.o: $(ASM_SUBDIR)/%.s $$(asm_dep) - $(PREPROC) $(BUILD_NAME) $< -- $(PREPROC_INC_PATHS) | $(AS) $(ASFLAGS) -o $@ - -$(ASM_ENUM_INCLUDE_DIR)/%.inc: include/%.h - $(ENUM_PROCESSOR) $< $(CC) "-D__attribute__(x)=" "-D$(GAME_VERSION)" "-E" "-nostdinc" "-Itools/agbcc" "-Itools/agbcc/include" "-iquote include" > $@ - -ifeq ($(NODEP),1) -$(DATA_ASM_BUILDDIR)/%.o: data_dep := -else -$(DATA_ASM_BUILDDIR)/%.o: data_dep = $(shell $(SCANINC) -I . -I $(ASSET_SUBDIR) -I $(ASSET_BUILDDIR) -I $(ASM_ENUM_INCLUDE_DIR) $(DATA_ASM_SUBDIR)/$*.s) -endif - -$(DATA_ASM_BUILDDIR)/%.o: $(DATA_ASM_SUBDIR)/%.s $$(data_dep) $(ENUM_ASM_HEADERS) - $(PREPROC) $(BUILD_NAME) $< charmap.txt -- $(PREPROC_INC_PATHS) | $(CPP) -I include -nostdinc -undef -Wno-unicode - | $(AS) $(ASFLAGS) -o $@ - -$(SONG_BUILDDIR)/%.o: $(SONG_SUBDIR)/%.s - $(AS) $(ASFLAGS) -I sound -o $@ $< - -$(OBJ_DIR)/linker.ld: linker.ld - $(CPP) $(CPPFLAGS) -x c linker.ld | grep -v '^#' >$(OBJ_DIR)/linker.ld - -$(ELF): $(OBJS) $(OBJ_DIR)/linker.ld - cd $(OBJ_DIR) && $(LD) $(LDFLAGS) -n -T linker.ld -o ../../$@ $(LIB) - $(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent - -$(ROM): $(ELF) - $(OBJCOPY) -O binary --gap-fill 0xFF --pad-to 0x9000000 $< $@ - -usa: ; @$(MAKE) GAME_VERSION=USA -demo_usa: ; @$(MAKE) GAME_VERSION=DEMO_USA -jp: ; @$(MAKE) GAME_VERSION=JP -demo_jp: ; @$(MAKE) GAME_VERSION=DEMO_JP -eu: ; @$(MAKE) GAME_VERSION=EU diff --git a/Toolchain.mk b/Toolchain.mk new file mode 100644 index 00000000..4adb9f3e --- /dev/null +++ b/Toolchain.mk @@ -0,0 +1,32 @@ +# ======== +# compiler +# ======== + +ifneq (,$(shell which arm-none-eabi-gcc)) +PREFIX := +else ifdef DEVKITARM +PREFIX := $(DEVKITARM)/bin/ +else +$(error arm-none-eabi-gcc not found, please install (devkitPro supported)) +endif + + +CC := $(PREFIX)arm-none-eabi-gcc +CPP := $(CC) -E +CXX := $(PREFIX)arm-none-eabi-g++ +AS := $(PREFIX)arm-none-eabi-as +LD := $(PREFIX)arm-none-eabi-ld +OBJCOPY := $(PREFIX)arm-none-eabi-objcopy + +# ============ +# custom tools +# ============ + +CC1 := tools/agbcc/bin/agbcc +SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c + +SCANINC := tools/bin/scaninc +PREPROC := tools/bin/preproc +ASSET_PROCESSOR := tools/bin/asset_processor +ENUM_PROCESSOR := tools/extract_include_enum.py +FIX := tools/bin/gbafix diff --git a/data/animations/npc/sturgeon.s b/data/animations/npc/sturgeon.s index a4fa9b14..dc4be7fd 100644 --- a/data/animations/npc/sturgeon.s +++ b/data/animations/npc/sturgeon.s @@ -45,4 +45,4 @@ gSpriteAnimations_Sturgeon:: @ 0810FBD0 .4byte gSpriteAnimations_Sturgeon_7 .4byte gSpriteAnimations_Sturgeon_8 .4byte gSpriteAnimations_Sturgeon_9 - .4byte 00000000 \ No newline at end of file + .4byte 00000000 diff --git a/linker.ld b/linker.ld index 50a77389..ab7e510a 100644 --- a/linker.ld +++ b/linker.ld @@ -880,7 +880,7 @@ SECTIONS { src/gba/m4a.o(.text); asm/lib/libagbsyscall.o(.text); src/eeprom.o(.text); - *libc.a:memcpy.o(.text); + libc.a(.text); /* handwritten assembly in arm mode */ asm/src/intr.o(.text); diff --git a/tools/src/scaninc/asm_file.cpp b/tools/src/scaninc/asm_file.cpp index f53777bc..18b1e956 100644 --- a/tools/src/scaninc/asm_file.cpp +++ b/tools/src/scaninc/asm_file.cpp @@ -29,7 +29,7 @@ AsmFile::AsmFile(std::string path) { FILE* fp = std::fopen(path.c_str(), "rb"); if (fp == NULL) - fatal_error("Failed to open \"%s\" for reading.\n", path.c_str()); + fatal_error("Failed to open \"{}\" for reading.\n", path.c_str()); std::fseek(fp, 0, SEEK_END); @@ -40,7 +40,7 @@ AsmFile::AsmFile(std::string path) { std::rewind(fp); if (std::fread(m_buffer, m_size, 1, fp) != 1) - fatal_error("Failed to read \"%s\".\n", path.c_str()); + fatal_error("Failed to read \"{}\".\n", path.c_str()); std::fclose(fp); @@ -159,7 +159,7 @@ void AsmFile::SkipString() { fatal_error(INPUT_ERROR_MESSAGE("unexpected EOF in string\n")); if (c == '\\') { - c = GetChar(); + c = GetChar(); } } } diff --git a/tools/src/scaninc/c_file.cpp b/tools/src/scaninc/c_file.cpp index a8ff921f..fc5ed555 100644 --- a/tools/src/scaninc/c_file.cpp +++ b/tools/src/scaninc/c_file.cpp @@ -26,7 +26,7 @@ CFile::CFile(std::string path) { FILE* fp = std::fopen(path.c_str(), "rb"); if (fp == NULL) - fatal_error("Failed to open \"%s\" for reading.\n", path.c_str()); + fatal_error("Failed to open \"{}\" for reading.\n", path.c_str()); std::fseek(fp, 0, SEEK_END); @@ -38,7 +38,7 @@ CFile::CFile(std::string path) { std::rewind(fp); if (std::fread(m_buffer, m_size, 1, fp) != 1) - fatal_error("Failed to read \"%s\".\n", path.c_str()); + fatal_error("Failed to read \"{}\".\n", path.c_str()); std::fclose(fp); diff --git a/tools/src/scaninc/source_file.cpp b/tools/src/scaninc/source_file.cpp index 0cefc9f1..107396b0 100644 --- a/tools/src/scaninc/source_file.cpp +++ b/tools/src/scaninc/source_file.cpp @@ -25,7 +25,7 @@ SourceFileType GetFileType(std::string& path) { std::size_t pos = path.find_last_of('.'); if (pos == std::string::npos) - fatal_error("no file extension in path \"%s\"\n", path.c_str()); + fatal_error("no file extension in path \"{}\"\n", path.c_str()); std::string extension = path.substr(pos + 1); @@ -38,7 +38,7 @@ SourceFileType GetFileType(std::string& path) { else if (extension == "inc") return SourceFileType::Inc; else - fatal_error("Unrecognized extension \"%s\"\n", extension.c_str()); + fatal_error("Unrecognized extension \"{}\"\n", extension.c_str()); // Unreachable return SourceFileType::Cpp; From 716098ec4eb7bee0d398ccec5226a1b1d5192db2 Mon Sep 17 00:00:00 2001 From: Henny022p Date: Sun, 26 Feb 2023 03:56:51 +0100 Subject: [PATCH 2/6] fix Jenkinsfile --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index e54bf2fb..e4aba2b1 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,7 +12,7 @@ pipeline { sh 'cp /usr/local/etc/roms/tmc.demo.jp.gba baserom_demo_jp.gba' sh 'cp /usr/local/etc/roms/tmc.jp.gba baserom_jp.gba' sh 'cp /usr/local/etc/roms/tmc.eu.gba baserom_eu.gba' - sh 'make setup' + sh 'make tools' } } stage('Build') { From 9924c4086ab68988afcb808218ddfb7ccab0ae3f Mon Sep 17 00:00:00 2001 From: Henny022p Date: Sun, 26 Feb 2023 04:02:51 +0100 Subject: [PATCH 3/6] expose extract_assets target in top level Makefile --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index afa20588..e79a3d26 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,10 @@ eu jp usa demo_jp demo_usa: custom: tools @$(MAKE) GAME_VERSION=USA CUSTOM=1 +.PHONY: extract_assets +extract_assets: + @$(MAKE) -f GBA.mk extract_assets + .PHONY: tools tools: tools/bin From 54fc93770ccb9dec9483308a4405155605d8b851 Mon Sep 17 00:00:00 2001 From: Henny022p Date: Sun, 26 Feb 2023 14:20:26 +0100 Subject: [PATCH 4/6] make TOOLCHAIN_PATH configurable --- Toolchain.mk | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Toolchain.mk b/Toolchain.mk index 4adb9f3e..76e2a871 100644 --- a/Toolchain.mk +++ b/Toolchain.mk @@ -2,21 +2,27 @@ # compiler # ======== +ifndef TOOLCHAIN_PATH ifneq (,$(shell which arm-none-eabi-gcc)) -PREFIX := +TOOLCHAIN_PATH := else ifdef DEVKITARM -PREFIX := $(DEVKITARM)/bin/ +TOOLCHAIN_PATH := $(DEVKITARM)/bin/ else $(error arm-none-eabi-gcc not found, please install (devkitPro supported)) endif +endif +# ensure trailing slash +ifneq ($(TOOLCHAIN_PATH),) +override TOOLCHAIN_PATH:=$(TOOLCHAIN_PATH)/ +endif -CC := $(PREFIX)arm-none-eabi-gcc +CC := $(TOOLCHAIN_PATH)arm-none-eabi-gcc CPP := $(CC) -E -CXX := $(PREFIX)arm-none-eabi-g++ -AS := $(PREFIX)arm-none-eabi-as -LD := $(PREFIX)arm-none-eabi-ld -OBJCOPY := $(PREFIX)arm-none-eabi-objcopy +CXX := $(TOOLCHAIN_PATH)arm-none-eabi-g++ +AS := $(TOOLCHAIN_PATH)arm-none-eabi-as +LD := $(TOOLCHAIN_PATH)arm-none-eabi-ld +OBJCOPY := $(TOOLCHAIN_PATH)arm-none-eabi-objcopy # ============ # custom tools From f9fcc589d0cc96a9ac6016a706154d7ad9eb87b5 Mon Sep 17 00:00:00 2001 From: Henny022p Date: Sun, 26 Feb 2023 14:21:17 +0100 Subject: [PATCH 5/6] update information in INSTALL --- INSTALL.md | 86 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index a9cedf71..398d07f0 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,14 +1,22 @@ # Install -First, you must put a The Legend of Zelda: The Minish Cap (U) ROM (with SHA1: `b4bd50e4131b027c334547b4524e2dbbd4227130`) in the root directory of the repository and name it `baserom.gba`. +This repository does not include any of the games assets. +To build the game using the decomp you need an original baserom for each version you want to build. +Put them with the appropriate filename into the repository root directory. +The supported versions are: -## Building other variants -To build other variants, you need to place the corresponding baserom before building, e.g. `baserom_jp.gba` for JP. +| Version | Filename | SHA1 | +|-----------------------|------------------------|--------------------------------------------| +| USA (project default) | `baserom.gba` | `b4bd50e4131b027c334547b4524e2dbbd4227130` | +| EU | `baserom_eu.gba` | `cff199b36ff173fb6faf152653d1bccf87c26fb7` | +| JP | `baserom_jp.gba` | `6c5404a1effb17f481f352181d0f1c61a2765c5d` | +| USA (Demo) | `baserom_demo_usa.gba` | `63fcad218f9047b6a9edbb68c98bd0dec322d7a1` | +| JP (Demo) | `baserom_demo_jp.gba` | `9cdb56fa79bba13158b81925c1f3641251326412` | ## Prerequisites -| Linux | macOS | Windows 10 (build 18917+) | Windows 10 (1709+) | Windows 8, 8.1, and 10 (1507, 1511, 1607, 1703) -| ----- | ----- | ------------------------- | ------------------ | --------------------------------------------------------- -| none | [Xcode Command Line Tools package][xcode] | [Windows Subsystem for Linux 2][wsl2] | [Windows Subsystem for Linux][wsl] | [Cygwin][cygwin] +| Linux | macOS | Windows 10 (build 18917+) | Windows 10 (1709+) | Windows 8, 8.1, and 10 (1507, 1511, 1607, 1703) | +|-------|-------------------------------------------|---------------------------------------|------------------------------------|-------------------------------------------------| +| none | [Xcode Command Line Tools package][xcode] | [Windows Subsystem for Linux 2][wsl2] | [Windows Subsystem for Linux][wsl] | [Cygwin][cygwin] | [xcode]: https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-DOWNLOADING_COMMAND_LINE_TOOLS_IS_NOT_AVAILABLE_IN_XCODE_FOR_MACOS_10_9__HOW_CAN_I_INSTALL_THEM_ON_MY_MACHINE_ [wsl2]: https://docs.microsoft.com/windows/wsl/wsl2-install @@ -17,53 +25,59 @@ To build other variants, you need to place the corresponding baserom before buil The [prerelease version of the Linux subsystem](https://docs.microsoft.com/windows/wsl/install-legacy) available in the 1607 and 1703 releases of Windows 10 is obsolete so consider uninstalling it. -Make sure that the `build-essential`, `git`, `python3`, `python3-pip`, `cmake` and `libpng-dev` packages are installed. The `build-essential` package includes the `make`, `gcc-core`, and `g++` packages so they do not have to be obtained separately. +Make sure that the `build-essential`, `git`, `python3`, `python3-pip`, `cmake` and `libpng-dev` packages are installed. The `build-essential` package includes the `make`, `gcc-core`, and `g++` packages, so they do not have to be obtained separately. In the case of Cygwin, [include](https://cygwin.com/cygwin-ug-net/setup-net.html#setup-packages) the `make`, `git`, `gcc-core`, `gcc-g++`, and `libpng-devel` packages. -Install the **devkitARM** toolchain of [devkitPro](https://devkitpro.org/wiki/Getting_Started) and add its environment variables. For Windows versions without the Linux subsystem, the devkitPro [graphical installer](https://github.com/devkitPro/installer/releases) includes a preconfigured MSYS2 environment, thus the steps below are not required. +To build the games code, the `arm-none-eabi-gcc` compiler is required. +Both a standalone installation and [devkitPro](https://devkitpro.org/wiki/Getting_Started) are supported. +For devkitPro, install the `gba-dev` package. - sudo (dkp-)pacman -S gba-dev - export DEVKITPRO=/opt/devkitpro - echo "export DEVKITPRO=$DEVKITPRO" >> ~/.bashrc - export DEVKITARM=$DEVKITPRO/devkitARM - echo "export DEVKITARM=$DEVKITARM" >> ~/.bashrc +If `arm-none-eabi-gcc` is not available through `PATH` use `TOOLCHAIN_PATH=` to indicate its location. +This is not required for devkitPro, the `DEVKITARM` environment variable is used for auto-detection. -Install the pycparser python package: - pip3 install pycparser +Install `python3` and the `pycparser` python package: +`pip3 install pycparser` ## Installation To set up the repository: +```shell +git clone https://github.com/zeldaret/tmc +git clone https://github.com/pret/agbcc - git clone https://github.com/zeldaret/tmc - git clone https://github.com/pret/agbcc +cd ./agbcc +sh build.sh +sh install.sh ../tmc - cd ./agbcc - sh build.sh - sh install.sh ../tmc +cd ../tmc +make tools +``` +To build `tmc.gba`: +```shell +make -j$(nproc) +``` +>**Note:** If the build command is not recognized on Linux, including the Linux environment used within Windows, run `nproc` and replace `$(nproc)` with the returned value (e.g.: `make -j4`). Because `nproc` is not available on macOS, the alternative is `sysctl -n hw.ncpu`. - cd ../tmc - make setup +You can configure the game version built by using the `GAME_VERSION` variable (ie. `make GAME_VERSION=EU`). +Convenience targets for all 5 versions exist (`make usa eu jp demo_usa demo_jp`). +`make all` builds all 5 versions. -To build **tmc.gba**: +If you modify the game you need to do a custom build. +Use `CUSTOM=1` for that (any nonempty value will enable it, so `CUSTOM=0` will NOT disable it). +There is a convenience target `make custom` that does a custom USA build. - make -j$(nproc) - -If only `.c` or `.s` files were changed, turn off the dependency scanning temporarily. Changes to any other files will be ignored and the build will either fail or not reflect those changes. - - make -j$(nproc) NODEP=1 - -**Note:** If the build command is not recognized on Linux, including the Linux environment used within Windows, run `nproc` and replace `$(nproc)` with the returned value (e.g.: `make -j4`). Because `nproc` is not available on macOS, the alternative is `sysctl -n hw.ncpu`. +The `COMPARE` variable controls the SHA1 verification check. +It is enabled (`1`) for normal builds and disabled (`0`) for custom builds by default. ### Note for Mac users The BSD make that comes with Mac XCode can be buggy, so obtain GNU make and sed using [Homebrew](https://brew.sh): - - brew install make gnu-sed - +```shell +brew install make gnu-sed +``` When compiling agbcc, substitute the `build.sh` line for - - gsed 's/^make/gmake/g' build.sh | sh - +```shell +gsed 's/^make/gmake/g' build.sh | sh +``` Finally, use `gmake` instead of `make` to compile the ROM(s). From 65d861a5c2fb1bc93f5bf84a991bdd21f23be3dd Mon Sep 17 00:00:00 2001 From: Henny022p Date: Wed, 1 Mar 2023 19:34:10 +0100 Subject: [PATCH 6/6] add dependency to tools to more helper targets fixes asset extraction and parallel multi version builds without manually building tools first --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e79a3d26..394eacea 100644 --- a/Makefile +++ b/Makefile @@ -14,14 +14,14 @@ jp: GAME_VERSION=JP usa: GAME_VERSION=USA demo_jp: GAME_VERSION=DEMO_JP demo_usa: GAME_VERSION=DEMO_USA -eu jp usa demo_jp demo_usa: +eu jp usa demo_jp demo_usa: tools @$(MAKE) GAME_VERSION=$(GAME_VERSION) custom: tools @$(MAKE) GAME_VERSION=USA CUSTOM=1 .PHONY: extract_assets -extract_assets: +extract_assets: tools @$(MAKE) -f GBA.mk extract_assets .PHONY: tools