diff --git a/.gitignore b/.gitignore index 170aaea..a6d31fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /bin/ /obj/ /dep/ -/res/ +/assets/ diff --git a/Makefile b/Makefile index a3ef25e..26c42e9 100644 --- a/Makefile +++ b/Makefile @@ -1,121 +1,89 @@ -.SUFFIXES: +.SUFFIXES: # Suppress a lot of useless default rules, which also provides a nice speedup. -################################################ -# # -# CONSTANT DEFINITIONS # -# # -################################################ +# Recursive `wildcard` function. +rwildcard = $(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) -## Directory constants -# These directories can be placed elsewhere if you want; directories whose placement -# must be fixed, lest this Makefile breaks, are hardcoded throughout this Makefile -BINDIR := bin -OBJDIR := obj -DEPDIR := dep - -# Program constants -ifneq ($(strip $(shell which rm)),) - # POSIX OSes - RM_RF := rm -rf - MKDIR_P := mkdir -p -else - # Windows - RM_RF := -del /q - MKDIR_P := -mkdir +# Program constants. +# POSIX OSes (the sane default). +RM_RF := rm -rf +MKDIR_P := mkdir -p +ifeq ($(strip $(shell which rm)),) + # Windows *really* tries its hardest to be Special™! + RM_RF := -del /q + MKDIR_P := -mkdir endif -# Shortcut if you want to use a local copy of RGBDS -RGBDS := -RGBASM := $(RGBDS)rgbasm -RGBLINK := $(RGBDS)rgblink -RGBFIX := $(RGBDS)rgbfix +RGBDS ?= # Shortcut if you want to use a local copy of RGBDS. +RGBASM := ${RGBDS}rgbasm +RGBLINK := ${RGBDS}rgblink +RGBFIX := ${RGBDS}rgbfix +RGBGFX := ${RGBDS}rgbgfx -ROM = $(BINDIR)/$(ROMNAME).$(ROMEXT) +ROM = bin/${ROMNAME}.${ROMEXT} # Argument constants INCDIRS = src/ src/include/ WARNINGS = all extra -ASFLAGS = -p $(PADVALUE) $(addprefix -i,$(INCDIRS)) $(addprefix -W,$(WARNINGS)) -LDFLAGS = -p $(PADVALUE) -FIXFLAGS = -p $(PADVALUE) -v -i "$(GAMEID)" -k "$(LICENSEE)" -l $(OLDLIC) -m $(MBC) -n $(VERSION) -r $(SRAMSIZE) -t $(TITLE) +ASFLAGS = -p ${PADVALUE} $(addprefix -I,${INCDIRS}) $(addprefix -W,${WARNINGS}) +LDFLAGS = -p ${PADVALUE} +FIXFLAGS = -p ${PADVALUE} -i "${GAMEID}" -k "${LICENSEE}" -l ${OLDLIC} -m ${MBC} -n ${VERSION} -r ${SRAMSIZE} -t ${TITLE} -# The list of "root" ASM files that RGBASM will be invoked on -SRCS = $(wildcard src/*.asm) +# The list of ASM files that RGBASM will be invoked on. +SRCS = $(call rwildcard,src,*.asm) ## Project-specific configuration # Use this to override the above include project.mk -################################################ -# # -# TARGETS # -# # -################################################ - # `all` (Default target): build the ROM -all: $(ROM) +all: ${ROM} .PHONY: all # `clean`: Clean temp and bin files clean: - $(RM_RF) $(BINDIR) - $(RM_RF) $(OBJDIR) - $(RM_RF) $(DEPDIR) - $(RM_RF) res + ${RM_RF} bin obj assets .PHONY: clean # `rebuild`: Build everything from scratch # It's important to do these two in order if we're using more than one job rebuild: - $(MAKE) clean - $(MAKE) all + ${MAKE} clean + ${MAKE} all .PHONY: rebuild -############################################### -# # -# COMPILATION # -# # -############################################### - -# How to build a ROM -$(BINDIR)/%.$(ROMEXT) $(BINDIR)/%.sym $(BINDIR)/%.map: $(patsubst src/%.asm,$(OBJDIR)/%.o,$(SRCS)) - @$(MKDIR_P) $(@D) - $(RGBASM) $(ASFLAGS) -o $(OBJDIR)/build_date.o src/res/build_date.asm - $(RGBLINK) $(LDFLAGS) -m $(BINDIR)/$*.map -n $(BINDIR)/$*.sym -o $(BINDIR)/$*.$(ROMEXT) $^ $(OBJDIR)/build_date.o \ - && $(RGBFIX) -v $(FIXFLAGS) $(BINDIR)/$*.$(ROMEXT) - -# `.mk` files are auto-generated dependency lists of the "root" ASM files, to save a lot of hassle. -# Also add all obj dependencies to the dep file too, so Make knows to remake it -# Caution: some of these flags were added in RGBDS 0.4.0, using an earlier version WILL NOT WORK -# (and produce weird errors) -$(OBJDIR)/%.o $(DEPDIR)/%.mk: src/%.asm - @$(MKDIR_P) $(patsubst %/,%,$(dir $(OBJDIR)/$* $(DEPDIR)/$*)) - $(RGBASM) $(ASFLAGS) -M $(DEPDIR)/$*.mk -MG -MP -MQ $(OBJDIR)/$*.o -MQ $(DEPDIR)/$*.mk -o $(OBJDIR)/$*.o $< - -ifneq ($(MAKECMDGOALS),clean) --include $(patsubst src/%.asm,$(DEPDIR)/%.mk,$(SRCS)) -endif - -################################################ -# # -# RESOURCE FILES # -# # -################################################ - - -# By default, asset recipes convert files in `res/` into other files in `res/` -# This line causes assets not found in `res/` to be also looked for in `src/res/` -# "Source" assets can thus be safely stored there without `make clean` removing them +# By default, asset recipes convert files in `assets/` into other files in `assets/`. +# This line causes assets not found in `assets/` to be also looked for in `src/assets/`. +# "Source" assets can thus be safely stored there without `make clean` removing them! VPATH := src -# Define how to compress files using the PackBits16 codec -# Compressor script requires Python 3 -res/%.pb16: src/tools/pb16.py res/% - @$(MKDIR_P) $(@D) +# Define how to compress files using the PackBits16 codec. +# (The compressor script requires Python 3.) +assets/%.pb16: src/tools/pb16.py assets/% + @${MKDIR_P} ${@D} $^ $@ -# Catch non-existent files -# KEEP THIS LAST!! -%: - @false +# How to build a ROM. +# Notice that the build date is always refreshed. +bin/%.${ROMEXT}: $(patsubst src/%.asm,obj/%.o,${SRCS}) + @${MKDIR_P} ${@D} + ${RGBASM} ${ASFLAGS} -o obj/build_date.o src/assets/build_date.asm + ${RGBLINK} ${LDFLAGS} -m bin/$*.map -n bin/$*.sym -o $@ $^ \ + && ${RGBFIX} -v ${FIXFLAGS} $@ + +# `.mk` files are auto-generated dependency lists of the source ASM files, to save a lot of hassle. +# Also add all obj dependencies to the dep file too, so Make knows to remake it. +# Caution: some of these flags were added in RGBDS 0.4.0, using an earlier version WILL NOT WORK +# (and produce weird errors). +obj/%.mk: src/%.asm + @${MKDIR_P} ${@D} + ${RGBASM} ${ASFLAGS} -M $@ -MG -MP -MQ ${@:.mk=.o} -MQ $@ -o ${@:.mk=.o} $< +# DO NOT merge this with the rule above, otherwise Make will assume that the `.o` file is generated, +# even when it isn't! +# This causes weird issues that depend, among other things, on the version of Make. +obj/%.o: obj/%.mk + @touch $@ + +ifeq ($(filter clean,${MAKECMDGOALS}),) +include $(patsubst src/%.asm,obj/%.mk,${SRCS}) +endif diff --git a/README.md b/README.md index 4c6f55f..9087a11 100644 --- a/README.md +++ b/README.md @@ -12,19 +12,31 @@ Make sure you have [RGBDS](https://github.com/rednex/rgbds), at least version 0. ## Customizing -Edit `project.mk` to customize most things specific to the project (like the game name, file name and extension, etc.). Everything has accompanying doc comments. +Edit `project.mk` to customize most things specific to the project (like the game name, file name and extension, etc.). +Everything has accompanying doc comments. -Everything in the `src` folder is the source, and can be freely modified however you want. The basic structure in place should hint you at how things are organized. If you want to create a new "module", you simply need to drop a `.asm` file in the `src` directory, name does not matter. All `.asm` files in that root directory will be individually compiled by RGBASM. +Everything in the `src` directory is the source, and can be freely modified however you want. +Any `.asm` files in that directory (and its sub-directories, recursively) will be individually assembled, automatically. +If you need some files not to be assembled directly (because they are only meant to be `INCLUDE`d), you can either rename them (typically, to `.inc`), or move them outside of `src` (typically, to a directory called `include`). -The file at `src/res/build_date.asm` is compiled individually to include a build date in your ROM. Always comes in handy. +The file at `src/assets/build_date.asm` is compiled individually to include a build date in your ROM. +Always comes in handy. -If you want to add resources, I recommend using the `src/res` folder. Add rules in the Makefile; an example is provided for compressing files using PB16 (a variation of [PackBits](https://wiki.nesdev.com/w/index.php/Tile_compression#PackBits)). +If you want to add resources, I recommend using the `src/assets` directory. +Add rules in the Makefile; an example is provided for compressing files using PB16 (a variation of [PackBits](https://wiki.nesdev.com/w/index.php/Tile_compression#PackBits)). ## Compiling -Simply open you favorite command prompt / terminal, place yourself in this directory (the one the Makefile is located in), and run the command `make`. This should create a bunch of things, including the output in the `bin` folder. +Simply open you favorite command prompt / terminal, place yourself in this directory (the one the Makefile is located in), and run the command `make`. +This should create a bunch of things, including the output in the `bin` directory. -If you get errors that you don't understand, try running `make clean`. If that gives the same error, try deleting the `deps` folder. If that still doesn't work, try deleting the `bin` and `obj` folders as well. If that still doesn't work, you probably did something wrong yourself. +Pass the `-s` flag to `make` if it spews too much input for your tastes. +Päss the `-j ` flag to `make` to build more things in parallel, replacing `` with however many things you want to build in parallel; your number of (logical) CPU cores is often a good pick (so, `-j 8` for me), run the command `nproc` to obtain it. + +If you get errors that you don't understand, try running `make clean`. +If that gives the same error, try deleting the `assets` directory. +If that still doesn't work, try deleting the `bin` and `obj` directories as well. +If that still doesn't work, feel free to ask for help. ## See also @@ -32,9 +44,10 @@ If you want something less barebones, already including some "base" code, check Perhaps [a gbdev style guide](https://gbdev.io/guides/asmstyle) may be of interest to you? -I recommend the [BGB](https://bgb.bircd.org) emulator for developing ROMs on Windows and, via Wine, Linux and macOS (64-bit build available for Catalina). [SameBoy](https://github.com/LIJI32/SameBoy) is more accurate, but has a much worse interface except on macOS. +I recommend the [BGB](https://bgb.bircd.org) emulator for developing ROMs on Windows and, via Wine, Linux and macOS (64-bit build available for Catalina). +[SameBoy](https://github.com/LIJI32/SameBoy) is more accurate, but has a more lackluster interface outside of macOS. ### Libraries - [Variable-width font engine](https://github.com/ISSOtm/gb-vwf) -- [structs in RGBDS](https://github.com/ISSOtm/rgbds-structs) +- [Structs in RGBDS](https://github.com/ISSOtm/rgbds-structs) diff --git a/project.mk b/project.mk index 8107a33..19e2ebc 100644 --- a/project.mk +++ b/project.mk @@ -1,66 +1,67 @@ -# This file contains project configuration +# This file contains project-specific configuration. +# You can override variables set in the Makefile here. -# Value that the ROM will be filled with +# Value that the ROM will be filled with. PADVALUE := 0xFF -## Header constants (passed to RGBFIX) +## Header constants (passed to RGBFIX). -# ROM version (typically starting at 0 and incremented for each published version) +# ROM version (typically starting at 0 and incremented for each published version). VERSION := 0 -# 4-ASCII letter game ID +# 4-ASCII letter game ID. GAMEID := BOIL -# Game title, up to 11 ASCII chars +# Game title, up to 11 ASCII chars. TITLE := BOILERPLATE -# New licensee, 2 ASCII chars -# Homebrew games FTW! +# New licensee, 2 ASCII chars. +# Homebrew games FTW!. LICENSEE := HB -# Old licensee, please set to 0x33 (required to get SGB compatibility) +# Old licensee, please set to 0x33 (required to get SGB compatibility). OLDLIC := 0x33 -# MBC type, tells which hardware is in the cart -# See https://gbdev.io/pandocs/#_0147-cartridge-type or consult any copy of Pan Docs -# If using no MBC, consider enabling `-t` below +# MBC type, tells which hardware is in the cart. +# You can get a list of valid values by running `rgbfix -m help`. +# See https://gbdev.io/pandocs/MBCs for more information, or consult any copy of Pan Docs. +# If using no MBC, consider enabling `-t` below. MBC := 0x00 -# ROM size is set automatically by RGBFIX +# ROM size is set automatically by RGBFIX. -# Size of the on-board SRAM; MBC type should indicate the presence of RAM -# See https://gbdev.io/pandocs/#_0149-ram-size or consult any copy of Pan Docs -# Set this to 0 when using MBC2's built-in SRAM +# Size of the on-board SRAM; MBC type should indicate the presence of RAM. +# See https://gbdev.io/pandocs/The_Cartridge_Header#0149--ram-size or consult any copy of Pan Docs. +# Set this to 0 when using MBC2's built-in SRAM. SRAMSIZE := 0x00 -# ROM name +# ROM name. ROMNAME := boilerplate ROMEXT := gb -# Compilation parameters, uncomment to apply, comment to cancel -# "Sensible defaults" are included +# Compilation parameters, uncomment to apply, comment to cancel. +# "Sensible defaults" are included. +# Please refer to RGBDS' documentation. +# For example, offline: `man 1 rgbasm`; online: https://rgbds.gbdev.io/docs/rgbasm.1 -# Disable automatic `nop` after `halt` -ASFLAGS += -h - -# Export all labels -# This means they must all have unique names, but they will all show up in the .sym and .map files +# Export all labels. +# This means they must all have unique names, but they will all show up in the .sym and .map files. # ASFLAGS += -E -# Game Boy Color compatible +# Game Boy Color compatible. # FIXFLAGS += -c -# Game Boy Color required +# Game Boy Color required. # FIXFLAGS += -C -# Super Game Boy compatible +# Super Game Boy compatible. # FIXFLAGS += -s -# Game Boy mode +# Game Boy mode. # LDFLAGS += -d -# No banked WRAM mode +# No banked WRAM mode. # LDFLAGS += -w -# 32k mode +# 32k mode. # LDFLAGS += -t diff --git a/src/res/build_date.asm b/src/assets/build_date.asm similarity index 100% rename from src/res/build_date.asm rename to src/assets/build_date.asm