GBA Development setup in macOS
To develop in GBA we need the tools to do it, and installing it in macOS is simple even if they take a few steps.
Install pacman
The first thing we must do is install pacmac, which will allow us to download the devkitpro for the GBA, to install it we must go to the following URL:
https://github.com/devkitPro/pacman/releases/tag/v1.0.2
And we will download devkitpro-pacman-installer.pkg. Once it has been downloaded, we install the package. The following will appear:
So, we need to go to System Preferences -> Security & Privacy and allow the permissions:
Follow the steps to install the package.
Once that the installation was finished, we need to update our .bashrc or .zshrc file.
Update our environments vars
With the installation of pacman, we need to tell to our system where the files are located, so we need to update our .bashrc or .zshrc file.
Open your file and copy the next exports
export DEVKITPRO=/opt/devkitpro
export DEVKITARM=${DEVKITPRO}/devkitARM
export DEVKITPPC=${DEVKITPRO}/devkitPPC
export PATH=${DEVKITPRO}/tools/bin:$PATH
Install Xcode Tools
Now we need to install the Xcode tools to use the compiler and other utilities. In your terminal write the follow command:
xcode-select --install
Install devkitpro
Now we have all the tools to install our GBA compiler, so is time to write in the terminal.
sudo dkp-pacman -S gba-dev
Enter your password. You will prompt with options to get more control about the things that your going to install, for now we are going to install all of them. So, hit Enter and then Enter to confirm.
If you have Catalina you will get an error.
error: Partition / is mounted read only
error: not enough free disk space
error: failed to commit transaction (not enough free disk space)
This is because Catalina root partition is only for read, and you cannot install anything here, but you can have a workaround installing with this command:
sudo dkp-pacman -S gba-dev -r /System/Volumes/Data
Again, hit Enter, and Enter.
With devkitpro installed, your are not able to create a GBA game, so we need to test if our tools was installed correctly.
Hello World GBA
In your Desktop or whenever you want, create a folder named hellogba, inside create a new file named Makefile, this file will help us to compile our code and generate a rom
Copy the following
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
include $(DEVKITARM)/gba_rules
#---------------------------------------------------------------------------------
# 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 := rom/$(notdir $(CURDIR))
BUILD := build
SOURCES := src
INCLUDES := include
DATA :=
MUSIC :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -mthumb -mthumb-interwork
CFLAGS := -g -Wall -O2\
-mcpu=arm7tdmi -mtune=arm7tdmi\
$(ARCH)
CFLAGS += $(INCLUDE)
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $*.map)
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS := -lmm -lgba
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBGBA)
#---------------------------------------------------------------------------------
# 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)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir)) \
$(foreach dir,$(GRAPHICS),$(CURDIR)/$(dir))
export DEPSDIR := $(CURDIR)/$(BUILD)
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
ifneq ($(strip $(MUSIC)),)
export AUDIOFILES := $(foreach dir,$(notdir $(wildcard $(MUSIC)/*.*)),$(CURDIR)/$(MUSIC)/$(dir))
BINFILES += soundbank.bin
endif
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SOURCES)
export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))
export INCLUDE := $(foreach dir,$(INCLUDES),-iquote $(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr $(BUILD) $(TARGET).elf $(TARGET).gba
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
# 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)
-include $(DEPSDIR)/*.d
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------
This template include all necessary things to compile and generate a rom, for now, the most important lines are:
TARGET := rom/$(notdir $(CURDIR))
BUILD := build
SOURCES := src
INCLUDES := include
DATA :=
MUSIC :=
That are the directories where you’re going to write your code and generate the output. Create the rom, build, src and include folders.
Inside src directory, create a new file named hello.c and write the next code
int main()
{
*(unsigned int*)0x04000000 = 0x0403;
((unsigned short*)0x06000000)[120+80*240] = 0x001F;
((unsigned short*)0x06000000)[136+80*240] = 0x03E0;
((unsigned short*)0x06000000)[120+96*240] = 0x7C00;
while(1);
return 0;
}
This code show three points in the screen, we are going to use only to test our environment.
Now is time to compile!
In your terminal, write this
make
And if you see this message
linking cartridge
built ... hellogba.gba
ROM fixed!
Your environment is ready to work with. In the rom folder, you are going to see two files, hello.gba and hello.elf, the last one is util for debugging.
Now we need an emulator to test our “game”.
I am using mGBA and you can download it here https://mgba.io/
Load the hello.gba in the emulator and you should see this screen
Now, you are ready to create GBA games!
Resources
Some resources to start GBA development
https://www.youtube.com/channel/UCQvQbVuWMM7OYTVrmGQq0hA
http://www.coranac.com/tonc/text/toc.htm
http://www.loirak.com/gameboy/gbatutor.php
https://github.com/gbdev/awesome-gbadev
https://www.reinterpretcast.com/writing-a-game-boy-advance-game