Loirak Development Logo  

Gameboy Advance Programming for Beginners - Loirak Development

Loirak -> Gameboy -> GBA Development
 

Gameboy Advance Programming for Beginners

Have you ever dreamed of becomming a game programmer? Today is your lucky day, becuase if you go through the following steps. I bet you will be making games before the day is over. By the time you finish reading this page you will have the basics that will enable you to build homebrewn games that will give give professional developers a run for their money. (well maybe not professional developers, but its a start!). This tutorial will cover Nintendo's new Gameboy Advance. If you want older information about coding for the Gameboy Color visit gbprog.php

This tutorial will cover the basics from downloading the compiler (devkitadv), installing it, setting it up, making roms, and programming basic graphics on the gameboy. But there are a few prerequisites. You need to know how to download and extract zip files from the internet. Second, you should be able to think logically (some programming experience is recommended), and finally be familiar with a few DOS concepts like paths, file organization, and directories. If you do not know how to use a Zip program, or the basics of DOS then you will have a difficult time getting through this tutorial, so first learn those things before reading on.

Step 1 - Setting up the Environment

1.1 - Installing the Compiler

As they say in German, "Aller Anfang ist schwer" (the hardest part is getting started). Setting up the compiler, and getting the hardware or emulator is probably the hardest and most fustrutating thing for beginners. In fact a lot of people get so fustrated that they give up. Well, in writing this tutorial my aim is that you can get up and compiling your games in no time. So let's get started.

The best part about programming for the GBA is that the GBA community is sort of one nice family. A lot of people share their work and knowledge to help other newbies out. So when you finally get to the point of making demos or games please share your knowledge with others. If you don't have your own web site to post to, there already exists a couple great forums where you can post your work or discovery about the GBA. Like gbadev.org. One person to make a very significant contribution is Jason Wilkins. He has put together the unoffical GBA software development kit, known simply as devkit advance. Go to this address http://devkitadv.sourceforge.net/, then the download page. Download the following files to your hard drive. The MacOS folks will need to go to gnufoo.org/gba to get the developer kit. The Linux people can get the DevKitAdvance from the same place as the windows users they will just need to download different files.

The files are in the Release 4 distribution.
  • agb-win-binutils-r4.zip (2.3MB)
  • agb-win-core-r5.zip (481kB)
  • agb-win-gcc-r4.zip (2.4MB)
  • agb-win-newlib-r4.zip (3.8MB)
  • ** agb-win-patch-r4.zip (2.0MB) ** download this ONLY if you use Win9x/Me, if you use Win2k/NT/XP you DO NOT need it.
After downloading them to your hard drive, you will need to unzip them in C:\> or the root directory of your hard drive. This will create a directory called C:\devkitadv>. You will need to use WinZip, 7-Zip, or WinRar to accomplish this.

If you are using Windows 9x/Me here is what Jason Wilkins has to say about the devkitadv, and the last patch file for Win9x users.
  • This release works out of the box with WinNT, Win2k, and WinXP, but you will have to download an additional file to get it to work with Win9x and WinMe. This is because of the "Virtual Memory Exhausted" error. The "fix" causes some projects, those that use C files to include binary data, to use way too much memory to compile.
  • People using Win9x and WinMe are stuck with this problem, but I am not going to punish everyone, so Win9x/Me users will have to download agb-win-patch-r4.zip which contains replacements for the files that have the problem.
After unzipping the files, the next step is to add C:\devkitadv\bin to your PATH. This can be accomplished in a number of ways. I will explain how to do this in Windows 2000/XP, then we will all do it the DOS way (which also works for Windows 2000/XP).

In Windows 2000/XP right click my computer, goto properties. Click the advanced tab, and then click on environment variables. In the system variables scroll down to path, and then click edit. Make sure it ends with a semi-colon ";", then add C:\devkitadv\bin

Now the DOS way (Windows 2000/XP users continue to follow along), So open up notepad, and type in only TWO of the following lines choosing the command or cmd statement based on your operating system. The **** portions are comments do NOT type them into your file.

