GBA Development/HAM IDE
GBA development with the HAM IDE and compiler
[edit | edit source]Step 1 - Setup
[edit | edit source]The first thing that needs to be done for this project is to download and install the necessary programs. Download the following files from these links
Open up the first executable and run it, when it is done extracting the files it will ask you to type in 'OK' (so do that), and also put in an installation path. Make the installation path C:\GBADev . When these steps are done, click on 'Install', and it should finish just fine.
Next run the second executable, click on 'Next', then select 'I accept the agreement', click next again, select the folder that vham will be installed to (it should already be selected, but if not, put it under C:\GBADev\vham ), then click 'Next' -> 'Next' -> 'Next'-> 'Install' -> Finish'. If all went well you should have your Gameboy Advance development environment all set up and ready to make some games!
Step 2 - Getting started with a new project
[edit | edit source]If you haven't already opened up the VHam environment, go ahead and double-click on the 'VisualHAM' icon on your desktop. Once its open we are going to create a new project, so go ahead and click on 'File' >> 'New' >> 'New Project'. The project type that we are going to make is a '[C++ Empty]' type project, so select that, and then type in a project name and location. It doesn't matter what the project name is, as long as you remember it, and the location can be any folder on the hard drive. (If you can't think of a good project name, or location just input "etchasketch" as the project name and "c:\projects\etchasketch" as the Location).
Step 3 - Getting acquainted with the main.cpp file
[edit | edit source]Once the project has been created you will have in the left hand window 2 files that you can edit, main.cpp and makefile. Do not make any changes to the makefile (it will not be needed in this project), it is only needed for more advanced projects. The only file that we are going to be changing is the main.cpp file. Basically this file is the code that is executed when the game is being run. Go ahead and double click on 'main.cpp' in that left hand pane.
Mostly this file is pretty empty, except for a few lines. All that your game does right now is just display's the HAM logo, and then shows a blank black screen. Let me explain what some of the items in this file are, and what they do.
#include <mygba.h>
This line includes into the program a whole bunch of other functions and declaration that we can use. This is needed unless you want to do everything at a machine level (not pretty)
MULTIBOOT
Allows your game to boot off off a linker cable and not need a cartridge. Not needed for our project, and it can be deleted.
int main(void) {}
Everything within the first and the very last curly brace is the main body of the program. The game starts at the first curly brace, and ends at the last ending brace.
ham_Init();
First statement in the body of the program. Initializes all of the HAM features. Also causes that little 'Created with HAM" logo to show up at the beginning of your game.
while(true) {}
A loop that continues to run over and over again and never finishes. This basically stalls the game and causes it to never finish (Most of the time a console game will finish by the user turning off the power). If the game gets all the way to the end it will restart back at the begning. This statement just keeps things from ever ending.
return 0;
This statement just tells your main() function to exit out with a return code of '0'. Generally this means that the program ended successfully. When this line is executed the game ends, and then restarts back up again (if the power is still on).
Step 4 - Building and running your game
[edit | edit source]This step should be fairly easy to do. Once you have made any of your changes to the main.cpp file and you want to see how they affect the game, simply save your code by clicking on 'File' >> 'Save All', and then compile and run your game by pressing the 'F6' key on your keyboard. You can also build with other options by clicking on the red ! If everything worked correctly, you should have a running game! Congratulations... its not much yet, but soon it will be.
Step 5 - Adding our first additional function to main.cpp
[edit | edit source]Now we are going to get into really adding some useful code into this game. We want our game to show something on the screen, right? Lets add a function that will draw a certain colored pixel to the screen. If you have questions about pixels or functions, I will explain this in class.
Right after the line of code that says ham_Init(); you will need to add the following line of code
ham_SetBgMode(3);
This will set the gameboy hardware into a certain video mode (mode 3) that will give us direct access to the video memory in a sequential memory array (I'll explain that term in class). This makes it easy to put a single pixel on the screen basically.
Now we need to add a function to our program. All functions will be added above the main() function, but below the #include <mygba.h> section. Any function that calls another can only call the functions that are declared above it. main() will be calling all of our other functions, so it needs to be at the bottom. Add the following function to your main.cpp file
//Function that draws a single pixel to the screen void drawPix(int xPos, int yPos, int color) { unsigned short* videoBuffer = (unsigned short*)0x6000000; videoBuffer[(yPos*240) + xPos] = color; }
Now that you have that function, anywhere in your main() function you can call drawPix(). You need to give the function how far to the right of the screen (xPos), how far down on the screen (yPos), and what color to make the pixel (color). I'll explain this is better detail in class. But if example you wanted to draw a single white pixel 50 pixels over and 100 pixels down, you would call in your main() the following line of code
drawPix(50,100,0xFFFFFF);
You can test this, save your project, and then run your program (see step 4 for detail on that).
Step 6 - Saving information with variables
[edit | edit source]With our Etch-A-Sketch program we are going to need to save certain information about where the Etch-A-Stetch pen is, and what color it is currently drawing. This is going to take 5 variables. 2 of them will save where the pen is at (how far over and down it is), and then other 4 for the color (how much Red, Green, and Blue is in the pen, as well as the total pen color).
Right above your function that we just declared, we are going to make 6 global variables. Put the following lines right below your #include <mygba.h> section (but above the other functions).
// Global variables int curX, curY, curColor; u8 cR, cG, cB;
We also need to initialize these variables in your main() function so that the values are set to zero, and not to some random garbage value. Right under the statement ham_SetBgMode(3); put the following lines
curX = 0; curY = 0; cR = 0xFF; cG = 0xFF; cB = 0xFF; curColor = 0xFFFF;
Now you can keep track of your drawing pen from any function by either checking the value of this variable, or you can change the value to something else. We will be doing this later on when we get input from the joypad. In fact this leads right up to our next section.
Step 6 - Getting input from the keyboard
[edit | edit source]What good is a game if you can't control it? Input is actually pretty easy. Its just a matter of checking to see if certain values are true are false. Basically the 'A' button is either being pressed at a given time, or its not. The tricky part is deciding what each of these key buttons being pressed means. Lets make another function right under the drawPix() function that gets input from the joypad, and changes our variables based on that input.
//Gets input from the joypad void query_input() { }
Notice how there is some blank space in between the curly braces. We are going to add some more code in here that is actually going to check the joypad buttons. This is done by using an If() statement. If the statement is true, then the line of code right below will get run, otherwise it will be skipped. Lets say that we want to move the pen down when the down button is pressed. We would use the following 2 lines of code
if (F_CTRLINPUT_DOWN_PRESSED) curY++;
If the down button is being held down when this code executes, the variable curY will be incremented by 1. variable++ means the same as varible = variable + 1 Lets put the following code into the query_input() function
if (F_CTRLINPUT_UP_PRESSED) curY--; if (F_CTRLINPUT_DOWN_PRESSED) curY++; if (F_CTRLINPUT_LEFT_PRESSED) curX--; if (F_CTRLINPUT_RIGHT_PRESSED) curX++; if (F_CTRLINPUT_B_PRESSED) curColor = RGB(--cR, cG, cB); if (F_CTRLINPUT_A_PRESSED) curColor = RGB(cR, --cG, cB); if (F_CTRLINPUT_L_PRESSED) curColor = RGB(cR, cG, --cB); if (F_CTRLINPUT_R_PRESSED) { cR = 0xFF; cG = 0xFF; cB = 0xFF; curColor = RGB(cR, cG, cB); }
This code segment is a little long and ugly, and I will explain more in class about specifics, but all it pretty much does it check the up, down, left, right, B, A, L, and R buttons on the joypad. When those are pressed it sets variables to certain values.
Step 7 - Making the Game loop
[edit | edit source]We've got a function to get input from the user, we have a function to put stuff on the screen, not we just have to put it all togeather by making our main game loop. We are making one more function that will be called on every screen refresh, basically once every 60 seconds or so. Every screen refresh we are going to check the input buttons, and then draw to the screen. Right after your drawPix() and query_input(), but before your main() functions you need to make another function that calls both of those other first 2 functions.
// Function called every screen refresh void vbl_func() { query_input(); drawPix(curX,curY, curColor); }
Pretty simple isn't it? It really is. Most of the work is already being done in the other 2 functions that we made, so there isn't much more work to do in here. The only other thing that we need to do is to call this functions every 1/60th of a second. This can be done by putting in main() after the variable initialization the following code statement
//Starts running the vbl_func every screen refresh ham_StartIntHandler(INT_TYPE_VBL,(void*)&vbl_func);
Now that it is checking the joypad every 1/60th of a second, and drawing your pen to the screen, your Etch-A-Sketch is done! Save the file, build it and run it! There still might be other enhancements that you could add to it (such as stopping the pen from falling off the side of the screen, or adding on screen instructions that explain how to use the game). You have an interactive, and I might add pretty fun, program that runs on a Gameboy Advance system.
Once you've got the basic program running correctly, save it off and back it up, then try making other changes to the program on your own and see if you can make the program a little more unique and personal. Maybe you could make the pen bigger or a different shape than just a single dot, or maybe make the pen spin around in a circle when you press the start button, or any one of a hundred different things.
End notes & Resources
[edit | edit source]- HAM Gameboy Advance Development Web Site
- VisualHAM Web Site
- HAM Basic Tutorial
- "Programming the Nintendo Game Boy Advance: The Unofficial Guide".
- Programming the Nintendo Gameboy Advance the Unoffical Guide (online book in PDF format)
- Complete Source code to this project
- Compiled Binary ROM for this project
- Peter Schraut. "HEL Library". depends on the HAM SDK.