|
Chapter 2 – Setting Up a Project
In this chapter, we will create a directory to do our work, populate
that directory with starting files and configure a makefile to manage
our builds. We’ll also write the SGADE version of the canonical
‘Hello World’ application.
What you need for this chapter
1. the SGADE template makefile
2. Jeff Frohwein’s crt0.s and lnkscript
Create a new directory called ‘BBAdvance’ for the project
and copy the SGADE template makefile and Jeff’s crt0.s
& lnkscript* into it.
Create ‘bin’, ‘data’, ‘include’ and
‘source’ subdirectories in the ‘BBAdvance’ directory.
When you are done, the project directory should look like this:
BBAdvance/ top-level project directory
bin/ sub-directory for intermediate object files
data/ sub-directory for source data (images, etc)
include/ sub-directory for C header files
source/ sub-directory for C source files
crt0.s Jeff Frohwein’s C Run-Time startup code
lnkscript Jeff Frohwein’s linker script
Makefile template makefile
Open ‘Makefile’ with your favorite source editor. Using the
editor, make the following changes to the makefile. Note that the sample
changes reflect the configuration of my machine. The changes for your
machine may be different.
Change the project name definition from ‘Sample’ to ‘BBAdvance’.
This variable is used by the makefile to define the name of the output
GBA ROM file as well as the name of the main source file.
PROJECT = BBAdvance
You may optionally change the project base directory definition to
contain the full path of the BBAdvance directory, though the default
relative path should work in most environments. This variable is used
by the makefile to locate all of the other project sub-directories.
PROJECT_DIR = C:/dev/gba/Projects/BBAdvance
Change the GCC directory definition to contain the full path to your
Devkit Advance installation. This directory should contain four sub-directories:
‘arm-agb-elf’, ‘bin’, ‘include’,
and ‘lib’.
GCC_DIR = C:/devkitadv
Change the Socrates Lib and Include directory definitions to contain
the full path to the SGADE libraries and include files.
SOCRATES_LIB_DIR = C:/dev/gba/SGADE/lib/
SOCRATES_INC_DIR = C:/dev/gba/SGADE/include/
If you are so inclined, you can also change the comments in the makefile
header information to reflect the name of the project.
Save the updated makefile when you have finished with your changes.
Create a new file in the source subdirectory called ‘bbadvance.c’.
This is the game implementation file that we’ll be modifying in
later chapters as we add features to the game. Use your source editor
to add the following code to this file:
#include "Socrates.h"
// tell crt0 that we want multiboot support
int __gba_multiboot = 1234567890;
int AgbMain(void)
{
SoDisplayInitialize(); // initialize the display
// set palette
SoPaletteSetGreyScale(SO_SCREEN_PALETTE, true);
SoMode4RendererEnable(); // change into bitmap mode
SoMode4RendererClear(); // clear the screen
// display something
SoMode4RendererDrawString(10, 230, 10, "Hello World!",
SoFontGetDefaultFontImage());
SoMode4RendererFlip(); // flip message onto display
for(;;) ; // go into an infinite loop
return 0;
}
Before we go on, let’s examine the code that we’ve added
in detail.
The #include statement at the top is the only link you need to access
all of the SGADE functionality in your program. It is a master include
file that includes all of the SGADE module includes.
The “__gba_multiboot” variable must be present if you want
the compiled ROM to support loading over a multi-boot cable, but it
is only half of the required link. The other half exists in Jeff’s
crt0.s file. For multi-boot to work, you must have the “__gba_multiboot”
variable defined in your project and you must have the “__MultiBootInclude”
label defined in crt0.s. To remove multi-boot support, you should comment
out both of these items.
The “AgbMain” function is called by Jeff’s crt0.s
when the ROM boots. It is equivalent to the “main” function
you would expect to find in a regular C program.
The first four calls in AgbMain prepare the GBA to display data in
graphics mode 4. Mode 4 is a bitmap mode with two full image ‘pages’
that can be alternatively displayed. All of the SGADE mode 4 renderer
drawing functions do their work on the hidden or ‘back’
buffer. Because of this, the image they create will not be visible until
it is ‘flipped’ to the front buffer.
The SoDisplayInitialize
call sets the GBA display registers to a known starting state. The SoPaletteSetGreyScale
call then initializes the GBA’s screen palette to a grey-scale
ramp. SoMode4RendererEnable
modifies the display registers to put the GBA into bitmap mode and SoMode4RendererClear
then clears the contents of the back buffer.
Since a blank display isn’t interesting for long, the next two
functions are used to paint something on the display and then show the
created image to the user. The SoMode4RendererDrawString
call in our sample draws the “Hello World!” string on the
display at pixel position (10,10), not going past pixel 230 on the right
edge, using the SGADE default
font. SoMode4RendererFlip
then swaps the front and back buffers to display the result.
Test out your project by running ‘make’ from a command shell
in the BBAdvance directory. If all is well, it should produce a file named
‘BBAdvance.gba’.
You’re on your way! Running this file using your favorite GBA emulator
will produce a screen like the one below.

click here to download the solution
to this chapter
Additions for Standard C Library support
This tutorial won't be using the standard C library, but there are occasions
where it can come in very handy. With this in mind, here are the steps
to include support for it in a project.
First, ensure that you have the library binaries and include files
installed on your PC. In the DevKit
Advance distribution, the library is in the file agb-win-newlib-r4.zip.
In the Makefile, change the L_FLAGS macro to include '-lc' before '-lgcc'.
This tells the linker to look for functions in libc.a (the standard
C library). It must appear before -lgcc since some C library functions
use functions in the GCC library.
L_FLAGS = -lSocrates -L $(SOCRATES_LIB_DIR) -L$(STD_LIB_DIR0) \
-L$(STD_LIB_DIR1) -T $(LINK_SCRIPT_DIR)/lnkscript -lc -lgcc
In your source file, just #include the header files you're interested
in.
Additions for C++ support This tutorial also won't be
using C++, but there's no reason you can't use it in your projects. Here's
what you need to do to get your Makefile to compile a C++ project.
Again, ensure that you have the standard C library binaries and include
files installed on your PC. In DevKit Advance, the C++ support routines
are also located in the agb-win-newlib-r4.zip file.
In crt0.s, uncomment the definition of __CPPSupport.
.equ __CPPSupport, 1
In the Makefile, change the L_FLAGS macro to include '-lg' and '-lc'
before '-lgcc'. This tells the linker to look for functions in libg.a
(the C++ library) and libc.a (the Standard C library).
L_FLAGS = -lSocrates -L $(SOCRATES_LIB_DIR) -L$(STD_LIB_DIR0) \
-L$(STD_LIB_DIR1) -T $(LINK_SCRIPT_DIR)/lnkscript -lg -lc -lgcc
Move $(PROJECT).o from the definition of the O_FILES_FROM_C macro to
the definition of the O_FILES_FROM_CPP macro.
O_FILES_FROM_C =
O_FILES_FROM_CPP = $(PROJECT).o
Uncomment the CRTBEGIN_O and CRTEND_O macros.
CRTBEGIN_O = $(STD_LIB_DIR0)/crtbegin.o
CRTEND_O = $(STD_LIB_DIR0)/crtend.o
In your main source file, create an entry point named “main”
instead of “AgbMain”. Also, ensure that your project source
file(s) end with '.cpp', '.cxx', or '.cc' (not just '.c').
With these changes in place, you should be able to compile and run projects
using C++.
Footnotes
* The provided zip file is Jeff's offical version
1.28. It can also be found on his web site at www.devrs.com/gba/ccode.php#cmisc.
|