set PATH=c:\devkitadv\bin;%PATH%
cmd          **** win 2000/NT/XP users
command      **** win 9x/Me users
Now, in notepad click Save As, change the save as type to All Files. I am going to say that last part twice because otherwise it will not work, so when in the Save As menu change the save as type to All Files. Finally type in the filename filename "C:\devkitadv\start.bat" and click save.

Now browse to this C:\devkitadv folder using windows explorer, and double click on the startup.bat file, a command prompt (DOS prompt) window will show up. Now type "exit" and press enter to close the command prompt window. You can compile your programs from here, and use the other gcc tools since the path is setup for this window.

Note that if you are bone headed and decided to install the devkitadv to a different directory you will need to define GCC_EXEC_PREFIX environment variable using the following line set GCC_EXEC_PREFIX=c:/devkitadv/lib/gcc-lib/ where Where c:/devkitadv/ is the installation directory. Use forward slashes. The trailing slash is required. PLEASE NOTE most users do not have to do this. Only do this if you have problems compiling your first rom, which is what we are going to do right now!

1.2 - Making our first ROM

That should be it for setting up the devkitadv, so let us make our first program or Rom, but before we make that program. We need something to view it. I assume that since you want to program for the gameboy advance, that you own a gameboy advance. If so you might want to invest in a flash writer and cart from Success-HK.com or Linker4u.com. They allow you to put your own games on a rewritable cartrige, and then play it on a real gameboy advance. The other option is an emulator. This is not really an option, since anyone who programs knows that it takes too long to load your rom onto the writer every time you want to test it. So the best thing to do is to get an emulator. This way you can test your program on your windows machine, right after you make it. The best emulator out there is VisualBoyAdvance at http://vba.ngemu.com/. Go to the download page and get it!

Now onto making the first rom, first of all we need to make a directory for storing your files that you make or your source code. I store my code in a directory called "C:\prog". You can store yours anywhere you want, but if you would like to follow the path of least resistance, and follow my example click My Computer or open windows explorer click on your C drive. On the right hand side you should see folder icons for program files windows or winnt, etc. Click file, new folder and type in the name "prog". Now go into this folder. Make a directory inside this one called "hello" by following the same routine. Go inside of the hello folder. Now serparately open up notepad and type in the following. Or just copy and paste:

/* hello.c - Gameboy Advance Tutorial - Loirak Development */
#define RGB16(r,g,b)  ((r)+(g<<5)+(b<<10)) 

int main()
{
	char x,y;  
	unsigned short* Screen = (unsigned short*)0x6000000; 
	*(unsigned long*)0x4000000 = 0x403; // mode3, bg2 on 

	// clear screen, and draw a blue back ground
	for(x = 0; x<240;x++)   //loop through all x
	{
		for(y = 0; y<160; y++)  //loop through all y
		{
			Screen[x+y*240] = RGB16(0,0,31);  
		}
	}

	// draw a white HI on the background
	for(x = 20; x<=60; x+=15)
		for(y = 30; y<50; y++)  
			Screen[x+y*240] = RGB16(31,31,31);  
	for (x = 20; x < 35; x++)
		Screen[x+40*240] = RGB16(31,31,31);  

	while(1){}	//loop forever
}

Now in notepad, click save as, then make sure to go into the prog\hello directory, change the save as type from text documents to All files, and type in the file name "hello.c" Now in notepad, click file then new (to make a new file), paste or type the following.

set path=C:\devkitadv\bin;%path%
gcc -o hello.elf hello.c -lm
objcopy -O binary hello.elf hello.gba
pause
In notepad, click save as, then make sure you are in the prog\hello directory, change the save as type from text documents to All files, and type in the file name "make.bat" Close notepad, then using windows explorer, or my computer to navigate to that directory, and double click "make.bat" Assuming no errors were reported. Your folder should now have two new files. An elf file, and "hello.gba". Now open your recently downloaded copy of VisualBoyAdvance, and open hello.gba, you should get a blue screen, with HI written on it. See pictures below. Your first Game, ROM, whatever you want to call it. You should be proud of yourself. You have successfully downloaded the compiler, an emulator, set everything up, and made your first program!
Compiling program HI Program Running
Picture of program being compiled. Click to enlarge Hi program running in VisualBoyAdvance

