diff --git a/.gitignore b/.gitignore index 0dc34e7..ed9bbac 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ text_errors.txt terminal_output.txt tools/payload-generator/payload-generator tools/make-file-container/make-file-container +options.json \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9774293..b4990fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ -FROM devkitpro/devkitarm:20251117 +FROM devkitpro/devkitarm:20260610 -LABEL author="Poke Transporter GB" +LABEL author="Striaton Lab Team" +LABEL name="Poke Transporter GB" USER root @@ -8,7 +9,10 @@ ARG USER_ID ARG GROUP_ID ENV DEBIAN_FRONTEND="noninteractive" +ENV IS_PTGB=true -RUN apt update && apt install -y build-essential cmake bison flex pkg-config libpng-dev git python3-pip python3-png python3-debugpy && pip install pandas requests openpyxl --break-system-packages +RUN apt-get update && apt-get install -y build-essential cmake bison flex pkg-config libpng-dev git python3-pip jq && pip install --root-user-action=ignore pandas requests openpyxl debugpy pypng --break-system-packages -RUN git clone https://github.com/gbdev/rgbds.git && cd rgbds && make -j$(nproc) && make install +RUN mkdir -p rgbds && curl -fsSL https://github.com/gbdev/rgbds/releases/download/v1.0.2+hotfix/rgbds-linux-x86_64.tar.xz | tar -xJ -C rgbds && cd rgbds && ./install.sh + +RUN git config --global --add safe.directory /ptgb \ No newline at end of file diff --git a/Makefile b/Makefile index 3af6076..ae40dae 100644 --- a/Makefile +++ b/Makefile @@ -1,362 +1,234 @@ +SHELL = /bin/sh +SRCDIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) +PYPACKAGES := debugpy pandas pypng requests openpyxl BUILD_LANGS := japanese english french german italian spanishEU spanishLA korean chineseSI chineseTR portugueseBR BUILD_TYPES := release debug -BUILD_XLSXS := local remote +BUILD_XLSXS := remote local -# defaults -BUILD_LANG ?= english -BUILD_TYPE ?= release -BUILD_XLSX ?= local +.ONESHELL: -ifneq ($(filter $(BUILD_LANG),$(BUILD_LANGS)),) -else - $(error $(BUILD_LANG) is not a valid build language) -endif +default: help -ifneq ($(filter $(BUILD_TYPE),$(BUILD_TYPES)),) -else - $(error $(BUILD_TYPE) is not a valid build type) -endif +.PHONY: help +help: # Display this help message + @tabs 2 + @printf "\033[1;4mTargets\033[0m\n" +# shows help for all targets that follow the format of "target: #", where target includes a-z, A-Z, 0-9, and _ characters + @grep -E '^[a-zA-Z0-9_]+: #' Makefile | while read -r l; do printf "\t\033[1;32m$$(echo $$l | cut -f 1 -d':')\033[00m:$$(echo $$l | cut -f 2- -d'#')\n"; done -ifneq ($(filter $(BUILD_XLSX),$(BUILD_XLSXS)),) -else - $(error $(BUILD_XLSX) is not a valid xlsx source) -endif +# if [ $(id | grep -c docker) = 0 ]; then +# $1 = command name +# $2 = package name +define check_package + @if [ "$(2)" = "docker" ]; then + if ! command -v $(1) >/dev/null 2>&1; then + printf "\033[1;31mDocker is not installed!\n" + printf "Please install Docker through your package manager.\033[0m\n" + exit + elif [ "$$(id | grep -c docker)" = 0 ]; then + printf "\033[1;31mUser is not in docker group!\033[0m\n" + if [ "$$(cat /etc/group | grep -c docker)" = 0 ]; then + echo "Creating docker group..." + sudo groupadd docker + fi + echo "Adding user to docker group..." + sudo usermod -aG docker $$USER + echo + printf "\033[1;31mPlease log out and log back in for this to take effect.\033[0m\n" + exit + else + echo "Docker is installed and user is in docker group." + fi + else + if ! command -v $(1) >/dev/null 2>&1; then + printf "\033[1;31m$(2) not found. Installing...\033[0m\n" + if [ "$(2)" = "rgbds" ]; then + mkdir -p rgbds && curl -L https://github.com/gbdev/rgbds/releases/download/v1.0.2+hotfix/rgbds-linux-x86_64.tar.xz | tar -xJ -C rgbds && cd rgbds && ./install.sh && cd .. && rm -rf rgbds + else + apt update && apt install -y $(1) + fi + else + echo "$(2) found." + fi + fi +endef -GIT_SUFFIX := $(shell git describe --tags --long --dirty | sed -E 's/^[^-]+-([0-9]+)-g[0-9a-f]+(-dirty)?$$/\1/') -GIT_FULL := $(shell git describe --tags --always --dirty 2>/dev/null) - -ifeq ($(GIT_SUFFIX),0) -GIT_VERSION = $(shell git describe --tags --abbrev=0) -else -GIT_VERSION = $(shell git describe --tags --abbrev=0)b -endif - -CMD_GOALS := $(filter-out build,$(MAKECMDGOALS)) - -LANG_INDEX := $(shell echo $(BUILD_LANGS) | tr ' ' '\n' | nl -v0 | grep -w $(BUILD_LANG) | awk '{print $$1 + 1}') -TYPE_INDEX := $(shell echo $(BUILD_TYPES) | tr ' ' '\n' | nl -v0 | grep -w $(BUILD_TYPE) | awk '{print $$1}') - -CPPFLAGS += -DPTGB_BUILD_LANGUAGE=$(LANG_INDEX) -CPPFLAGS += -DDEBUG_MODE=$(TYPE_INDEX) -CPPFLAGS += -DBUILD_INFO=\"$(GIT_FULL)\" - -CFLAGS += $(CPPFLAGS) -CXXFLAGS += $(CPPFLAGS) - - -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- - -ifeq ($(strip $(DEVKITARM)),) -$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") -endif - -include $(DEVKITARM)/gba_rules - -# The directory this makefile is located in. -# This is relevant when the second stage of this Makefile is called from the build directory. -MKFILE_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) - -#--------------------------------------------------------------------------------- -# the LIBGBA path is defined in gba_rules, but we have to define LIBTONC ourselves -#--------------------------------------------------------------------------------- -LIBTONC := $(DEVKITPRO)/libtonc -LIBPCCS := $(CURDIR)/PCCS - -#--------------------------------------------------------------------------------- -# Environment for building tool binaries using the host's compiler, not the devkitARM toolchain -# These tools need to run on the build machine, not the GBA. -#--------------------------------------------------------------------------------- -HOST_ENV := env - \ - PATH="$(PATH)" \ - TMPDIR=/tmp TMP=/tmp TEMP=/tmp \ - SYSTEMROOT="$(SYSTEMROOT)" \ - CC=cc \ - CXX=c++ \ - CFLAGS= \ - CXXFLAGS= \ - LDFLAGS= \ - AR=ar - -#--------------------------------------------------------------------------------- -# TARGET is the name of the output -# BUILD is the directory where object files & intermediate files will be placed -# SOURCES is a list of directories containing source code -# INCLUDES is a list of directories containing extra header files -# DATA is a list of directories containing binary data -# GRAPHICS is a list of directories containing files to be processed by grit -# -# All directories are specified relative to the project directory where -# the makefile is found -# -#--------------------------------------------------------------------------------- -TARGET := $(notdir $(CURDIR))_mb -LOADERNAME := $(notdir $(CURDIR))_standalone -BUILD := build -GENERATED_DIR := $(BUILD)/generated -SOURCES := source -INCLUDES := include PCCS/lib/include -DATA := data -MUSIC := audio -GRAPHICS := graphics graphics/languages/$(BUILD_LANG) -FILE_CONTAINERS := container - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -ARCH := -mthumb -mthumb-interwork - -CFLAGS += -Wall -O2\ - -mcpu=arm7tdmi -mtune=arm7tdmi -masm-syntax-unified\ - $(ARCH) - -CFLAGS += $(INCLUDE) -ffunction-sections -fdata-sections -Os -Wall -mthumb -mcpu=arm7tdmi -mtune=arm7tdmi -fstack-usage -CXXFLAGS += $(CFLAGS) -g0 -fno-rtti -fno-exceptions -fdata-sections -ffunction-sections -std=c++20 -Wno-volatile -D_GLIBCXX_USE_CXX20_ABI=0 -fstack-usage - -ifeq ($(BUILD_TYPE), debug) - CFLAGS += -O0 -g3 -DDEBUG - CXXFLAGS += -O0 -g3 -DDEBUG -else ifeq ($(BUILD_TYPE), release) - CFLAGS += -flto - - -endif - -ASFLAGS := $(ARCH) -LDFLAGS = -Os $(ARCH) -Wl,-Map,$(notdir $*.map) -Wl,--gc-sections -mthumb -mcpu=arm7tdmi -mtune=arm7tdmi -Wl,-Map,output.map,--cref -nodefaultlibs - -# eliminate libsysbase_libsysbase_a-handle_manager.o and its 4KB IWRAM buffer -LDFLAGS += -Wl,--wrap=__get_handle -Wl,--wrap=_close_r - -ifeq ($(BUILD_TYPE), release) -LDFLAGS += -flto -endif - -ifeq ($(BUILD_TYPE), debug) -ASFLAGS += -g -LDFLAGS += -O0 -g -endif - -#--------------------------------------------------------------------------------- -# any extra libraries we wish to link with the project -#--------------------------------------------------------------------------------- -LIBS := -lmm -ltonc -lgba -lc -lgcc -lsysbase -lpccs - - -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib. -# the LIBGBA path should remain in this list if you want to use maxmod -#--------------------------------------------------------------------------------- -LIBDIRS := $(LIBGBA) $(LIBTONC) $(LIBPCCS) - -#--------------------------------------------------------------------------------- -# no real need to edit anything past this point unless you need to add additional -# rules for different file extensions -#--------------------------------------------------------------------------------- - - -ifneq ($(BUILD),$(notdir $(CURDIR))) -#--------------------------------------------------------------------------------- - -export OUTPUT := $(CURDIR)/$(TARGET) - -SOURCE_DIRS_RECURSIVE := $(shell find $(SOURCES) -type d) - -export VPATH := $(CURDIR)/$(GENERATED_DIR) \ - $(foreach dir,$(SOURCE_DIRS_RECURSIVE),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ - $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) - -export DEPSDIR := $(CURDIR)/$(BUILD) - -CFILES := $(sort $(notdir $(shell find $(SOURCES) -type f -name "*.c"))) -CPPFILES := $(sort $(notdir $(shell find $(SOURCES) -type f -name "*.cpp")) translated_text.cpp) -SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) - -#--------------------------------------------------------------------------------- -# use CXX for linking C++ projects, CC for standard C -#--------------------------------------------------------------------------------- -ifeq ($(strip $(CPPFILES)),) -#--------------------------------------------------------------------------------- - export LD := $(CC) -#--------------------------------------------------------------------------------- -else -#--------------------------------------------------------------------------------- - export LD := $(CXX) -#--------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------- - -export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) - -export OFILES_GRAPHICS := $(PNGFILES:.png=.o) - -export OFILES := $(OFILES_SOURCES) $(OFILES_GRAPHICS) - -ifneq ($(strip $(MUSIC)),) - export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) - BINFILES += soundbank.bin - OFILES += soundbank.bin.o -endif - -export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(PNGFILES:.png=.h) - -export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I$(CURDIR)/$(GENERATED_DIR) \ - -I$(CURDIR)/PCCS/tools/table-generator/include \ - -I$(CURDIR)/$(BUILD) - -export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) - -.PHONY: all clean - -GENERATE_STAMP := $(BUILD)/.generate_data.$(BUILD_LANG).$(BUILD_TYPE).stamp -BUILD_STAMP := $(BUILD)/.build.$(BUILD_LANG).$(BUILD_TYPE).stamp - -TEXT_GENERATED_OUTPUTS := \ - $(GENERATED_DIR)/translated_text.h \ - $(GENERATED_DIR)/translated_text.cpp \ - $(GENERATED_DIR)/fonts.h - -all: - @set -e; \ - if [ "$(BUILD_XLSX)" = "remote" ]; then \ - $(MAKE) --no-print-directory text_generated BUILD_LANG=$(BUILD_LANG) BUILD_TYPE=$(BUILD_TYPE) BUILD_XLSX=$(BUILD_XLSX); \ - fi; \ - before=$$(stat -c %Y $(BUILD_STAMP) 2>/dev/null || echo 0); \ - $(MAKE) --no-print-directory $(BUILD_STAMP) BUILD_LANG=$(BUILD_LANG) BUILD_TYPE=$(BUILD_TYPE) BUILD_XLSX=$(BUILD_XLSX); \ - after=$$(stat -c %Y $(BUILD_STAMP) 2>/dev/null || echo 0); \ - if [ "$$before" = "$$after" ] && [ "$$after" != "0" ]; then \ - echo "PTGB build up to date."; \ +.PHONY: setup +setup: # Setup all required dependencies + @if [ -f /.dockerenv ] || [ -n "$$GITPOD" ]; then + if [ ! "$$(IS_PTGB)" ]; then + printf "\033[1;31mRunning inside an non-Poké Transporter GB Docker shell!\n" + printf "Please run this on the host machine or inside the Poké Transporter GB's Docker shell.\033[0m" + exit + else + echo "Running in Docker shell; continuing..." + fi + else + echo "Running outside of Docker shell. Checking Docker installation..." + $(call check_package,docker,docker) + if [ "$$(docker container ls -f "name=ptgb" --format "{{.Names}}")" = "ptgb" ]; then + echo "Docker container found and running." + elif [ "$$(docker container ls -af "name=ptgb" --format "{{.Names}}")" = "ptgb" ]; then + echo "Docker container found; starting..." + docker start ptgb >/dev/null + else + echo "Docker container does not exist." + echo "Checking status of docker buildx..." + if docker buildx version >/dev/null 2>&1; then + echo "buildx installed. Continuing..." + else + printf "\033[1;31mbuildx is not installed!\n" + printf "\033[1;31mPlease install through your package manager.\n" + exit + fi + echo "Creating Docker image..." + mkdir -p $(SRCDIR)/docker-build && cd $(SRCDIR)/docker-build + DOCKER_BUILDKIT=1 docker build -t ptgb-builder:latest -f $(SRCDIR)/Dockerfile $(SRCDIR)/docker-build + rm -rf $(SRCDIR)/docker-build + echo + echo "Creating Docker container..." + docker container create -w /ptgb -v $(SRCDIR):/ptgb --name ptgb -it ptgb-builder:latest + echo "Starting Docker container..." + docker start ptgb >/dev/null + fi + echo + docker exec ptgb make --no-print-directory -C /ptgb _setup + echo + printf "\033[1;32mEverything is set up!\033[0m\n" fi -text_generated: to_compress generated_dir data - @PTGB_GEN_DIR="$(CURDIR)/$(GENERATED_DIR)" python3 tools/text_helper/main.py $(BUILD_LANG) $(BUILD_TYPE) $(BUILD_XLSX) +_setup: + @echo "Checking Docker container's packages..." +# Python + $(call check_package,python3,python3) + + for package in $(PYPACKAGES); do + if pip show "$$package" > /dev/null 2>&1; then + echo "$$package found." + else + echo "Installing $$package" + pip install --root-user-action=ignore "$$package" + fi + done -data: - @mkdir -p $@ +# rgbds + $(call check_package,rgbasm,rgbds) +# jq + $(call check_package,jq,jq) -to_compress: - @mkdir -p $@ -generated_dir: - @mkdir -p $(GENERATED_DIR) - -generate_data: $(GENERATE_STAMP) - -$(GENERATE_STAMP): compress_lz10.sh | data to_compress generated_dir - @if [ "$(BUILD_XLSX)" != "remote" ]; then \ - $(MAKE) --no-print-directory text_generated BUILD_LANG=$(BUILD_LANG) BUILD_TYPE=$(BUILD_TYPE) BUILD_XLSX=$(BUILD_XLSX); \ +# $1 = command name +# $2 = package name +define check_package_host + @if ! command -v $(1) >/dev/null 2>&1; then + printf "\033[1;31m$(2) is not installed!\n" + printf "Please install $(2) through your package manager.\033[0m\n" + exit fi - @echo "----------------------------------------------------------------" - @echo "Building v$(GIT_VERSION) with parameters: $(BUILD_LANG), $(BUILD_TYPE), $(BUILD_XLSX)" - @echo "----------------------------------------------------------------" - @$(HOST_ENV) $(MAKE) -C tools/make-file-container - @$(HOST_ENV) $(MAKE) -C tools/gb-payload-generator - @echo - @echo "----------------------------------------------------------------" - @echo - @find $(FILE_CONTAINERS) -name "*.containerdef" -print0 | xargs -0 -n1 tools/make-file-container/make-file-container -H $(BUILD) to_compress - @find tools/text_helper/build -name "*.containerdef" -print0 | xargs -0 -n1 tools/make-file-container/make-file-container to_compress - @echo "Compressing bin files!" - @echo -n "[" - @find to_compress -name "*.bin" -print0 | xargs -0 -n1 ./compress_lz10.sh - @echo "]" - @echo "Compressing finished!" - @echo - @echo "----------------------------------------------------------------" - @echo - @touch $@ +endef -#--------------------------------------------------------------------------------- -$(BUILD_STAMP): $(GENERATE_STAMP) | $(BUILD) - @$(MAKE) -C PCCS \ - CC="$(CC)" \ - CXX="$(CXX)" \ - CFLAGS="$(CFLAGS)" \ - CXXFLAGS="$(CXXFLAGS)" \ - LDFLAGS="$(LDFLAGS)" - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - @mkdir -p loader/data - @cp $(TARGET).gba loader/data/multiboot_rom.bin - @$(MAKE) -C loader - @cp loader/loader.gba $(LOADERNAME).gba - @touch $@ +.PHONY: configure +configure: # Specify BUILD_LANG, BUILD_TYPE, and BUILD_XLSX + $(call check_package_host,dialog,dialog) + $(call check_package_host,jq,jq) + +# generate default options.json (based on makefile vars) if it doesn't already exist + @touch $(SRCDIR)/options.json -$(BUILD): - @mkdir -p $@ + set -- $(BUILD_LANGS) + langs=$$(printf '%s\n' "$$@" | jq -R -s 'split("\n")[:-1]') -#--------------------------------------------------------------------------------- -clean: - @echo clean ... - @$(MAKE) -C tools/make-file-container clean - @$(MAKE) -C tools/gb-payload-generator clean - @$(MAKE) -C loader clean - @$(MAKE) -C PCCS clean - @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba $(LOADERNAME).gba data/ to_compress/ - @rm -f text_helper/output.json - @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba data/ to_compress/ - @rm -fr $(GENERATED_DIR) + set -- $(BUILD_TYPES) + types=$$(printf '%s\n' "$$@" | jq -R -s 'split("\n")[:-1]') + set -- $(BUILD_XLSXS) + xlsxs=$$(printf '%s\n' "$$@" | jq -R -s 'split("\n")[:-1]') + jq -n \ + --argjson langs "$$langs" \ + --argjson types "$$types" \ + --argjson xlsxs "$$xlsxs" \ + '{ + BUILD_LANGS: $$langs, + BUILD_TYPES: $$types, + BUILD_XLSXS: $$xlsxs, + selected: { + lang: "", + type: "", + xlsx: "" + } + }' > "$(SRCDIR)/options.json" -#--------------------------------------------------------------------------------- -else + menu() { + title="$$1" + json="$$2" + array_key="$$3" -BINFILES := $(foreach dir,../$(DATA),$(notdir $(wildcard $(dir)/*.*))) -export OFILES_BIN := $(addsuffix .o,$(BINFILES)) -OFILES := $(OFILES_BIN) $(OFILES) + menu_args="" + i=1 -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- + while IFS= read -r item; do + menu_args="$$menu_args $$i $$item" + i=$$((i + 1)) + done <&2 + return 1 + ;; + 255) + printf "\033[1;31mUser pressed escape.\033[0m\n" >&2 + return 1 + ;; + *) + printf "\033[1;31mUnknown error occurred.\033[0m\n" >&2 + return 1 + ;; + esac + } -$(OFILES_SOURCES) : $(HFILES) +# prompt user for selections + if ! LANG=$$(menu "ROM Language" options.json "BUILD_LANGS"); then + exit 1 + fi + if ! TYPE=$$(menu "ROM Type" options.json "BUILD_TYPES"); then + exit 1 + fi + if ! XLSX=$$(menu "Text Source" options.json "BUILD_XLSXS"); then + exit 1 + fi + clear + tmp=$$(mktemp) +# store selections in options.json + jq \ + --arg lang "$$LANG" \ + --arg type "$$TYPE" \ + --arg xlsx "$$XLSX" \ + '.selected.lang = $$lang | .selected.type = $$type | .selected.xlsx = $$xlsx' \ + $(SRCDIR)/options.json > "$tmp" && mv "$tmp" $(SRCDIR)/options.json -#--------------------------------------------------------------------------------- -# The bin2o rule should be copied and modified -# for each extension used in the data directories -#--------------------------------------------------------------------------------- + @printf "\033[1;32mBuild configured!\033[0m\n" -#--------------------------------------------------------------------------------- -# rule to build soundbank from music files -#--------------------------------------------------------------------------------- -soundbank.bin soundbank.h : $(AUDIOFILES) -#--------------------------------------------------------------------------------- - @mmutil $^ -osoundbank.bin -hsoundbank.h +.PHONY: clean +clean: # Cleans the build directory + @echo "Starting Docker container..." + @docker start ptgb >/dev/null + @docker exec ptgb make -f /ptgb/container.mk -C /ptgb clean -#--------------------------------------------------------------------------------- -# This rule links in binary data with the .bin extension -#--------------------------------------------------------------------------------- -%.bin.o %_bin.h : %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -#--------------------------------------------------------------------------------- -# This rule creates C source files using grit -# grit takes an image file and a .grit describing how the file is to be processed -# add additional rules like this for each image extension -# you use in the graphics folders -#--------------------------------------------------------------------------------- -%.c %.h: %.png %.grit -#--------------------------------------------------------------------------------- - @echo "grit $(notdir $<)" - @grit $< -ftc -o$* - -# make likes to delete intermediate files. This prevents it from deleting the -# files generated by grit after building the GBA ROM. -.SECONDARY: - --include $(DEPSDIR)/*.d -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- +.PHONY: build +build: # Builds the ROM + @echo "Starting Docker container..." + @docker start ptgb >/dev/null + @docker exec ptgb make -f /ptgb/container.mk -C /ptgb all \ No newline at end of file diff --git a/container.mk b/container.mk new file mode 100644 index 0000000..71a2456 --- /dev/null +++ b/container.mk @@ -0,0 +1,344 @@ +SRCDIR = /ptgb + +BUILD_LANGS := $(shell jq -r '.BUILD_LANGS | join (" ")' < $(SRCDIR)/options.json) +BUILD_TYPES := $(shell jq -r '.BUILD_TYPES | join (" ")' < $(SRCDIR)/options.json) +BUILD_XLSXS := $(shell jq -r '.BUILD_XLSXS | join (" ")' < $(SRCDIR)/options.json) + +BUILD_LANG ?= $(shell jq -r '.selected.lang' < $(SRCDIR)/options.json) +BUILD_TYPE ?= $(shell jq -r '.selected.type' < $(SRCDIR)/options.json) +BUILD_XLSX ?= $(shell jq -r '.selected.xlsx' < $(SRCDIR)/options.json) + +GIT_SUFFIX := $(shell git describe --tags --long --dirty | sed -E 's/^[^-]+-([0-9]+)-g[0-9a-f]+(-dirty)?$$/\1/') +GIT_FULL := $(shell git describe --tags --always --dirty 2>/dev/null) + +ifeq ($(GIT_SUFFIX),0) +GIT_VERSION = $(shell git describe --tags --abbrev=0) +else +GIT_VERSION = $(shell git describe --tags --abbrev=0)b +endif + +CMD_GOALS := $(filter-out build,$(MAKECMDGOALS)) + +LANG_INDEX := $(shell echo $(BUILD_LANGS) | tr ' ' '\n' | nl -v0 | grep -w $(BUILD_LANG) | awk '{print $$1 + 1}') +TYPE_INDEX := $(shell echo $(BUILD_TYPES) | tr ' ' '\n' | nl -v0 | grep -w $(BUILD_TYPE) | awk '{print $$1}') + +CPPFLAGS += -DPTGB_BUILD_LANGUAGE=$(LANG_INDEX) +CPPFLAGS += -DDEBUG_MODE=$(TYPE_INDEX) +CPPFLAGS += -DBUILD_INFO=\"$(GIT_FULL)\" + +CFLAGS += $(CPPFLAGS) +CXXFLAGS += $(CPPFLAGS) + + +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- + +include $(DEVKITARM)/gba_rules + +# The directory this makefile is located in. +# This is relevant when the second stage of this Makefile is called from the build directory. +MKFILE_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) + +#--------------------------------------------------------------------------------- +# the LIBGBA path is defined in gba_rules, but we have to define LIBTONC ourselves +#--------------------------------------------------------------------------------- +LIBTONC := $(DEVKITPRO)/libtonc +LIBPCCS := $(CURDIR)/PCCS + +#--------------------------------------------------------------------------------- +# Environment for building tool binaries using the host's compiler, not the devkitARM toolchain +# These tools need to run on the build machine, not the GBA. +#--------------------------------------------------------------------------------- +HOST_ENV := env - \ + PATH="$(PATH)" \ + TMPDIR=/tmp TMP=/tmp TEMP=/tmp \ + SYSTEMROOT="$(SYSTEMROOT)" \ + CC=cc \ + CXX=c++ \ + CFLAGS= \ + CXXFLAGS= \ + LDFLAGS= \ + AR=ar + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +# DATA is a list of directories containing binary data +# GRAPHICS is a list of directories containing files to be processed by grit +# +# All directories are specified relative to the project directory where +# the makefile is found +# +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR))_mb +LOADERNAME := $(notdir $(CURDIR))_standalone +BUILD := build +GENERATED_DIR := $(BUILD)/generated +SOURCES := source +INCLUDES := include PCCS/lib/include +DATA := data +MUSIC := audio +GRAPHICS := graphics graphics/languages/$(BUILD_LANG) +FILE_CONTAINERS := container + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- +ARCH := -mthumb -mthumb-interwork + +CFLAGS += -Wall -O2\ + -mcpu=arm7tdmi -mtune=arm7tdmi -masm-syntax-unified\ + $(ARCH) + +CFLAGS += $(INCLUDE) -ffunction-sections -fdata-sections -Os -Wall -mthumb -mcpu=arm7tdmi -mtune=arm7tdmi -fstack-usage +CXXFLAGS += $(CFLAGS) -g0 -fno-rtti -fno-exceptions -fdata-sections -ffunction-sections -std=c++20 -Wno-volatile -D_GLIBCXX_USE_CXX20_ABI=0 -fstack-usage + +ifeq ($(BUILD_TYPE), debug) + CFLAGS += -O0 -g3 -DDEBUG + CXXFLAGS += -O0 -g3 -DDEBUG +else ifeq ($(BUILD_TYPE), release) + CFLAGS += -flto + + +endif + +ASFLAGS := $(ARCH) +LDFLAGS = -Os $(ARCH) -Wl,-Map,$(notdir $*.map) -Wl,--gc-sections -mthumb -mcpu=arm7tdmi -mtune=arm7tdmi -Wl,-Map,output.map,--cref -nodefaultlibs + +# eliminate libsysbase_libsysbase_a-handle_manager.o and its 4KB IWRAM buffer +LDFLAGS += -Wl,--wrap=__get_handle -Wl,--wrap=_close_r + +ifeq ($(BUILD_TYPE), release) +LDFLAGS += -flto +endif + +ifeq ($(BUILD_TYPE), debug) +ASFLAGS += -g +LDFLAGS += -O0 -g +endif + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lmm -ltonc -lgba -lc -lgcc -lsysbase -lpccs + + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib. +# the LIBGBA path should remain in this list if you want to use maxmod +#--------------------------------------------------------------------------------- +LIBDIRS := $(LIBGBA) $(LIBTONC) $(LIBPCCS) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- + + +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +SOURCE_DIRS_RECURSIVE := $(shell find $(SOURCES) -type d) + +export VPATH := $(CURDIR)/$(GENERATED_DIR) \ + $(foreach dir,$(SOURCE_DIRS_RECURSIVE),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ + $(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +CFILES := $(sort $(notdir $(shell find $(SOURCES) -type f -name "*.c"))) +CPPFILES := $(sort $(notdir $(shell find $(SOURCES) -type f -name "*.cpp")) translated_text.cpp) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +PNGFILES := $(foreach dir,$(GRAPHICS),$(notdir $(wildcard $(dir)/*.png))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) +#--------------------------------------------------------------------------------- + export LD := $(CC) +#--------------------------------------------------------------------------------- +else +#--------------------------------------------------------------------------------- + export LD := $(CXX) +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) + +export OFILES_GRAPHICS := $(PNGFILES:.png=.o) + +export OFILES := $(OFILES_SOURCES) $(OFILES_GRAPHICS) + +ifneq ($(strip $(MUSIC)),) + export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir)) + BINFILES += soundbank.bin + OFILES += soundbank.bin.o +endif + +export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES))) $(PNGFILES:.png=.h) + +export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(GENERATED_DIR) \ + -I$(CURDIR)/PCCS/tools/table-generator/include \ + -I$(CURDIR)/$(BUILD) + +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) + +.PHONY: all clean + +GENERATE_STAMP := $(BUILD)/.generate_data.$(BUILD_LANG).$(BUILD_TYPE).stamp +BUILD_STAMP := $(BUILD)/.build.$(BUILD_LANG).$(BUILD_TYPE).stamp + +TEXT_GENERATED_OUTPUTS := \ + $(GENERATED_DIR)/translated_text.h \ + $(GENERATED_DIR)/translated_text.cpp \ + $(GENERATED_DIR)/fonts.h + +all: + @set -e; \ + if [ "$(BUILD_XLSX)" = "remote" ]; then \ + $(MAKE) --no-print-directory -f $(SRCDIR)/container.mk text_generated BUILD_LANG=$(BUILD_LANG) BUILD_TYPE=$(BUILD_TYPE) BUILD_XLSX=$(BUILD_XLSX); \ + fi; \ + before=$$(stat -c %Y $(BUILD_STAMP) 2>/dev/null || echo 0); \ + $(MAKE) --no-print-directory -f $(SRCDIR)/container.mk $(BUILD_STAMP) BUILD_LANG=$(BUILD_LANG) BUILD_TYPE=$(BUILD_TYPE) BUILD_XLSX=$(BUILD_XLSX); \ + after=$$(stat -c %Y $(BUILD_STAMP) 2>/dev/null || echo 0); \ + if [ "$$before" = "$$after" ] && [ "$$after" != "0" ]; then \ + echo "PTGB build up to date."; \ + fi + +text_generated: to_compress generated_dir data + @PTGB_GEN_DIR="$(CURDIR)/$(GENERATED_DIR)" python3 tools/text_helper/main.py $(BUILD_LANG) $(BUILD_TYPE) $(BUILD_XLSX) + +data: + @mkdir -p $@ + +to_compress: + @mkdir -p $@ + +generated_dir: + @mkdir -p $(GENERATED_DIR) + +generate_data: $(GENERATE_STAMP) + +$(GENERATE_STAMP): compress_lz10.sh | data to_compress generated_dir + @if [ "$(BUILD_XLSX)" != "remote" ]; then \ + $(MAKE) --no-print-directory -f $(SRCDIR)/container.mk text_generated BUILD_LANG=$(BUILD_LANG) BUILD_TYPE=$(BUILD_TYPE) BUILD_XLSX=$(BUILD_XLSX); \ + fi + @echo "----------------------------------------------------------------" + @echo "Building v$(GIT_VERSION) with parameters: $(BUILD_LANG), $(BUILD_TYPE), $(BUILD_XLSX)" + @echo "----------------------------------------------------------------" + @$(HOST_ENV) $(MAKE) -C tools/make-file-container + @$(HOST_ENV) $(MAKE) -C tools/gb-payload-generator + @echo + @echo "----------------------------------------------------------------" + @echo + @find $(FILE_CONTAINERS) -name "*.containerdef" -print0 | xargs -0 -n1 tools/make-file-container/make-file-container -H $(BUILD) to_compress + @find tools/text_helper/build -name "*.containerdef" -print0 | xargs -0 -n1 tools/make-file-container/make-file-container to_compress + @echo "Compressing bin files!" + @echo -n "[" + @find to_compress -name "*.bin" -print0 | xargs -0 -n1 ./compress_lz10.sh + @echo "]" + @echo "Compressing finished!" + @echo + @echo "----------------------------------------------------------------" + @echo + @touch $@ + +#--------------------------------------------------------------------------------- +$(BUILD_STAMP): $(GENERATE_STAMP) | $(BUILD) + @$(MAKE) -C PCCS \ + CC="$(CC)" \ + CXX="$(CXX)" \ + CFLAGS="$(CFLAGS)" \ + CXXFLAGS="$(CXXFLAGS)" \ + LDFLAGS="$(LDFLAGS)" + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/container.mk + @mkdir -p loader/data + @cp $(TARGET).gba loader/data/multiboot_rom.bin + @$(MAKE) -C loader + @cp loader/loader.gba $(LOADERNAME).gba + @touch $@ + +$(BUILD): + @mkdir -p $@ + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @$(MAKE) -C tools/make-file-container clean + @$(MAKE) -C tools/gb-payload-generator clean + @$(MAKE) -C loader clean + @$(MAKE) -C PCCS clean + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba $(LOADERNAME).gba data/ to_compress/ + @rm -f text_helper/output.json + @rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba data/ to_compress/ + @rm -fr $(GENERATED_DIR) + + + +#--------------------------------------------------------------------------------- +else + +BINFILES := $(foreach dir,../$(DATA),$(notdir $(wildcard $(dir)/*.*))) +export OFILES_BIN := $(addsuffix .o,$(BINFILES)) +OFILES := $(OFILES_BIN) $(OFILES) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- + +$(OUTPUT).gba : $(OUTPUT).elf + +$(OUTPUT).elf : $(OFILES) + +$(OFILES_SOURCES) : $(HFILES) + +#--------------------------------------------------------------------------------- +# The bin2o rule should be copied and modified +# for each extension used in the data directories +#--------------------------------------------------------------------------------- + +#--------------------------------------------------------------------------------- +# rule to build soundbank from music files +#--------------------------------------------------------------------------------- +soundbank.bin soundbank.h : $(AUDIOFILES) +#--------------------------------------------------------------------------------- + @mmutil $^ -osoundbank.bin -hsoundbank.h + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .bin extension +#--------------------------------------------------------------------------------- +%.bin.o %_bin.h : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + +#--------------------------------------------------------------------------------- +# This rule creates C source files using grit +# grit takes an image file and a .grit describing how the file is to be processed +# add additional rules like this for each image extension +# you use in the graphics folders +#--------------------------------------------------------------------------------- +%.c %.h: %.png %.grit +#--------------------------------------------------------------------------------- + @echo "grit $(notdir $<)" + @grit $< -ftc -o$* + +# make likes to delete intermediate files. This prevents it from deleting the +# files generated by grit after building the GBA ROM. +.SECONDARY: + +-include $(DEPSDIR)/*.d +#--------------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------------- diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 8bba183..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,27 +0,0 @@ -# This docker-compose file allows you to pull the devkitpro/devkitarm docker container -# and use it to build the Poke Transporter GB rom(s). -# -# To launch the container itself in the background: -# docker compose up -d -# Note the container name being printed in the terminal. In my case it was this: poke_transporter_gb-build-1 -# -# Then get a terminal into the container like this: -# docker exec -it poke_transporter_gb-build-1 /bin/bash -# -# Now you can build the project inside this terminal. - -version: "3.5" - -services: - build: - image: ptgb-builder:latest - working_dir: /usr/Poke_Transporter_GB - command: tail -F anything - volumes: - - type: bind - source: ${SSH_AUTH_SOCK} - target: ${SSH_AUTH_SOCK} - - type: bind - source: ${PWD} - target: /usr/Poke_Transporter_GB - diff --git a/loader/data/multiboot_rom.bin b/loader/data/multiboot_rom.bin new file mode 100755 index 0000000..a154c40 Binary files /dev/null and b/loader/data/multiboot_rom.bin differ diff --git a/tools/text_helper/text.xlsx b/tools/text_helper/text.xlsx index c65690a..8807dfd 100644 Binary files a/tools/text_helper/text.xlsx and b/tools/text_helper/text.xlsx differ