Homebrew Engineer's Notebook: Game Boy Advance Development

This is my online notebook for Game Boy Advance development. It represents my experiences and collected knowledge. I'm not a professional game developer. I'm not licensed by Nintendo. Make use of this information at your own risk.

Development Tools

This section covers the tools I'm using for Game Boy Advance development.

Host Environment

I'm using Ubuntu Linux 8.04 for my host environment. It's free software, and I find it very useful and convenient for software development. Microsoft Windows is another common host environment for Game Boy Advance development. Because I do not use it for development, I won't comment on it any further.

Toolchain

A toolchain is a set of the software tools that translate source code and binary resource files (graphics, sounds, etc) into a form that can be used by the Game Boy Advance. This usable form is commonly called a ROM, and often ends with the extension ".gba". devkitPro is the most advanced toolchain available for Game Boy Advance development. devkitPro for Linux is available for download from SourceForge, a popular site for open source and free software. The following table will help you obtain the toolchain packages you will need for Game Boy Advance development:
Type Name Link
Toolchain devkitARM devkitARM_r23b-i686-linux.tar.bz2
Library (Source) libgba libgba-src-20060720.tar.bz2
Library (Source) libnds libnds-src-20071023.tar.bz2
Examples gba gba-examples-20060718.tar.bz2
Examples nds nds-examples-20080427.tar.bz2
NOTE: I've included the Nintendo DS (nds) libraries and examples, because that is today's most common hardware for playing Game Boy Advance games; Slot 2 on the Nintendo DS. Also, after I master Game Boy Advance development, I plan to leverage this into Nintendo DS development. As I understand it, the hardware and concepts involved are quite similar.
NOTE: I've indicated the source packages of the libraries libgba and libnds. Compiling them is an important step that confirms the toolchain has been installed properly. If you can't compile the libraries from source, you probably won't be able to compile a program for the Game Boy Advance either. Better to work out the problems now, as it will save you lots of trouble later.

Toolchain Installation

Once you've downloaded the packages, it's time to install them. Although it's possible to make the toolchain available to every user on the system, I am the only user on my system. So, to save myself the hassle, I just install them in my home directory.
TODO: Add instructions for installing the toolchain for the system instead of just one user.
In order to use the script I've provided below, you'll need to save the packages to your home directory (~).
#!/bin/bash
# install-devkitPro.sh
cd ~
mkdir devkitPro
cd devkitPro
tar xjf ~/devkitARM_r23b-i686-linux.tar.bz2
mkdir examples
cd examples
mkdir gba
cd gba
tar xjf ~/gba-examples-20060718.tar.bz2
cd ..
mkdir nds
cd nds
tar xjf ~/nds-examples-20080427.tar.bz2
cd ..
cd ..
mkdir libgba
cd libgba
tar xjf ~/libgba-src-20060720.tar.bz2
cd ..
mkdir libnds
cd libnds
tar xjf ~/libnds-src-20071023.tar.bz2
cd ~
echo "DONE: devkitPro installed! Be sure to modify ~/.bashrc and ~/.gnomerc"
It's not the most elegant or concise script, but it is hopefully easy to follow.
CAVEAT: Some people have warned against using graphical tools to unpack the packages, as they don't preserve the structure properly. If you don't use the script above, you may want to consider still using the command line for this task.
When the script is finished, you should have a structure similar to the one in the devkitPro wiki:
devkitPro
   |
   +-- devkitARM
   +-- examples
         |
         +-- gba
         +-- nds
   +-- libgba
   +-- libnds
There is one final step. Depending on your environment, programs need to know where devkitPro is located. Add the following lines to the files ~/.bashrc and ~/.gnomerc
# define variables for devkitPro
export DEVKITPRO=$HOME/devkitPro
export DEVKITARM=$DEVKITPRO/devkitARM
You may need to create the file ~/.gnomerc. On my Ubuntu system, it didn't exist by default.

Library Compilation

Here is the litmus test. Assuming the toolchain has been installed properly, you should now be able to compile the libraries libgba and libnds from the source packages. Change into the ~/devkitPro/libgba directory and issue the following command:
make && make install
It should run through a compilation sequence and end with a list of files installed to the ~/devkitPro/libgba directory. If it did, congratulations; you have a working Game Boy Advance development toolchain at your disposal! At your option, you may also compile the libnds library.

Example Compilation

With the libraries fully compiled, you should be able to compile the Game Boy Advance examples as well. Change into the ~/devkitPro/examples/gba directory and issue the following command:
make
It should recursively compile all of the examples.
CAVEAT: Some of the examples do not compile properly for me. /gba/audio/ApexAudio and /gba/audio/Krawall do not compile properly. I don't know why yet.

Emulator