Step 2 - Basic Graphics on the GBA System

If you don't know C Programming the following explanations about the hello program, and the GBA system maybe a bit hard to follow. We have here a short tutorial on C programming basics at www.loirak.com/prog/ctutor.php, which will help you to understand some of the information about the gameboy advance that is to follow. If you already program in C, more power to you, and just continue reading this document.

This might be information you already know, but let's talk about the GBA. The Gameboy Advance has a 32bit ARM7TDMI processor running at a blazing 16.78Mhz. The GBA is roughly equivalent to the SNES, and perhaps a bit better. The GBA has six different graphics modes, and a max resolution of 240 pixels wide, by 160 pixels tall. It has 96k of video memory (which sounds pretty pathetic compared to my GeForce 4 with 128Mb). But my GeForce 4 is bigger than the Gameboy, and has to have its own fan. The GBA also has 256K external ram. Commerical catrige sizes (games you buy) are generally 32Mbit (4MB) or 64 Mbit (8MB).

Now lets talk more about the graphics modes. The first three modes 0,1,2 are tile modes. Basically the graphics are organized into 8x8 pixels sections, and maps are passed to the GBA to be drawn. Tile modes are a little more complex than the other three modes. So this tutorial isn't going to cover them. If you want to learn more about tile modes visit The Pern Project. The next three modes are bitmap modes. The below table describes the three modes.

Mode 3 This is the simplest graphic mode for the GBA. The screen is a 16 bit linear buffer. Meaning every pixel has two bytes of information. Those two bytes are made up of red, green, and blue component. Each of those basic three colors can have a value from 0..31 resulting in a maximum of 32,768 colors. Mode 3 has a resolution of 240x160.
Mode 4 This mode is a little different than mode 3, it still has a resolution of 240x160. But each pixel uses only one byte. Each byte contains a number from 0..255 that refers to an entry in a 256 color palette. Since each pixel only uses one byte, the screen only uses half of video memory. This means we can have two screens in video ram at the same time. Meaning we can be drawing to one screen, and performing calculations while the other screen is being displayed. This leads to more smooth animation and visual effects than mode 3 can accomplish.
Mode 5 This is the last bitmap mode. Like mode three it is a 16 bit linear buffer, so it can use 32,768 different colors. This mode however has a resolution of 160x128. So a full GBA screen only takes up half of video memory, and like mode 4 it can be double buffered. This mode is not really that usefull, so that is all we will say about mode 5.

Now that we know how the bitmap modes are made up. Lets discuss the Hello program we wrote when we were setting up the compiler. After declareing variables x and y, we make a variable called Screen which is a unsigned short (also known as u16). Screen is a pointer to memory location 0x6000000. This location in memory is that start of VRAM. The line after this we assign the hex value 0x403 to memory location 0x4000000. Location 0x4000000 in memory is a graphics register, perhaps the most important one. Registers our special memory locations on the GBA. When you put different values into these registers, different things will happen. The register talked about here controls the graphic modes of the Gameboy. It is usually referenced using a #define and named REG_DISPCNT. Here is a description of this 16 bit register taken from the Cowbit Hardware Spec:

Address: 0x4000000 - REG_DISPCNT (The display control register)

                           R
F E D C  B A 9 8  7 6 5 4  3 2 1 0 
W V U S  L K J I  F D B A  C M M M
0-2 (M) = The video mode. See video modes list above. 
3   (C) = Game Boy Color mode. Read only - should stay at 0. 
4   (A) = This bit controls the starting address of the bitmap in bitmapped modes
          and is used for page flipping. See the description of the specific
          video mode for details. 
5   (B) = Force processing during hblank. Setting this causes the display
          controller to process data earlier and longer, beginning from the end of
          the previous scanline up to the end of the current one. This added
          processing time can help prevent flickering when there are too many
          sprites on a scanline.
