GBA Development From the Ground Up, Volume 3

Published March 10, 2002 by Brian Sowers, posted by Myopic Rhino
Do you see issues with this article? Let us know.
Advertisement
[size="5"]What will this article cover?

This article is going to be short and sweet. It's going to cover input, a remarkably easy topic that should be refreshing after the last volume. In fact, I'm not even sure this article is worthy of a whole volume, but this is how I'm going to do it anyhow.


[size="5"]Getting Input

Unlike the PC where you have a gagillion different possible input devices, we're blessed enough to only have one to deal with. What's more, this input device is simple enough to cover swiftly and efficiently.

Input from the keypad is detected in a single register located at 0x4000130. Thus, our definition would look something like this:

#define KEYS (*(volatile u16*)0x4000130)
OR we could use the version defined in gba.h called REG_P1. It's already defined, so you wouldn't need the above snippet. However, I like using the name KEYS instead of REG_P1 because it seems more explanatory to me. You do whatever you want.

The variable is volatile because the register changes outside the code. Each bit in this register gives the status of a specific key. Thus, we want a header file so that we can access all the different bits with simple variable names. Here we go:

//keypad.h
#ifndef __KEYPAD__
#define __KEYPAD__
#define KEYA 1
#define KEYB 2
#define KEYSELECT 4
#define KEYSTART 8
#define KEYRIGHT 16
#define KEYLEFT 32
#define KEYUP 64
#define KEYDOWN 128
#define KEYR 256
#define KEYL 512

//This is already in gba.h, but it has a much less reader-friendly name (REG_P1)
#define KEYS (*(volatile u16*)0x4000130)

#define KEY_DOWN(k) ( ! ( ( KEYS ) & k ) )

#endif
That's the entire file. Now to check if a specific button is pressed, we check that respective bit (using &) to see if it is clear. If so, the key has been pressed. Look at this:

if ( ! ( (KEYS) & DESIREDKEY ) )
{
//The ! makes sure the bit is NOT 1... if it's not 1, the key is pressed
//do whatever
}
I prefer to make a little macro like this:

#define KEY_DOWN( k ) ( ! ( ( KEYS ) & k ) )
Then I can just use KEY_DOWN in my if statement instead of remember the & and ! of KEYS.

So, with the help of keypad.h, all you have to do is use KEY_DOWN to figure out if a button was pressed.


[size="5"]Example

If you somehow don't understand input, here's a little example to clench the deal:

#include "gba.h" //Defined in Volume 2 (ALWAYS include this first)
#include "keypad.h"
#include "screenmodes.h" //Defined in Volume 2

u16* theVideoBuffer = (u16*)VideoBuffer;
#define RGB(r,g,b) (r+(g<<5)+(b<<10)) //Macro to build a color

void FillScreen( u16 color )
{
u16 x, y;
for ( x = 0; x < 240; x++ )
for ( y = 0; y < 160; y++ )
theVideoBuffer[ y * 240 + x ] = color;
}

int main()
{
SetMode( SCREENMODE3 | BG2ENABLE );

while ( 1 )
if ( KEY_DOWN( KEYUP) )
FillScreen( RGB(31,0,0) );
else if ( KEY_DOWN( KEYDOWN) )
FillScreen( RGB(0,31,0) );
else if ( KEY_DOWN(KEYLEFT) )
FillScreen( RGB(0,0,31) );
else if ( KEY_DOWN(KEYRIGHT) )
FillScreen( RGB(31,31,0) );
else if ( KEY_DOWN(KEYA) )
FillScreen( RGB(0,31,31) );
else if ( KEY_DOWN(KEYB) )
FillScreen( RGB(31,0,31) );
else if ( KEY_DOWN(KEYSTART) )
break;

return 0;
}
All the demo does is fill the screen with a certain color depending on what button is pressed. Start ends the program.


[size="5"]Next Article

In the next article, I'm going to give you information on a slightly complex/tricky topic-tile modes.


[size="5"]Acknowledgements

I would like to thank dovoto, as his tutorials have been my biggest source of information on GBA development since I started. Check out his site at www.thepernproject.com. I'd also like to thank the guys in #gamedev and #gbadev on EFNet in IRC for all their help, and all the help they'll be giving me as I write these articles. Furthermore, I would like to thank www.gbadev.org/. The site is a great resource, and it is definitely worth your time.

Special thanks to www.gamedev.net for being my largest game development resource and for putting my articles on their site. Extra special thanks to Inspi for helping me with my coding woes and checking over this article.

If you have any questions or comments, you can always e-mail me at [email="genesisgenocide@yahoo.com"]genesisgenocide@yahoo.com[/email] or [email="nairb@usa.com"]nairb@usa.com[/email]. I can't promise I'll answer your questions, like your comments, or listen to your suggestions, but I'll at least read the e-mail (as long as it doesn't look like spam).
Cancel Save
0 Likes 0 Comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!

The third installment in this series provides an explanation and example of getting input on the GameBoy Advance.

Advertisement
Advertisement
Advertisement