In order to test your programs for the Game Boy Advance, it is necessary to run them. The host environment has no direct support for running Game Boy Advance programs, so most developers use an emulator. An emulator is itself a program, designed to mimic the hardware and software of the Game Boy Advance. Your host environment runs the emulator, and the emulator runs your program in ROM format, allowing you to test it.

Visual Boy Advance

Visual Boy Advance is the most comprehensive and stable emulator for the Game Boy Advance as of this writing. On Ubuntu Linux, it is easy to install Visual Boy Advance with the following command:
sudo apt-get install visualboyadvance-gtk
The emulator can then be run from the command line with the following command:
gvba [optional-rom]
If the path to a ROM file is provided on the command-line, Visual Boy Advance will automatically load and execute the ROM when it starts. Otherwise, you can use the GUI menus to find and open the ROM file you want to run.
CAVEAT: Very few emulators are 100% perfect, and Visual Boy Advance is no exception. If you plan to run your program on a Game Boy Advance, you will need to test on a Game Boy Advance. The emulator is quick and convenient for development, but it is not a substitute for testing on the actual hardware.

Integrated Development Environment (IDE)

An Integrated Development Environment (IDE) is a program software developers use to create software. Technically, any text editor can be used to create source code files. However, an IDE usually provides tools that highlight mistakes, allow you to browse the source code, and even automate some simple repetitive programming tasks.

Eclipse 3.2

TODO: See if I can get the toolchain working in Eclipse. Others have written about this.

NetBeans 6.0.1

I was able to get the devkitARM toolchain working from NetBeans 6.0.1. On Ubuntu Linux, it is easy to install NetBeans with the following command:
sudo apt-get install netbeans
After this you need to install C/C++ development support. The commands are: Tools | PlugIns (menu), Available Plugins (tab), C/C++ (checkbox). The rest is just clicking Next until it decides to install.
NetBeans Project
Setting up a NetBeans project that makes use of the devkitARM toolchain is not difficult. The commands are: File | New Project (menu), Categories: C/C++ (list), Projects: C/C++ Project From Existing Code, Browse... (button), Find the Makefile for your project. The rest is just clicking Next until it creates the project.
TIP: The examples installed to $DEVKITPRO/examples/gba/ can be made into NetBeans projects this way.
TIP: John Philpott wrote to inform me about getting NetBeans to find devkitPro when launched from GNOME instead of the command line. The modifications to ~/.gnomerc enable this, so if you want NetBeans to know where to find devkitPro, it is important to create this file.
TODO: Figure out how to get NetBeans to launch the emulator with the ROM built by the project.

Documentation

The second most important thing for development is documentation. Tutorials teach you what you need to know. Reference documents allow you to leverage that knowledge into working programs. Here is a list of sites I've found with very useful documentation:

Community

The most important thing for development is community. Here is a list of sites where you can discuss Game Boy Advance development:
TIP: Use the right forum. devkitpro.org supports the devkitPro toolchain. gbadev.org is a community of people who develop for the Game Boy Advance and Nintendo DS.
CAVEAT: The toolchain is provided to you for free by the generosity of the community. Participation in the gbadev.org community is voluntary. Strolling in with an arrogant attitude and/or ordering people to fix things for you is a faux pas and unlikely to work out as you hope. Likewise, discussion of methods for making illegal copies of commercial games or how to locate an illegal copy of the Official Nintendo SDK, is likely to get you banned. These forums are an invaluable resource to beginners and experts alike. Don't abuse it, ever.

Project Setup

This section covers how to set up a new Game Boy Advance development project. This could be used for working through a tutorial or creating your masterpiece.

Template Project

devkitPro includes an example named template. It's a rather clever pre-built project structure that works out of the box. You need only create your files in the right directory and make will take care of it from there. An overview of this build system is given in the devkitPro wiki.

Creating a New Project

If you compiled the examples as I suggested above, there are probably some build files hanging around in your template example. Change to the template example directory and issue the following command:
make clean
This will get rid of those pesky files and allow you to create a new project. Creating a new project is as easy as copying the template example to the directory where you want to work. For example, to create a project called hello, give the following command:
cp -R $DEVKITPRO/examples/gba/template $HOME/hello
This will create a hello project in your home (~) directory. If you change to that directory, you can create a ROM from your project by giving the following command:
make
NOTE: The template project is configured to use the name of the directory where the Makefile is located as the name of the ROM file. So hello_mb.gba. The _mb stands for multiboot; a ROM configured to allow more than one Game Boy Advance to play a game from a single game pak.

C/C++ Primer

This section covers some important details about C/C++ when programming for an environment that interacts directly with hardware. This section will not teach beginner level C/C++ programming, as it is outside the scope of this document. Readers who need this information should use their favorite search engine to look for C/C++ material at their level of skill.