6   (D) = Sets whether sprites stored in VRAM use 1 dimension or 2.
          1 - 1d: tiles are are stored sequentially 
          0 - 2d: each row of tiles is stored 32 x 64 bytes in from the start of the
          previous row.
7   (F) = Force the display to go blank when set. This can be used to save power 
          when the display isn't needed, or to blank the screen when it is being
          built up (such as in mode 3, which has only one framebuffer). On the SNES,
          transfers rates to VRAM were improved during a forced blank; it is logical
          to assume that this would also hold true on the GBA.

8   (I) = If set, enable display of BG0. 
9   (J) = If set, enable display of BG1. 
A   (K) = If set, enable display of BG2. 
B   (L) = If set, enable display of BG3. 
C   (S) = If set, enable display of OAM (sprites). 
D   (U) = Enable Window 0
E   (V) = Enable Window 1 
F   (W) = Enable Sprite Windows 

There are few things things important here to notice. Bits 0-2 control the mode. Also note that in bitmap mode we have to enable BG2. All the other stuff relates to tile modes or sprites which is beyond the scope of this tutorial. So now you can figure out why we set this register to the hex value 0x403. If you convert this to binary and match up each bit. You will see that 0x403 would turn bit 10(A), and bits 2 & 1 on. So our sample program enables background 2, and sets the mode to 3.

This sets GBA to its third graphics mode. As talked about earlier mode three has a screen width of 240x160, and each pixel has 16bits of information. These sixteen bits are used to assign a color. In the Hello program, at the top you notice the following define #define RGB16(r,g,b) ((r)+(g<<5)+(b<<10)) (also known as a macro). As you notice it takes the blue that comes in, shifts it up 10 bits, takes the green and shifts it up 5 bits, and finally adds in the red value. So every pixel has five bits of each primary color. The values that you can use range from 0..31 (since 2^5=32). So for example if you wanted to change the pixel at location at X=10, Y=15. The code would look like this.

Screen[ 10 + 15*240] = RGB16(0,31,0);

Memory for graphics is organized linearly, the first 240 pixels starting from memory address 0x6000000 represent the first line on the screen where y is 0, and x ranges between 0 and 239. To get to the next line on the screen, and draw on it. We simply adding the screen width multiplied by the Y that we want to get to. So in the code above we want line fifteen so we had 10 to 15 times 240. Very simple, eh. Now if you look at the Hello program you should be able to understand everything. First we clear the background to blue. Then we draw a couple lines to write HI to the screen.

Now that you know how to work around in mode3, I recommend change some things in the hello program, and trying to do some other stuff on your own. The best way to learn to program for the GBA is not to read about it, but to DO it.

Back so soon, ok, now we'll take a quick look at mode4. Mode 4 as mentioned above has the same resolution as mode3, but it can display a max of 256 colors at once, and uses a palette. Since it can only have 256 colors. We only need 8 bits per pixel, therefore when we draw stuff to the GBA it is twice as fast as Mode3. In fact DOOM GBA is written in this graphics mode.

So to draw something in mode 4 we simply write which number 0..255 that the pixel represents into the screen buffer. But also note mode 4 has two screen buffers. Since it takes up half the space as Mode3. So one can be displayed, and you can be changing the other, allowing animation to look a lot smoother than it could in mode3.

Our next program is again quite simple, it has a couple new things, first it takes a whole image made from a conversion tool, and displays it to the screen. It has keyboard input to move a block around on the screen. The data that is displayed to the screen is stored in a header file. This header file is generated by a program called pcx2gba.exe made by Dovoto, and taken from his Pern Project. It takes a PCX file that has 256 colors, and generates a C array for the image, and palette. Then the code below takes the information like the palette, and actual image, and draws it to the screen. After it is drawn to the screen. It reads the keyboard input, draws a flashing green block on top of the image. Here is the main code for this small program (you can download it here - display.zip (66k)) This file includes display.c, keypad.h, ppic.pcx, ppic.h, display.gba, and make.bat.

Before I show the main code, here is a screen shot of the program running to get you salivating.
HI Program Running

