Sei sulla pagina 1di 74

Programming The Nintendo Game Boy Advance: The Unofficial Guide

Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com


! "
" #
" " "

$ % & '

$ ( & '

$ )* + ,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
Programming The Nintendo Game Boy Advance: The Unofficial Guide
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
! " # $ % &
'

) *

+
, - !
, - "
, - #
.

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
Introduction to Bitmapped Graphics
/ -

-
0 1 2. +3 , 0
1 4 . .5 .6 7
8

5 +

, 9 4
) : ;
<' 4 = , + +
<' 4
- > :
-
6 = : ?, : ,
-

3 @ . 6 !*

//
// bg (38400 uncompressed bytes)
//
extern const unsigned char bg_Bitmap[38400] = {
0x4f, 0x3b, 0x23, 0x23, 0x2c, 0x1f, 0x22, 0x2d, 0x2f, 0x2f, 0x2f, 0x2f,

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0x31, 0x2f, 0x2d, 0x2f, 0x23, 0x1d, 0x2d, 0x4c, 0x37, 0x38, 0x2f, 0x2d,
0x22, 0x1f, 0x2f, 0x2d, 0x2d, 0x1d, 0x22, 0x2d, 0x23, 0x23, 0x33, 0x2f,
0x2f, 0x2d, 0x34, 0x2f, 0x2f, 0x2d, 0x2c, 0x23, 0x23, 0x2d, 0x2d, 0x2d,
0x22, 0x1f, 0x2f, 0x2b, 0x23, 0x2d, 0x2e, 0x2d, 0x1d, 0x23, 0x38, 0x2b,
.
.
.
0xe1, 0xe4, 0xc7, 0xbf, 0xc3, 0xf2, 0xf2, 0xf6, 0xf6, 0xf7, 0xf8, 0xf9,
0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf8, 0xf8, 0xf8, 0xf8, 0xf2, 0xf8,
0xf8, 0xf8, 0xf2, 0xf6, 0xf6, 0xf2, 0xf2, 0xf2, 0xf2, 0xf6, 0xf2, 0xd9,
0xe1, 0xd6, 0xd9, 0xd9, 0xd9, 0xd9, 0xc9, 0xf6, 0xf6, 0xf2, 0xf6, 0xf8,
0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9
};

+ 0
3 #%
& ,
+ : 6

!
"

!A "$$ <
( %B
+
- C &"$ %B$ D !A "$$
- ! '
+ 0
- 3 3 #&
#&" %"&
) B" B" :

Programming The Nintendo Game Boy Advance: The Unofficial Guide "#
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
- = +: 6 E F<
/ @ F

#
$

Selecting the Ideal Video Mode


,
#%

% - & '
' * $ . .
! &"$ %B$ %# 5
" &"$ %B$ A 8
# %B$ %&A %# 8

Hardware Double Buffer


4 " # 0
- 4 !
(
> ) : :
1, < 4

1, < 4 + +, < 4 !& G


E# G !
@ 1, < 4 &#B G 1 -
!& G +, < 4 &$ G

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
: ! +:
!

Horizontal and Vertical Retrace


C ,
96 H C
-
-
, 6< .6

@
I :
:
:

Working with Mode 3


I ! 0
&"$ %B$ %#
!& EBE , : -
- + "
&#B # %#
! :
- 1, < 4
) :(

3 !H +
#
0

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
Drawing Basics
9 : ! 8
! H . 3 @
6 " ) ) 5 :

Drawing Pixels
+: !

videoBuffer[y * SCREENWIDTH + x] = color;

) : !*

void DrawPixel3(int x, int y, unsigned short color)


{
videoBuffer[y * 240 + x] = c;
}

4 !. !
6 ( I ) 4 4 !.
*

/////////////////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// Mode3Pixels Project
// main.c source code file
/////////////////////////////////////////////////////////////

//add support for the rand function


#include <stdlib.h>

//declare the function prototype

Programming The Nintendo Game Boy Advance: The Unofficial Guide ""
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
void DrawPixel3(int, int, unsigned short);

//declare some defines for the video mode


#define REG_DISPCNT *(unsigned long*)0x4000000
#define MODE_3 0x3
#define BG2_ENABLE 0x400

//changes the video mode


#define SetMode(mode) REG_DISPCNT = (mode)

//packs three values into a 15-bit color


#define RGB(r,g,b) ((r)+(g<<5)+(b<<10))

//create a pointer to the video buffer


unsigned short* videoBuffer = (unsigned short*)0x6000000;

/////////////////////////////////////////////////////////////
// Function: main()
// Entry point for the program
/////////////////////////////////////////////////////////////
int main(void)
{
int x, y;
unsigned short color;

SetMode(MODE_3 | BG2_ENABLE);

while(1)
{
//randomize the pixel
x = rand() % 240;
y = rand() % 160;
color = RGB(rand()%31, rand()%31, rand()%31);

Programming The Nintendo Game Boy Advance: The Unofficial Guide "$
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
DrawPixel3(x, y, color);
}

return 0;
}

/////////////////////////////////////////////////////////////
// Function: DrawPixel3
// Draws a pixel in mode 3
/////////////////////////////////////////////////////////////
void DrawPixel3(int x, int y, unsigned short color)
{
videoBuffer[y * 240 + x] = color;
}

4 !. 3 #!

%
" & %'

( )$