Binary Operations

TODO: Game Boy Advance development makes heavy use of binary operations. Including a refresher on notation, shifting, and masking might not hurt.

Variable Width

libgba includes a header file that provides sized typedefs. The following table describes those typedefs:
typedef C/C++ Type
s8 signed char
u8 unsigned char
s16 signed short
u16 unsigned short
s32 signed int
u32 unsigned int
It is important not to overuse these types. Using a u8 where a standard int can suffice can be expensive. This is because the processor in the Game Boy Advance has 32-bit registers, and the compiler must inject binary masking operations. These invisible operations injected by the compiler can make the routine larger and make it run more slowly than if it was written without direct specification of the size. Generally, interaction with hardware should use the sized types, and everything else should use the processor's natural width (int) if at all possible.

volatile Keyword

The keyword volatile instructs the compiler that the value specified in the variable can change at any time, specifically by actions outside the program itself. This is important, because the hardware may be changing the value, but if the compiler doesn't know this, it may treat the variable as a simple memory location. This could cause the compiler to become overzealous, and "optimize away" a read or write operation that it thinks is unnecessary, but really needs to be there for correctness sake. Your routines that interact with your own data will not need to worry about this, but any code that interacts with the hardware registers need to take it into consideration. libgba already takes this into consideration, so use of the hardware registers through the constants defined in libgba is a safe bet. If your program sets up custom pointers to those hardware registers, be sure to declare those pointers volatile to avoid trouble.

Inefficiency Boogeyman

There are some people who will say C++ is less efficient, in terms of speed or code size, than C. These religious arguments have been the subject of countless threads on forums and newsgroups. Don't worry about it. The template project provided with libgba contains the following line in its Makefile:
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
These directives disable the "expensive" features of C++: Run-Time Type Identification (RTTI) and Exceptions. Assuming you don't go overboard on classes containing the virtual keyword or on templates in general, this should place your C++ code on par with even the best C, in terms of both speed and size. You also gain the benefits of the compiler doing the heavy lifting on object-oriented matters. Don't let an inefficiency boogeyman scare you away from the organization and code structure benefits of C++.

Graphics I: Modes and Backgrounds

This section covers the basics of the graphics system in the Game Boy Advance; modes and backgrounds.

Graphics Overview

There are a total of six graphic modes on the Game Boy Advance, numbered 0 through 5. These modes can be further sub-divided into two groups: the tiled modes (Modes 0, 1, and 2) and the bitmap modes (Modes 3, 4, and 5). The current graphics mode determines the availability and capabilities of the four background layers, numbered 0 through 3. Background capability falls into one of three categories: Tiled, Affine, or Bitmap.
BG 0 BG 1 BG 2 BG 3
Mode 0 Tiled Tiled Tiled Tiled
Mode 1 Tiled Tiled Affine X
Mode 2 X X Affine Affine
Mode 3 X X Bitmap X
Mode 4 X X Bitmap X
Mode 5 X X Bitmap X

Tiled Background

Tiled backgrounds display tile blocks, and have great flexibility in how individual tiles are displayed. However, tiled backgrounds lack the scaling and rotation capabilities of the affine backgrounds.

Affine Background

Affine backgrounds display tile blocks, but do not enjoy as much flexibility with individual tiles as tiled backgrounds do. Affine backgrounds make up this lost tile flexibility in additional layer capability; the whole layer can be scaled and rotated to an arbitrary degree.

Bitmap Background

Bitmap backgrouds do not display tile blocks, but instead have data for each individual pixel. Only Background 2 is available in bitmap graphic modes. The resolution and color depth available on background 2 depends on the selected graphic mode.

Display Control Register (REG_DISPCNT)

The primary hardware register responsible for control of the graphic display is REG_DISPCNT, which is defined in libgba as follows:
#define REG_DISPCNT *((volatile u16*)(0x04000000))
The register itself is accessed via address 0x04000000, is 16-bits wide, and is marked volatile so the compiler knows to treat it as a hardware register and not as a simple memory location. At the moment we are concerned with 7 bits out of the 16 found in the register:
REG_DISPCNT
F E D C B A 9 8 7 6 5 4 3 2 1 0
X BG 3 BG 2 BG 1 BG 0 X Graphics Mode
Bits 0-2 determine which graphics mode is selected. Values 0-5 have the meanings defined above. Values 6 and 7 are undefined; they could do anything, but are not gauranteed to do something useful or interesting.
Bits 8-B are flags that determine if a specific background layer is enabled (shown), or not. Not all background layers are available in all graphics modes; check the table above for availability.

Work in Progress

Last Updated: 22 June 2008
TODO: This online notebook is a work in progress. It covers all of the things I've learned thus far, but I expect to learn more. Check back for updates.