// display.c : sample program to display pcx, and get key input
typedef unsigned short u16; // two type definitions
typedef unsigned long u32;

#include "keypad.h"		//keypad definitions 
#include "ppic.h"

#define REG_DISPCNT    *(u32*)0x4000000
#define MODE_4 0x4
#define BG2_ENABLE 0x400
u16* paletteMem = (u16*)0x5000000;	// Pal is 256 16 bit BGR 
u16* videoBuffer = (u16*)0x6000000; // video memory

void PlotPixel(int x,int y, unsigned short int c) 
{
	videoBuffer[(y) *120 + (x)] = (c);
}

int main(void)
{
	int x, y, blockX, blockY, loop; // variables

	REG_DISPCNT = MODE_4 | BG2_ENABLE; // switch to mode4
	for(loop = 0; loop < 256; loop++)	// put pal in memory
		paletteMem[loop] = picPalette[loop];	

	blockX = 50;	// give our block a start position
	blockY = 50;

	while (1) // run forever
	{
		// process input
		if(!((*KEYS) & KEY_UP)) // they pushed up
			blockY--; // subtract from y (move up)
		if(!((*KEYS) & KEY_DOWN))
			blockY++; 
		if(!((*KEYS) & KEY_LEFT))
			blockX--;  
		if(!((*KEYS) & KEY_RIGHT))
			blockX++; 
		// draw the picture
		for(y = 0; y < 160; y++)
		{
			for(x = 0; x < 120; x++)
			{
				PlotPixel(x,y,picData[y*120+x]);
			}
		}
		PlotPixel(blockX, blockY, (75<<8)+75);
		PlotPixel(blockX+1, blockY, (75<<8)+75);
		PlotPixel(blockX, blockY+1, (75<<8)+75);
		PlotPixel(blockX+1, blockY+1, (75<<8)+75);
	}
	return 0;
}
Explanation. Well it is easiest to start at the top. First we define some simple types that are common when programming with the GBA. u32 means unsigned (only can store positive numbers) 32 bit variable, and u16 would be a unsigned 16bit variable. These are used by the header file which is generated by pcx2gba. To insert a different picture (like one you made). All you need to do is make a picture in your favorite graphics program and then overwrite ppic.pcx (from the display.zip file) Then run from dos in the same directory as all the code, and graphics.
pcx2gba ppic.pcx
Then it will generate a header file. Which as you notice from display.c is included on the sixth line of the program. You will also notice we include another file called keypad.h. This is also in the display.zip file. Here is the file:
//Key Definitions from Nokturn's key demo
#define KEY_A 1
#define KEY_B 2
#define KEY_SELECT 4
#define KEY_START 8
#define KEY_RIGHT 16
#define KEY_LEFT 32
#define KEY_UP 64
#define KEY_DOWN 128
#define KEY_R 256
#define KEY_L 512
int* KEYS = (int*)0x04000130;
As you can see it has some defines for which bits correspond to each button pressed. It also defines the KEYS register which is located 0x4000130. Basically to see if a certain key is pressed, you examine the contents of this register, and see if the corresponding bit is on or off. As in the display.c if we wanted to see whether the button up was being pressed we would use the following line.
if(!((*KEYS) & KEY_UP)) // up was pressed
After the inclusion of keypad.h we have a few more things defined. We define the REG_DISPCNT, MODE_4, BG2_ENABLE which was explained earlier. Next we define the location of both video memory, and palette memory. Video memory for Mode4 starts at the same place as with Mode3. But with Mode4 we need some space for the palette. The palette is a 256 16bit RGB entries. Using the RGB or BGR format we talked about above. If you wanted to change an entry in the palette then you could use the RGB16 macro that was in the Hello program. In the above program we simply copy each entry into the gba palette from the one the PCX file made.