Drawing Lines
' 0
4 @H G
+

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
: @ : -
+: +
( - ; 4 !9
H . !
( 6H <' 4
J@ J6 $#J4 !9

/////////////////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// Mode3Lines Project
// main.c source code file
/////////////////////////////////////////////////////////////

#define MULTIBOOT int __gba_multiboot;


MULTIBOOT

//add support for the rand function


#include <stdlib.h>

//declare the function prototype


void DrawPixel3(int, int, unsigned short);
void DrawLine3(int, int, int, int, unsigned short);

//declare some defines for the video mode


#define REG_DISPCNT *(unsigned long*)0x4000000
#define MODE_3 0x3
#define BG2_ENABLE 0x400

//changes the video mode


#define SetMode(mode) REG_DISPCNT = (mode)

//packs three values into a 15-bit color

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
#define RGB(r,g,b) ((r)+(g<<5)+(b<<10))

//create a pointer to the video buffer


unsigned short* videoBuffer = (unsigned short*)0x6000000;

/////////////////////////////////////////////////////////////
// Function: main()
// Entry point for the program
/////////////////////////////////////////////////////////////
int main(void)
{
int x1,y1,x2,y2;
unsigned short color;

SetMode(MODE_3 | BG2_ENABLE);

while(1)
{
x1 = rand() % 240;
y1 = rand() % 160;
x2 = rand() % 240;
y2 = rand() % 160;
color = RGB(rand()%31, rand()%31, rand()%31);

DrawLine3(x1,y1,x2,y2,color);
}

return 0;
}

/////////////////////////////////////////////////////////////
// Function: DrawPixel3
// Draws a pixel in mode 3
/////////////////////////////////////////////////////////////

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
void DrawPixel3(int x, int y, unsigned short color)
{
videoBuffer[y * 240 + x] = color;
}

/////////////////////////////////////////////////////////////
// Function: DrawLine3
// Bresenham's infamous line algorithm
/////////////////////////////////////////////////////////////
void DrawLine3(int x1, int y1, int x2, int y2, unsigned short color)
{
int i, deltax, deltay, numpixels;
int d, dinc1, dinc2;
int x, xinc1, xinc2;
int y, yinc1, yinc2;

//calculate deltaX and deltaY


deltax = abs(x2 - x1);
deltay = abs(y2 - y1);

//initialize
if(deltax >= deltay)
{
//If x is independent variable
numpixels = deltax + 1;
d = (2 * deltay) - deltax;
dinc1 = deltay << 1;
dinc2 = (deltay - deltax) << 1;
xinc1 = 1;
xinc2 = 1;
yinc1 = 0;
yinc2 = 1;
}
else

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
{
//if y is independent variable
numpixels = deltay + 1;
d = (2 * deltax) - deltay;
dinc1 = deltax << 1;
dinc2 = (deltax - deltay) << 1;
xinc1 = 0;
xinc2 = 1;
yinc1 = 1;
yinc2 = 1;
}

//move the right direction


if(x1 > x2)
{
xinc1 = -xinc1;
xinc2 = -xinc2;
}
if(y1 > y2)
{
yinc1 = -yinc1;
yinc2 = -yinc2;
}

x = x1;
y = y1;

//draw the pixels


for(i = 1; i < numpixels; i++)
{
DrawPixel3(x, y, color);

if(d < 0)
{

Programming The Nintendo Game Boy Advance: The Unofficial Guide "!
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
d = d + dinc1;
x = x + xinc1;
y = y + yinc1;
}
else
{
d = d + dinc2;
x = x + xinc2;
y = y + yinc2;
}
}
}

4 !9 3 #"

*
" & %+

( )$

Making GBA Programs Multi-Bootable


4 !9 -
*

#define MULTIBOOT int __gba_multiboot;


MULTIBOOT

Programming The Nintendo Game Boy Advance: The Unofficial Guide $#


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
+
(
- 4
-
3 " + , -$
+ " " ' .

-
,
<' 4
- 4 I & 4 I& *KK -
-
<' 4 .6 :
<' 4

#define MULTIBOOT int __gba_multiboot;

LL L
) 4
@H G C - <' 4
4 I&

) ( M : - <
*

MULTIBOOT

+ - *

int __gba_multiboot;

) 4 /9 + ''

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
4 /9 + ''
<' 4 &#B
G / < 4 <
( < 4 =+ -
C 4 I& - ( <' 4

) -
4 /9 + '' + -
4 I& + N!$ $$
+ 9-@
+ 4 I& +
6 H <' 4 J4
- 4 I& 4 171

5 0 , &$$$ 7. 3
4 I& - +
J4 J4 J, L&GL7. 3
J, +5 5 J@8@ 14 !&JH <+I1<@ 5
.6 5 9. % !EA !E3 8
<
'
4 171
H
4 I&
6 . , ;
, OAK4 1

4 I& 5
6 . @ < 6H J4 6 H <' 4
6H

multiboot Mode3Lines

3
*

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
mb -w 50 -s %1.gba

5 + <' 4 J4
4 I& -
.6 + @ -
C =3 6 E F<
/ @ F, + : -
@
=)

+ : 4 I& + C
- - *

Parallel MBV2 cable found: hardware=v2.0, firmware=v4


EPP support found.
Looking for multiboot-ready GBA...
Sending data. Please wait...
CRC Ok - Done.

ERROR - No hardware found on selected parallel port!


Check parallel port number, make sure cable is connected to port and to GBA,
& make sure GBA is turned on.

+ 1 . . 1.. .6 : +' @ + .6
: 1.. : - 4 I& -
( + #$
- .6 + -
%$$ : - +

< 4 I&
,
C
= + 4 I&
N!$ $$ @

Programming The Nintendo Game Boy Advance: The Unofficial Guide $"
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
- 3
9 - 1 3 9 - +
4 I& : 8 4 I&
I ) 4 . ( @
4 I& - +
- + - 4 I& 3 P *KK K K
K & 0 ' F4 I&F

Drawing Circles

=
+ - -
, 4 !6
!

/////////////////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// Mode3Circles Project
// main.c source code file
/////////////////////////////////////////////////////////////

#define MULTIBOOT int __gba_multiboot;


MULTIBOOT

//add support for the rand function


#include <stdlib.h>

//declare the function prototype


void DrawPixel3(int, int, unsigned short);
void DrawCircle3(int, int, int, int);

//declare some defines for the video mode


#define REG_DISPCNT *(unsigned long*)0x4000000

Programming The Nintendo Game Boy Advance: The Unofficial Guide $$


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
#define MODE_3 0x3
#define BG2_ENABLE 0x400

//changes the video mode


#define SetMode(mode) REG_DISPCNT = (mode)

//packs three values into a 15-bit color


#define RGB(r,g,b) ((r)+(g<<5)+(b<<10))

//create a pointer to the video buffer


unsigned short* videoBuffer = (unsigned short*)0x6000000;

/////////////////////////////////////////////////////////////
// Function: main()
// Entry point for the program
/////////////////////////////////////////////////////////////
int main(void)
{
int x, y, r;
unsigned short color;

SetMode(MODE_3 | BG2_ENABLE);

while(1)
{
x = rand() % 240;
y = rand() % 160;
r = rand() % 50 + 10;
color = RGB(rand()%31, rand()%31, rand()%31);

DrawCircle3(x, y, r, color);
}

return 0;

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
}

/////////////////////////////////////////////////////////////
// Function: DrawPixel3
// Draws a pixel in mode 3
/////////////////////////////////////////////////////////////
void DrawPixel3(int x, int y, unsigned short color)
{
videoBuffer[y * 240 + x] = color;
}

/////////////////////////////////////////////////////////////
// Function: DrawCircle3
// Bresenham's infamous circle algorithm
/////////////////////////////////////////////////////////////
void DrawCircle3(int xCenter, int yCenter, int radius, int color)
{
int x = 0;
int y = radius;
int p = 3 - 2 * radius;
while (x <= y)
{
DrawPixel3(xCenter + x, yCenter + y, color);
DrawPixel3(xCenter - x, yCenter + y, color);
DrawPixel3(xCenter + x, yCenter - y, color);
DrawPixel3(xCenter - x, yCenter - y, color);
DrawPixel3(xCenter + y, yCenter + x, color);
DrawPixel3(xCenter - y, yCenter + x, color);
DrawPixel3(xCenter + y, yCenter - x, color);
DrawPixel3(xCenter - y, yCenter - x, color);

if (p < 0)
p += 4 * x++ + 6;
else

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
p += 4 * (x++ - y--) + 10;
}
}

4 !6 3 ##

" & %

( )$

Drawing Filled Boxes


) ?+: C
= 4 !
, + :
,

( 4 ! 6 H <' 4
J@ J6 $#J4 !

/////////////////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// Mode3Boxes Project
// main.c source code file
/////////////////////////////////////////////////////////////

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
#define MULTIBOOT int __gba_multiboot;
MULTIBOOT

//add support for the rand function


#include <stdlib.h>

//declare the function prototype


void DrawPixel3(int, int, unsigned short);
void DrawBox3(int, int, int, int, unsigned short);

//declare some defines for the video mode


#define REG_DISPCNT *(unsigned long*)0x4000000
#define MODE_3 0x3
#define BG2_ENABLE 0x400

//changes the video mode


#define SetMode(mode) REG_DISPCNT = (mode)

//packs three values into a 15-bit color


#define RGB(r,g,b) ((r)+(g<<5)+(b<<10))

//create a pointer to the video buffer


unsigned short* videoBuffer = (unsigned short*)0x6000000;

/////////////////////////////////////////////////////////////
// Function: main()
// Entry point for the program
/////////////////////////////////////////////////////////////
int main(void)
{
int x1, y1, x2, y2;
unsigned short color;

SetMode(MODE_3 | BG2_ENABLE);

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
while(1)
{
x1 = rand() % 240;
y1 = rand() % 160;
x2 = x1 + rand() % 60;
y2 = y1 + rand() % 60;
color = RGB(rand()%31, rand()%31, rand()%31);

DrawBox3(x1, y1, x2, y2, color);


}

return 0;
}

/////////////////////////////////////////////////////////////
// Function: DrawPixel3
// Draws a pixel in mode 3
/////////////////////////////////////////////////////////////
void DrawPixel3(int x, int y, unsigned short color)
{
videoBuffer[y * 240 + x] = color;
}

/////////////////////////////////////////////////////////////
// Function: DrawBox3
// Draws a filled box
/////////////////////////////////////////////////////////////
void DrawBox3(int left, int top, int right, int bottom,
unsigned short color)
{
int x, y;

for(y = top; y < bottom; y++)

Programming The Nintendo Game Boy Advance: The Unofficial Guide $!


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
for(x = left; x < right; x++)

DrawPixel3(x, y, color);

4 ! 3 #B

/
" & %)

( )$

Drawing Bitmaps
5 : ?
, - (
( +:
6 E +: -

Converting 8-Bit Bitmaps to 15-Bit Images


-
A &#B
%# ! # & A
: ( - 5
%# %B ### : K K<
<

Programming The Nintendo Game Boy Advance: The Unofficial Guide #


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
A -
- - - -
A %B

Converting Bitmap Images to Game Boy Format


: -

:
: 6 ;
+ @
>
& ; :(
- &
) 4
J J J !& ) 4

) 4
2
- @ < F F - 'G
4@
H' @ 8
' 0
+ & 8
( F6 H
J@ J6 $#J4 ! F + J@
6 H <' 4 '
- (

& ! C
*

gfx2gba -fsrc -c32k filename.bmp

A &#B & 5

6 !&- & C %#
A C : -

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
! # 3 5
- + !
( *

gfx2gba -fsrc -c32k mode3.bmp

! ! -
+ *

//
// mode3 (76800 uncompressed bytes)
//
const unsigned short mode3_Bitmap[38400] = {
0x7717, 0x7293, 0x69cd, 0x6e0f, 0x6e0f, 0x6e0f, 0x6e0f, 0x6e0f,
0x6e0f, 0x6e0f, 0x6e0f, 0x6e0f, 0x6e0f, 0x6e0f, 0x6e0f, 0x6e0f,
0x6e0f, 0x6e0f, 0x7293, 0x7717, 0x6e51, 0x6e0f, 0x7717, 0x6e51,
0x656a, 0x69cd, 0x61aa, 0x58c3, 0x6e51, 0x6e51, 0x7293, 0x7717,
0x7bbc, 0x7b5a, 0x6a2f, 0x6a2f, 0x6e51, 0x69cd, 0x656a, 0x6a2f,
0x6a2f, 0x6a2f, 0x6a2f, 0x6a2f, 0x6a2f, 0x6a2f, 0x7717, 0x7b9b,
0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7759, 0x7293,
0x6e51, 0x6a2e, 0x6a2f, 0x6a72, 0x7293, 0x6127, 0x58c3, 0x58c3,
. . .

5 C %# EB A$$ +
!A "$$ ; C "
+ "

Drawing Converted Bitmaps


6
-
; - ) : 4 !
*

/////////////////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// Mode3Bitmap Project

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
// main.c source code file
/////////////////////////////////////////////////////////////

#define MULTIBOOT int __gba_multiboot;


MULTIBOOT

//include files
#include <stdlib.h>
#include "mode3.raw.c"

//declare the function prototype


void DrawPixel3(int, int, unsigned short);

//declare some defines for the video mode


#define REG_DISPCNT *(unsigned long*)0x4000000
#define MODE_3 0x3
#define BG2_ENABLE 0x400

//changes the video mode


#define SetMode(mode) REG_DISPCNT = (mode)

//create a pointer to the video buffer


unsigned short* videoBuffer = (unsigned short*)0x6000000;

/////////////////////////////////////////////////////////////
// Function: main()
// Entry point for the program
/////////////////////////////////////////////////////////////
int main(void)
{
int x, y;

SetMode(MODE_3 | BG2_ENABLE);

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
//display the bitmap
for(y = 0; y < 160; y++)
for(x = 0; x < 240; x++)
DrawPixel3(x, y, mode3_Bitmap[y * 240 + x]);

//endless loop
while(1)
{
}

return 0;
}

/////////////////////////////////////////////////////////////
// Function: DrawPixel3
// Draws a pixel in mode 3
/////////////////////////////////////////////////////////////
void DrawPixel3(int x, int y, unsigned short c)
{
videoBuffer[y * 240 + x] = c;
}

4 ! 3 #E

" 0 1& $
. 0

1& $ 2 34
" 3

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
5
" & %)

( )$

Working with Mode 4


I " A C &"$ %B$
- %B
%B

Dealing with Palettes


4 " A C &#B
- )
" & *

const unsigned short mode4_Palette[256] = {


0x0001, 0x0023, 0x0026, 0x0086, 0x002a, 0x008a, 0x00aa, 0x010a,
0x00a9, 0x00ad, 0x00ae, 0x014e, 0x3940, 0x190b, 0x44e0, 0x4522,
0x25c0, 0x1e20, 0x3181, 0x2dc1, 0x2a23, 0x15cb, 0x3604, 0x3629,
0x4183, 0x45a5, 0x41e5, 0x4206, 0x3e27, 0x4627, 0x4228, 0x420c,
0x5481, 0x58c3, 0x5525, 0x6127, 0x4d86, 0x4dc7, 0x5186, 0x5988,
.
.
.
0x5fb5, 0x6357, 0x6396, 0x63b7, 0x639a, 0x6b36, 0x6b57, 0x6f37,
0x7357, 0x6f58, 0x7359, 0x7759, 0x7b5a, 0x6b78, 0x6f99, 0x6b99,
0x6fba, 0x739a, 0x7779, 0x7b9a, 0x6fdb, 0x73dc, 0x77bb, 0x7b9b,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0x7bbc, 0x7bdc, 0x7bdd, 0x77fd, 0x7fde, 0x7bfe, 0x7ffe, 0x77bf,
0x7bdf, 0x7fff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};

: +
8 5 I ) 4 ,
- "
- $

&#B
$ #$$$$$$ :
*

unsigned short* paletteMem = (unsigned short*)0x5000000;

@
&#B 4 3 *

for (n = 0; n < 256; n++)


paletteMem[n] = RGB(31, 31, 31);

4 "

5
= : ( &#B
C
5 :
- $ - $ $$
<
%B ; 6 E
F< / @ F 3 #A
! %# " A

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
2
2
!

Drawing Pixels
+ " -
! #
" : A
%B
96 H >
- -

3 #O

6
& *

!/

+ %B
-
0 ( ;

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
- 3 -
: -
+:

3 &*

unsigned short offset = (y * 240 + x) >> 1;


pixel = videoBuffer[offset];

5 5H: %*

if (x & 1)

3 +
A
- *

videoBuffer[offset] = (color << 8) + (pixel & 0x00FF);

+
- *

videoBuffer[offset] = (pixel & 0xFF00) + color;

) "
H4
, "
- ! #
'- : "

void DrawPixel4(int x, int y, unsigned char color)


{
unsigned short pixel;
unsigned short offset = (y * 240 + x) >> 1;

pixel = videoBuffer[offset];
if (x & 1)
videoBuffer[offset] = (color << 8) + (pixel & 0x00FF);
else

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
videoBuffer[offset] = (pixel & 0xFF00) + color;
}

4 ".

4 ".
" H . " + - "
- +
) 4 ".

/////////////////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// Mode4Pixels Project
// main.c source code file
/////////////////////////////////////////////////////////////

#define MULTIBOOT int __gba_multiboot;


MULTIBOOT

//add support for the rand function


#include <stdlib.h>

//declare the function prototype


void DrawPixel4(int x, int y, unsigned char bColor);

//declare some defines for the video mode


#define MODE_4 0x4
#define BG2_ENABLE 0x400
#define REG_DISPCNT *(unsigned int*)0x4000000
#define RGB(r,g,b) (unsigned short)((r)+((g)<<5)+((b)<<10))

//create a pointer to the video and palette buffers


unsigned short* videoBuffer = (unsigned short*)0x6000000;

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
unsigned short* paletteMem = (unsigned short*)0x5000000;

//changes the video mode


#define SetMode(mode) REG_DISPCNT = (mode)

/////////////////////////////////////////////////////////////
// Function: main()
// Entry point for the program
/////////////////////////////////////////////////////////////
int main(void)
{
int x1,y1,n;

SetMode(MODE_4 | BG2_ENABLE);

for (n = 1; n < 256; n++)


paletteMem[n] = RGB(rand() % 31, rand() % 31, rand() % 31);

while(1)
{
x1 = rand() % 240;
y1 = rand() % 160;

DrawPixel4(x1, y1, rand() % 256);


}

return 0;
}

/////////////////////////////////////////////////////////////
// Function: DrawPixel4
// Draws a pixel in mode 4
/////////////////////////////////////////////////////////////
void DrawPixel4(int x, int y, unsigned char color)

Programming The Nintendo Game Boy Advance: The Unofficial Guide #


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
{
unsigned short pixel;
unsigned short offset = (y * 240 + x) >> 1;

pixel = videoBuffer[offset];
if (x & 1)
videoBuffer[offset] = (color << 8) + (pixel & 0x00FF);
else
videoBuffer[offset] = (pixel & 0xFF00) + color;
}

4 ". 3 # %$

!7
" & *'

( )$

/ H . "
! + :
H . H . !
H . " H . # + H . " (
-

Drawing Bitmaps
@ " A - :
& " ! 3
!A "$$ " - !

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
- EB A$$ C 9
! +: "
2 &"$ %B$ -
:A &#B & +
- ( 6H <' 4 J@ J6 $#J4 " ) :
6 *

gfx2gba -fsrc -pmode4.pal mode4.bmp

& * " "


@
"L.
+:
" ( 4 " 4 !
2 ( I ) 4
3E

/////////////////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// Mode4Bitmap Project
// main.c source code file
/////////////////////////////////////////////////////////////

#define MULTIBOOT int __gba_multiboot;


MULTIBOOT

//include files
#include <stdlib.h>
#include <string.h>
#include "mode4.raw.c"
#include "mode4.pal.c"

//declare some defines for the video mode


#define REG_DISPCNT *(unsigned long*)0x4000000
#define MODE_4 0x4

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
#define BG2_ENABLE 0x400

//changes the video mode


#define SetMode(mode) REG_DISPCNT = (mode)

//create a pointer to the video and palette buffers


unsigned short* videoBuffer = (unsigned short*)0x6000000;
unsigned short* paletteMem = (unsigned short*)0x5000000;

/////////////////////////////////////////////////////////////
// Function: main()
// Entry point for the program
/////////////////////////////////////////////////////////////
int main(void)
{
int n;

//set video mode 4


SetMode(MODE_4 | BG2_ENABLE);

//set up the palette colors


for (n = 0; n < 256; n++)
paletteMem[n] = mode4_Palette[n];

//display the bitmap


memcpy(videoBuffer, mode4_Bitmap, 38400);

//endless loop
while(1)
{
}

return 0;
}

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
, = : - 4 ! , : H . "
? +:

+ - "=
3 # %% 5 @+ 6 -
+ 6
) 4 @H G 5 @+ 6

!!
" & *)

4
: - ; (
) "L
%&$ %B$ : 8
+: C H4

Page Flipping and Double Buffering


. " # +:

0 - + -

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
- -

+ ;
- !
- + "
$ B$$$$$$ - - $ B$$ $$$ )
*

unsigned short* FrontBuffer = (unsigned short*)0x6000000;


unsigned short* BackBuffer = (unsigned short*)0x600A000;

/ - *

#define BACKBUFFER 0x10

-
; 0 =

void FlipPage(void)
{
if(REG_DISPCNT & BACKBUFFER)
{
REG_DISPCNT &= ~BACKBUFFER;
videoBuffer = BackBuffer;
}
else
{
REG_DISPCNT |= BACKBUFFER;
videoBuffer = FrontBuffer;
}
}

) 4 "3 8 (
6H <' 4 J@ J6 $#J4 "3
I ) 4

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
/////////////////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// Mode4Flip Project
// main.c source code file
/////////////////////////////////////////////////////////////

#define MULTIBOOT int __gba_multiboot;


MULTIBOOT

//add support for the rand function


#include <stdlib.h>
#include <string.h>

//declare the function prototype


void DrawPixel4(int, int, unsigned char);
void DrawBox4(int, int, int, int, unsigned char);
void FlipPage(void);
void WaitVBlank(void);

//declare some defines for the video mode


#define REG_DISPCNT *(unsigned long*)0x4000000
#define MODE_4 0x4
#define BG2_ENABLE 0x400

//changes the video mode


#define SetMode(mode) REG_DISPCNT = (mode)

//packs three values into a 15-bit color


#define RGB(r,g,b) (unsigned short)((r)+((g)<<5)+((b)<<10))

//video buffer defines

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
#define BACKBUFFER 0x10
unsigned short* FrontBuffer = (unsigned short*)0x6000000;
unsigned short* BackBuffer = (unsigned short*)0x600A000;
unsigned short* videoBuffer;
unsigned short* paletteMem = (unsigned short*)0x5000000;

volatile unsigned short* ScanlineCounter =


(volatile unsigned short*)0x4000006;

/////////////////////////////////////////////////////////////
// Function: main()
// Entry point for the program
/////////////////////////////////////////////////////////////
int main(void)
{
int n;

//set video mode and start page flipping


SetMode(MODE_4 | BG2_ENABLE);
FlipPage();

//set the first two palette entries


paletteMem = RGB(0, 31, 0);
paletteMem = RGB(31, 0, 0);

//draw the first random box


DrawBox4(20, 20, 100, 140, 1);

//flip the page to the back buffer


FlipPage();

//draw the second random box


DrawBox4(140, 20, 220, 140, 2);

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
while(1)
{
//wait for vertical blank
WaitVBlank();

//flip the page


FlipPage();

//slow it down--modify as needed


n = 500000;
while(n--);
}

return 0;
}

/////////////////////////////////////////////////////////////
// Function: DrawPixel4
// Draws a pixel in mode 4
/////////////////////////////////////////////////////////////
void DrawPixel4(int x, int y, unsigned char color)
{
unsigned short pixel;
unsigned short offset = (y * 240 + x) >> 1;

pixel = videoBuffer[offset];
if (x & 1)
videoBuffer[offset] = (color << 8) + (pixel & 0x00FF);
else
videoBuffer[offset] = (pixel & 0xFF00) + color;
}

/////////////////////////////////////////////////////////////

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
// Function: DrawBox4
// Draws a filled box
/////////////////////////////////////////////////////////////
void DrawBox4(int left, int top, int right, int bottom,
unsigned char color)
{
int x, y;

for(y = top; y < bottom; y++)


for(x = left; x < right; x++)
DrawPixel4(x, y, color);
}

/////////////////////////////////////////////////////////////
// Function: FlipPage
// Switches between the front and back buffers
/////////////////////////////////////////////////////////////
void FlipPage(void)
{
if(REG_DISPCNT & BACKBUFFER)
{
REG_DISPCNT &= ~BACKBUFFER;
videoBuffer = BackBuffer;
}
else
{
REG_DISPCNT |= BACKBUFFER;
videoBuffer = FrontBuffer;
}
}
/////////////////////////////////////////////////////////////
// Function: WaitVBlank

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
// Checks the scanline counter for the vertical blank period
/////////////////////////////////////////////////////////////
void WaitVBlank(void)
{
while(*ScanlineCounter < 160);

4 "3 3 # %&

!#
" & *

Working with Mode 5


4 # ! %#
) # *
%B$ %&A= &"$ %B$ :
%#

Drawing Pixels
4 # ! : 0
( H . ! -
# *

void DrawPixel5(int x, int y, unsigned short c)

Programming The Nintendo Game Boy Advance: The Unofficial Guide #


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
{
videoBuffer[y * 160 + x] = c;
}

Testing Mode 5
4 #. ! (
@ 4 4 ' H 1L# -
%B$ %&A H #
! C +
# ( %B$ %&A C
& ! #L
!L @ =) 4 #. *

/////////////////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// Mode5Pixels Project
// main.c source code file
/////////////////////////////////////////////////////////////

//add support for the rand function


#include <stdlib.h>

//declare the function prototype


void DrawPixel5(int, int, unsigned short);

//declare some defines for the video mode


#define REG_DISPCNT *(unsigned long*)0x4000000
#define MODE_5 0x5
#define BG2_ENABLE 0x400

//changes the video mode


#define SetMode(mode) REG_DISPCNT = (mode)

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
//packs three values into a 15-bit color
#define RGB(r,g,b) ((r)+(g<<5)+(b<<10))

//create a pointer to the video buffer


unsigned short* videoBuffer = (unsigned short*)0x6000000;

/////////////////////////////////////////////////////////////
// Function: main()
// Entry point for the program
/////////////////////////////////////////////////////////////
int main(void)
{
int x, y;
unsigned short color;

SetMode(MODE_5 | BG2_ENABLE);

while(1)
{
//randomize the pixel
x = rand() % 160;
y = rand() % 128;
color = RGB(rand()%31, rand()%31, rand()%31);
DrawPixel5(x, y, color);
}

return 0;
}

/////////////////////////////////////////////////////////////
// Function: DrawPixel5
// Draws a pixel in mode 5
/////////////////////////////////////////////////////////////
void DrawPixel5(int x, int y, unsigned short c)

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
{
videoBuffer[y * 160 + x] = c;
}

4 #. 3 # %!

!%
" & '

( )$

. @
+ : 0 +: -
- ( (
8

=
) - 6 " F@ F

( - >

5 + C :
) +
+
+ .
H 6

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
-
.

void Print(int left, int top, char *str, unsigned short color)
{
int pos = 0;
while (*str)
{
DrawChar(left + pos, top, *str++, color);
pos += 8;
}
}

void DrawChar(int left, int top, char letter, unsigned short color)
{
int x, y;
int draw;

for(y = 0; y < 8; y++)


for (x = 0; x < 8; x++)
{
// grab a pixel from the font char
draw = font[(letter-32) * 64 + y * 8 + x];
// if pixel = 1, then draw it
if (draw)
DrawPixel3(left + x, top + y, color);
}
}

The Hard-Coded Font


5 - : +
> ( -
+ 8 % '
6 H <' 4 +

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
J@ J6 $#JH + :
( I ) 4 H (

#ifndef _FONT_H
#define _FONT_H

#define W 1

unsigned short font[] =


{
// (space) 32
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
// ! 33
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
// " 34
0,0,0,0,0,0,0,0,
0,W,W,0,W,W,0,0,
0,W,W,0,W,W,0,0,
0,0,W,0,0,W,0,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,0,W,0,0,W,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
// # 35
0,0,0,0,0,0,0,0,
0,0,W,0,0,W,0,0,
0,W,W,W,W,W,W,0,
0,0,W,0,0,W,0,0,
0,0,W,0,0,W,0,0,
0,W,W,W,W,W,W,0,
0,0,W,0,0,W,0,0,
0,0,0,0,0,0,0,0,
// $ 36
0,0,0,W,0,0,0,0,
0,0,W,W,W,W,0,0,
0,W,0,W,0,0,0,0,
0,0,W,W,W,0,0,0,
0,0,0,W,0,W,0,0,
0,W,W,W,W,0,0,0,
0,0,0,W,0,0,0,0,
0,0,0,0,0,0,0,0,
// % 37
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,W,W,0,0,W,0,0,
0,W,W,0,W,0,0,0,
0,0,0,W,0,0,0,0,
0,0,W,0,W,W,0,0,
0,W,0,0,W,W,0,0,
0,0,0,0,0,0,0,0,
// & 38
0,0,0,0,0,0,0,0,
0,0,W,W,W,0,0,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,W,0,0,0,W,0,0,
0,0,W,W,W,0,0,0,
0,W,0,W,0,0,0,0,
0,W,0,0,W,0,W,0,
0,0,W,W,W,W,0,0,
0,0,0,0,0,0,W,0,
// ' 39
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,0,W,0,0,0,
0,0,0,0,W,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
// ( 40
0,0,0,0,0,0,W,0,
0,0,0,0,0,W,0,0,
0,0,0,0,0,W,0,0,
0,0,0,0,0,W,0,0,
0,0,0,0,0,W,0,0,
0,0,0,0,0,W,0,0,
0,0,0,0,0,W,0,0,
0,0,0,0,0,0,W,0,
// ) 41
0,W,0,0,0,0,0,0,
0,0,W,0,0,0,0,0,
0,0,W,0,0,0,0,0,
0,0,W,0,0,0,0,0,
0,0,W,0,0,0,0,0,
0,0,W,0,0,0,0,0,
0,0,W,0,0,0,0,0,
0,W,0,0,0,0,0,0,
// * 42

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,0,0,0,0,0,0,0,
0,0,0,W,0,0,0,0,
0,W,0,W,0,W,0,0,
0,0,W,W,W,0,0,0,
0,0,W,W,W,0,0,0,
0,0,W,W,W,0,0,0,
0,W,0,0,0,W,0,0,
0,0,0,0,0,0,0,0,
// + 43
0,0,0,0,0,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,W,W,W,W,W,W,0,
0,W,W,W,W,W,W,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,0,0,0,0,0,
// , 44
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,0,0,0,0,0,
// - 45
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,W,W,W,W,W,W,0,
0,W,W,W,W,W,W,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,0,0,0,0,0,0,0,
// . 46
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,0,0,0,0,0,0,
// / 47
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,W,0,
0,0,0,0,0,W,W,0,
0,0,0,0,W,W,0,0,
0,0,0,W,W,0,0,0,
0,0,W,W,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,0,0,0,0,0,0,
// 0 48
0,0,W,W,W,W,0,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,W,W,0,
0,W,W,0,W,0,W,0,
0,W,W,W,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,W,W,0,0,
// 1 49
0,0,0,0,W,0,0,0,
0,0,W,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,W,W,W,W,0,0,
// 2 50
0,0,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,0,0,0,0,W,0,
0,0,0,0,0,W,W,0,
0,0,0,0,W,W,0,0,
0,0,0,W,W,0,0,0,
0,0,W,W,0,0,0,0,
0,W,W,W,W,W,W,0,
// 3 51
0,0,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,0,0,0,0,W,0,
0,0,0,0,0,0,W,0,
0,0,0,W,W,W,0,0,
0,0,0,0,0,0,W,0,
0,W,0,0,0,0,W,0,
0,0,W,W,W,W,0,0,
// 4 52
0,0,0,0,W,W,0,0,
0,0,0,W,W,W,0,0,
0,0,W,W,0,W,0,0,
0,W,W,0,0,W,0,0,
0,W,W,W,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
// 5 53
0,W,W,W,W,W,W,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,0,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide #


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,W,W,0,0,0,0,0,
0,0,W,W,W,W,0,0,
0,0,0,0,0,0,W,0,
0,W,0,0,0,0,W,0,
0,0,W,W,W,W,0,0,
// 6 54
0,0,0,W,W,W,W,0,
0,0,W,W,W,W,W,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,W,W,W,0,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,W,W,0,0,
// 7 55
0,W,W,W,W,W,W,0,
0,W,W,W,W,W,W,0,
0,W,0,0,0,W,W,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,W,W,0,0,0,0,
// 8 56
0,0,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,0,W,0,0,0,W,0,
0,0,W,W,W,W,0,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,W,W,0,0,
// 9 57
0,0,W,W,W,W,0,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,W,W,W,0,
0,0,0,0,0,W,W,0,
0,0,0,0,0,W,W,0,
0,0,0,0,0,W,W,0,
// : 58
0,0,0,0,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,0,0,0,0,0,0,
// ; 59
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
// < 60
0,0,0,0,W,W,0,0,
0,0,0,W,W,0,0,0,
0,0,W,W,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,0,W,W,0,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
// = 61
0,0,0,0,0,0,0,0,
0,W,W,W,W,W,0,0,
0,W,W,W,W,W,0,0,
0,0,0,0,0,0,0,0,
0,W,W,W,W,W,0,0,
0,W,W,W,W,W,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
// > 62
0,W,W,0,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,W,W,0,0,0,
0,0,W,W,0,0,0,0,
0,W,W,0,0,0,0,0,
// ? 63
0,0,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,0,0,0,W,W,0,
0,0,0,0,W,W,0,0,
0,0,0,W,W,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
// @ 64
0,0,0,0,0,0,0,0,
0,0,W,W,W,0,0,0,
0,W,0,0,0,W,0,0,
0,W,0,W,W,0,0,0,
0,W,0,W,W,0,0,0,
0,W,0,0,0,0,W,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide "
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,0,W,W,W,W,0,0,
0,0,0,0,0,0,0,0,
// A 65
0,0,W,W,W,0,0,0,
0,W,W,W,W,W,0,0,
0,W,W,0,0,W,0,0,
0,W,W,0,0,W,0,0,
0,W,W,W,W,W,0,0,
0,W,W,W,W,W,0,0,
0,W,W,0,0,W,0,0,
0,W,W,0,0,W,0,0,
// B 66
0,W,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,W,W,0,
0,W,W,0,0,W,0,0,
0,W,W,W,W,W,0,0,
0,W,W,0,0,W,W,0,
0,W,W,0,0,W,W,0,
0,W,W,W,W,W,0,0,
// C 67
0,0,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,W,0,
0,0,W,W,W,W,0,0,
// D 68
0,W,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide $


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,W,W,W,0,0,
// E 69
0,W,W,W,W,W,W,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,W,W,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,W,W,W,W,0,
// F 70
0,W,W,W,W,W,W,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,W,W,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
// G 71
0,0,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,0,0,
0,W,W,0,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,W,W,0,0,
// H 72
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
// I 73
0,0,W,W,W,W,0,0,
0,0,W,W,W,W,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,W,W,W,W,0,0,
// J 74
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,W,0,0,W,W,0,0,
0,W,W,W,W,W,0,0,
0,0,W,W,W,0,0,0,
// K 75
0,W,W,0,0,0,W,0,
0,W,W,0,0,W,W,0,
0,W,W,0,W,W,0,0,
0,W,W,W,W,0,0,0,
0,W,W,W,W,0,0,0,
0,W,W,0,W,W,0,0,
0,W,W,0,0,W,W,0,
0,W,W,0,0,0,W,0,
// L 76

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,W,W,W,W,0,
// M 77
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,W,0,W,W,0,
0,W,W,W,W,W,W,0,
0,W,W,0,W,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
// N 78
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,W,0,0,W,0,
0,W,W,W,W,0,W,0,
0,W,W,0,W,W,W,0,
0,W,W,0,0,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
// O 79
0,0,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,0,W,W,W,W,0,0,
// P 80
0,W,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,W,W,W,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
// Q 81
0,0,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,W,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,W,W,0,W,
// R 82
0,W,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,W,0,0,
0,W,W,W,W,0,0,0,
0,W,W,0,W,W,0,0,
0,W,W,0,0,W,W,0,
// S 83
0,0,W,W,W,W,0,0,
0,W,W,W,W,W,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,0,0,
0,0,W,W,W,W,0,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,0,0,0,0,0,W,0,
0,W,0,0,0,0,W,0,
0,0,W,W,W,W,0,0,
// T 84
0,W,W,W,W,W,W,0,
0,W,W,W,W,W,W,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
// U 85
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,W,W,0,0,
// V 86
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,0,W,0,0,
0,0,W,W,0,W,0,0,
0,0,W,W,0,W,0,0,
0,0,0,W,W,0,0,0,
// W 87
0,W,W,0,0,0,0,W,
0,W,W,0,0,0,0,W,
0,W,W,0,0,0,0,W,

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,W,W,0,0,0,0,W,
0,W,W,0,W,W,0,W,
0,0,W,W,0,0,W,0,
0,0,W,W,0,0,W,0,
0,0,W,W,0,0,W,0,
// X 88
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,0,W,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,W,W,0,W,0,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
// Y 89
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,W,W,0,0,0,W,0,
0,0,W,W,W,W,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
// Z 90
0,W,W,W,W,W,W,0,
0,W,W,W,W,W,W,0,
0,0,0,0,0,W,W,0,
0,0,0,0,W,W,0,0,
0,0,0,W,W,0,0,0,
0,0,W,W,0,0,0,0,
0,W,W,0,0,0,0,0,
0,W,W,W,W,W,W,0,
// [ 91
0,0,0,0,W,W,W,0,

Programming The Nintendo Game Boy Advance: The Unofficial Guide !#


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,W,0,
// \ 92
0,W,W,0,0,0,0,0,
0,W,W,0,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,W,W,0,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,W,W,0,0,0,
0,0,0,0,W,W,0,0,
0,0,0,0,W,W,0,0,
// ] 93
0,W,W,W,0,0,0,0,
0,W,W,W,0,0,0,0,
0,0,0,W,0,0,0,0,
0,0,0,W,0,0,0,0,
0,0,0,W,0,0,0,0,
0,0,0,W,0,0,0,0,
0,0,0,W,0,0,0,0,
0,W,W,W,0,0,0,0,
};
#endif

The DrawText Program


H !
6 ( H
( 3 H
+ - " #

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
H 6 H . " H . #

//////////////////////////////////////////////////
// Programming The Game Boy Advance
// Chapter 5: Bitmap-Based Video Modes
// DrawText Project
// main.c source code file
//////////////////////////////////////////////////

#define MULTIBOOT int __gba_multiboot;


MULTIBOOT

#include "font.h"

//declare some function prototypes


void DrawPixel3(int, int, unsigned short);
void DrawChar(int, int, char, unsigned short);
void Print(int, int, char *, unsigned short);

//create some color constants


#define WHITE 0xFFFF
#define RED 0x00FF
#define BLUE 0xEE00
#define CYAN 0xFF00
#define GREEN 0x0EE0
#define MAGENTA 0xF00F
#define BROWN 0x0D0D

//define some video mode values


#define REG_DISPCNT *(unsigned long*)0x4000000
#define MODE_3 0x3
#define BG2_ENABLE 0x400

//create a pointer to the video buffer

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
unsigned short* videoBuffer = (unsigned short*)0x6000000;

//////////////////////////////////////////////////
// Function: main()
// Entry point for the program
//////////////////////////////////////////////////
int main()
{
char *test = "TESTING...1...2...3...";
int pos = 0;

//switch to video mode 3 (240x160 16-bit)


REG_DISPCNT = (MODE_3 | BG2_ENABLE);

Print(1, 1, "DRAWTEXT PROGRAM", RED);


Print(1, 20, "()*+,-.0123456789:;<=>?@", GREEN);
Print(1, 30, "ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]", BLUE);
Print(1, 50, "BITMAP FONTS ARE A CINCH!", MAGENTA);
Print(1, 60, "(JUST BE SURE TO USE CAPS)", CYAN);

//display each character in a different color


while (*test)
{
DrawChar(1 + pos, 80, *test++, 0xBB + pos * 16);
pos += 8;
}

Print(1, 100, "THAT'S ALL, FOLKS =]", BROWN);

//continuous loop
while(1)
{
}

Programming The Nintendo Game Boy Advance: The Unofficial Guide !"
Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
return 0;
}

//////////////////////////////////////////////////
// Function: DrawPixel3
// Draws a pixel in mode 3
//////////////////////////////////////////////////
void DrawPixel3(int x, int y, unsigned short color)
{
videoBuffer[y * 240 + x] = color;
}

//////////////////////////////////////////////////
// Function: Print
// Prints a string using the hard-coded font
//////////////////////////////////////////////////
void Print(int left, int top, char *str, unsigned short color)
{
int pos = 0;
while (*str)
{
DrawChar(left + pos, top, *str++, color);
pos += 8;
}
}

//////////////////////////////////////////////////
// Function: DrawChar
// Draws a character one pixel at a time
//////////////////////////////////////////////////
void DrawChar(int left, int top, char letter, unsigned short color)
{
int x, y;
int draw;

Programming The Nintendo Game Boy Advance: The Unofficial Guide !$


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
for(y = 0; y < 8; y++)
for (x = 0; x < 8; x++)
{
// grab a pixel from the font char
draw = font[(letter-32) * 64 + y * 8 + x];
// if pixel = 1, then draw it
if (draw)
DrawPixel3(left + x, top + y, color);
}
}

H 3 # %"

!*
" 1 "

( )$

Summary
0 (
! " #

A " %#
! 9 -
-
.

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
Challenges

$ -/ 4 #
! +
- 5 : =,
#

$ 0/ 4 ! C 5 -

4 H !

$ 1/ 5 =
! (
+ (
. @6 ++

Chapter Quiz
0 C
0 C %$ 0 -
0 C

% , ?
$ E$$B$$$
$ B$$$$$$
6 $ B$$#$$$
H $ "O&A!$$

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
& , &"$ %B$ ?
4 "
4 !
6 4 #
H 4 &

! 3 *I #

" , %B$ %&A?


4 B
4 "
6 4 #
H 4 !

# , - "?
$ B$$$$$$
$ E$$B$$$
6 $ B$$#$$$
H $ B$$ $$$

B , 4 !9 ?
1

6 ) -
H I 5

E , &"$ %B$ %# - ?
4 !
4 &
6 4 #
H 4 "

A , %# ! #?

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com
6
H -

O , "?
!&
%B
6 B"
H A

%$ , C -
?
@1 +
,
6 . - 6
H + : - =

Programming The Nintendo Game Boy Advance: The Unofficial Guide !


Copyright (c)2003 by Jonathan S. Harbour -- http://www.jharbour.com

Potrebbero piacerti anche