Lastly we have the PlotPixel function. This takes a X, Y, and a color number which is the palette number that you want the pixel to be. You may notice that we multiply Y by 120 instead of buy 240 as in Mode3. This is because in Mode4 each pixel is represented by only 8 bits (one byte). But video memory is always written in 16 bit chunks. So 16 bits will hold two pixels. So each line would be 240/2 or 120. This is also why as you notice in the program that when I wrote the moving block to the screen. The color I give is 75 shifted up 8 bits, plus 75. This tells PlotPixel to write to pixels two the screen of palette entry 75 to the screen.

That should enough for you to understand the sample program. It is really simple, but think about what you now know. You can use two modes on the GBA, get keyboard input, and also draw graphics that you yourself made to the screen. That is a lot. In fact, that is enough to make a simple game. Don't believe me? well, goto tank.php download the program and see for yourself.

That about wraps it up for this tutorial, it was only meant to cover the basics and get you started. I recommend going through the tutorial twice to get the information down, and then writing some of your own sample programs. Take a look at Tank every thing in this program you should be able to understand, or wade your way through.

Good luck in your programming efforts. Here are some more web links for when you want to get more advanced.

Other Resources

Now that you've made a very simple game, I would say your a fairly accomplished GBA hobbyist. The next part is too get aquainted with interrupts, tile modes, and sound. But that is beyond the scope of this tutorial. So good luck, and here are some sites to help you out on your development journey.
  • Tank Advance - This is the short game discussed in the tutorial above. Basically you drive a tank, and dodge falling bombs. A simple game with complete source code (only 400 lines) for the GBA.
  • Skiing Advance - another GBA game with source code. You ski down the mountain, and dodge trees. This was an entry for the Feb. 2002 GBADev competition.
  • The Pern Project - this project is a set of tutorials on the gameboy advance. After reading the above tutorial. This is where you should go next. You will learn about hardware sprites, timers, tile modes, interupts, and more. Plus all the lessons have sample code you can learn from.
  • GBADev.org - This is the news site for the community, if you want to know what's going on, this is where to go. You should probably check in here weekly to get the latest demos, gameboy advance tools, and news. They also have occasional development competitions for cool prizes.
  • Devrs GBA - this is Jeff Frohwein's news page. It is another great community site. Another great place to get the latest development news and tools.
  • GBAEmu.com - another news page for the community. This site is generally updated with the latest news daily, and they were also host to the 4k competition. You should check it out.
  • VisualBoyAdvance - in my opinion the best emulator for Gameboy Advance. It has a Linux, and SDL version. Tons of features like map viewers, tile set viewers, and plus the newer versions support GDB, which means source level debugging.
  • Code Waves - this is the page of Sergej Kravcenko. He is famous for his version of Tetris, and also his freeware (non commercial) mod player. It is the engine for the sound in a lot of the demos there. Visit the page to get the Music Player SDK, and Tetris.
  • DevKit Advance - this has become the de facto standard compiler of the GBA scene. Put together by Jason Wilkins. As you should already know, this is the compiler we used in the above tutorial.
  • Success-HK - a Hong Kong based company, from which you can order cool accessories for your GBA. The most important of which is a Flash Linker and cartige. So you can test your demos on hardware. You can also get cool stuff like GBA cameras, radios, TV tuners, and more.
  • CowBit Hardware Specification - this file is an HTML document about the hardware inside the GBA, including all the registersm, sprites, tile modes, and basically all the hardware features of the GBA. It is not a tutorial, but is an excellent reference to look things up at.
  • Audio Advance - the most complete site with documentation on the GBA's sound hardware. Sound makes a big difference in your demos. This site has a bunch of samples, and is packed full of technical information about sound for the GBA.
  • C Programming Tutorial - a short step-by-step programming tutorial for C. This will teach you the basics of the C Language, so you can make GBA games. Covers data types, operators, pointers, arrays, and more.
  • Cimarron's ARM / GBA notes - a site of someone who went all the way through this tutorial, and it has screen shots of the results! The link above is to his first day, here is a link to the second day.

[C/C++] [Gameboy] [Java] [DirectX] [Games] [Contact] [Loirak HQ]
Viewing: Loirak -> Gameboy -> GBA Development
© Copyright 1998-2024 Loirak. All rights reserved.
4 December 2024