Alright then! We’ve established our goal, it is time to make the first steps towards it! For the duration of this course we will be using the C language which is versatile and simple enough to understand. We’ll program in the Visual C++ Express 2008 and we’ll be using NFLib by NightFox and Co. as our graphics library so that graphics do not impede our progress, but we’re miles before getting there. First and foremost, we need to start up our download queue, and we’ll be needing plenty-fancy things!
Firstly, we of course need the devKit Pro toolchain, available here:
http://sourceforge.net/projects/devkitpro/
Next, we need to get our hands on the code editor:
http://go.microsoft.com/?linkid=7729279
We will also need Drunken Coders’s Wizard to add a Nintendo DS application (among others!) as a project type:
http://pern.drunkencoders.com/download-wiz/
Finally, we’ll download NightFoxLib:
http://sourceforge.net/projects/nflib/
Once all the files are downloaded, proceed to installing them, starting from devKit Pro (preferably on C:\), next the Visual C++ Studio Express 2008, the Drunken Coders’s Template Wizard and finally NightFox Lib (preferably in the devKit Pro directory).
Now we have our programming environment ready! Exciting, isn’t it? Well, not quite. Why? Because now we have to move onto the Introductory chapters of this guide – they may be boring and taxing but without them we will not be able to really program anything as everything you will be reading from now on will sound like black magic before this knowledge sinks into you, at least partially. Thus, without further ado, we move onto…
To even have a chance at programming something, we need to know what we’ll be dealing with. Introductory Chapter 1 will introduce the first important subject – Variables, your main weapons when it comes to programming.
So, what is a Variable? Well, in layman’s terms, a variable can be just about “anything” – it can be a number, a character, literally anything, but to simplify it, we’ll say it is a value, a piece of data that is kept in the console’s memory for later use. In most
tutorials you would see a link to a Wikipedia article or a reference to a book that will introduce you to the subject – not here. We want to get from Zero to Hero and we want to get there fast, don’t we? As far as we’re concerned, we could possess all the knowledge about the variables and we still won’t be able to use them anyways! I will only pass onto you the knowledge that will actually be relevant to you, so bear with me.
Let’s start with describing how to Declare a Variable:
Type Name = Value;
Your typical variable has four identifying features – a scope, a type, a name and a value. First and foremost we will tackle types, as they determine how we will actually use a given variable.
We can divide our variables into 3 main groups – Integers, Booleans and Chars. Those can be Signed or Unsigned (except Booleans), plus Integers may range from 8 to 32 bit ones (even 64 on PC’s, but let’s not go ahead of ourselves). Sounds like black magic so-far? Good, cause we’re going to explain what all that means, starting from types and their properties:
Signedness is the first property we will discuss. One could write a whole elaborate essay on the differences between signed and unsigned variables. What you need to know is that Signed variables range from negative values throughout 0 and positive values while Unsigned ones range from 0 upwards. That’s it, really. That’s all you need to know!
Next, we’ll tackle the lovely Integers. As I said, Integers on the DS may consist of 8, 16 or 32 bits, but what does that mean, exactly? Well, it means what range of values a variable will be able to carry! For example, an 8-bit integer will have a lenght of 255, meaning it will range from -128 to 127 when signed and from 0 to 255 when it’s unsigned. A 16-bit one will have a length of 65,535 while a 32-bit one, a length of 4,294,967,295.
To use them, we will have to learn how to declare them! The symbols used to refer to those integers are u for Unsigned, s for Signed, followed by the length in bits, for example “u8” or “s16”.
Next we have Booleans. There’s really not much to say about them other then they may hold only two possible values – “true” (1) or “false” (0). We will mostly be using them for simple switches and there’s no point in dedicating any more time to them. The symbol used to declare Booleans is “bool”.
Finally, we have chars… Chars will mostly be used to hold characters or numbers, but they are much more versatile then that. By “holding anything” I really meant that you can use those variable to hold “anything”. From text to graphics and sound, arrays of chars will be your tool of choice. The symbol to declare chars is “char”.
Now that types have been discussed, we can move to Scopes, and we’ll discuss only two: Global and Local. A Global Variable is declared outside the main block of the program, thus can be called anywhere within it while a Local Variable is declared within a function, thus may only be used within that function. I’m sounding vague, huh? Functions? Blocks? What am I talking about? Well, let’s get right onto that in the Introductory Chapter 2, as I don’t think the “name” part needs any explanation other than “don’t use special signs or spaces when naming a Variable”.
So, what is a Function, you ask? Well, a Function in layman’s terms is a set of instructions that the program is supposed to carry out. How does a function look like, how do we declare it you ask? Let’s see the declaration for ourselves:
Type Name(TypeOf Argument, TypeOf Argument2){ … };
That… looks incredibly complex, doesn’t it? Let’s cut it into pieces, shall we?
Where “Type” you put either “void” if you don’t really want the function to return any value for you, just carry out the instructions. If you do want it to return some sort of a value or data, you can specify it using the previously described Types – that way, you will be able to assign the value returned to a given variable! Snazzy!
The Name can be just about anything, but without spaces and really fancy special signs.
As far as Arguments are concerned, there can be as many as you like and they can be any type of a variable you want.
How do we call our declared function? Well, we simply do this:
NameOfTheFunction(Value1, Value2);
Simple!
Just to practice, let’s build our very first simple function, shall we?
Code:
s16 Adding(s16 Number1, s16 Number2){
s16 Result=Number1+Number2;
return(Result);
}
So, what does this function do? Well, it adds the value specified as Number1 to the value specified in Number2 and returns its number as shown by Result!
So, if we do this:
Code:
s16 Number3;
Number3=Adding(2, 2);
Our function will assign the value “4” to the declared variable Number3. Neato, huh? Of course we’re not going to build functions with *that* simple functionality but hey! We’re just starting, right?
Before we can actually create any fun functions, we’ll have to learn a bit about operators and built-in C functions… but I’m feeling like you guys are yawning at this point – so much new-found knowledge and we can’t use it anywhere! Annoying, isn’t it? Well…
Let’s do something else, shall we? Let’s build our very first application! Oh, the excitement! First and foremost though, we will analyze the template we’re given from libnds so that we know where to put what, hmm? Your minds open? You’re fingers ready? This is the part you were all looking forward to, so let’s do this!
Open up Visual Studio C++ Express, start a new project and select the DS as your platform of choice via the wizard – the default settings will do. Once you’re done, you will be able to browse the contents of your Solution using the table of contents situated on the left-hand part of the screen. Right now you only have the Source file called “template.c”. Let’s open it! You will likely see this as the result:
Code:
/*-----------------------------------------------------
Basic template code for starting a DS app
-----------------------------------------------------*/
#include <nds.h>
#include <stdio.h>
int main(void) {
consoleDemoInit();
iprintf("Hello World!");
while(1) {
swiWaitForVBlank();
}
}
Wow wow wow, that’s alot and sooo fast! Let’s look through this quickly, shall we?
Every program is essentially divided into three main sections: the Includes, the Declarations and Defines and finally the main(); Function. We will discuss them all briefly. I will also explain the three functions that appear in this code so that they’re crystal clear.
#include is a directive referring to any files that may be included in the project. It’s vital to know that #include files will *always* be in our RAM – their content can be accessed anywhere throughout our program! This will turn out to be very useful when organizing your work and resources later-on, so remember it! The two files included are nds.h, which is the libnds library and stdio.h, which is the Standard Input/Output library of C and C++. The Angle-Brackets <> indicate that the compiler will search for the file using it’s specified INCLUDE path as well as the parent directory of your program, were we using simple quotation marks “”, the compiler would attempt to find it only in the parent directory, but more on that later.
Normally after the #include we would start putting our Global declarations, every variable declared there will be treated as Global. Keep that in mind!
This basic template has no variables, but let’s add one, just for the heck of it! Scroll up and put your declaration right before the main(); function. Let’s say…
char MyName[25]=”Put your name here, silly!”;
Can you tell me what kind of a variable that is? Yep, you are absolutely right! Great attention span! It’s indeed a char, its name is “MyName” and its value is… well, whatever your name is! What’s with the weird number in the brackets, you ask? Well, one char can only hold one character – with this number, our variable is now an Array, otherwise known as String, of the length of 25 characters – that way, we can put more characters in, but more on that in the later chapters about Arrays. In any case, good job! Remember about the “;”, without putting it at the end, the compiler will not know when the line of input ends and will return an error, so declare carefuly! Let’s move on.
Lines starting with “//” or enclosed between “/*” “*/” are called Comments – the compiler ignores them, but they are helpful to mark important parts of your code.
Finally we move on to the int main(); the most interesting part we’ll tackle today.
main(); is effectively the main function of the program – whatever is supposed to happen is placed in it. It is divided into two main parts – the part before while(1) and after it. We’ll talk about the while loop later, for now, all we need to know is that whatever is before while happens once, whatever comes within its brackets happens once each frame (the DS works at circa 60 frames per second, so the maths here are clear).
Before while(1) we have two functions, let’s have a closer look to know what they are:
consoleDemoInit(); is a function built-in libnds, it will launch a DOS-like command line to which you will be able to output text. Nothing more, nothing less, really.
iprintf("Hello World!"); is a function used for printing text. It prints it directly into the console, the text printed is placed between the quotation marks. Simple!
Let’s head to while, shall we?
It contains only one function - swiWaitForVBlank(); which, as the name implies, wait for a VBlank, meaning the end of a frame. You will have to put this function at the end of your main, always!
So, from what we’ve read so-far, this program should:
1. Initialize the console.
2. Print Hello World! On the screen.
Let’s see if it does that, shall we? Select “Build” from the context menu at the top of the screen, then hit “Build Solution”, alternatively just hit “F7”. This will begin the makefile operations and compile your very first .nds file. Excited? You should be!
Once Building Operations are finished, you will be able to read where the file was saved at the bottom part of the screen. No surprise there – it’s in the folder you specified when creating the Project.
Open that folder – the .nds file should be there. Provided you have an .nds emulator, you will be able to launch it, and… magic! It does what it’s supposed to!
I can hear you nagging “but what about my Variable?!? I want it to do something that wasn’t in the template, you’re a lame teacher!” and that breaks my heart. Would I desert you? Would I? Never!
Let’s spice up the code a little bit, hmm? Let’s make this program specifically about *you*.
Scroll back up where you declared your first variable and declare another one, like this:
char Text[100];
We already know it’s a string of characters with a specified length, but why No value? Well, it means that the string is empty – we can put data into it later-on though. This is called a “buffer” – a place dedicated in RAM for us to input data into.
Let’s move onto the function though, shall we? Before the iprintf(), we’ll add another fun function that is commonly used with strings:
sprintf(Text, “Hello World! My name is %s!”, MyName);
Okay, confusing, I know. Explaining now. sprintf(); is a function used for formatting strings – you select a destination buffer, then you write the format within the brackets, finally you write which variables should be used to format it. In this case, we are inserting the string MyName using “%s”. The final result should be “Hello World! My name is Whatever you specified as your name”. That’s neat, isn’t it?
Now, let’s modify the iprintf to use our text. All you need to do is this:
iprintf(Text);
Now, rather then Hello World!, the text printed will be whatever has been put in the buffer Text (hence the lack of brackets). Now, what you should have is this:
Code:
#include <nds.h>
#include <stdio.h>
char Text[100];
char MyName[25]="Foxi4";
int main(void) {
consoleDemoInit();
sprintf(Text, "Hello World! My name is %s!", MyName);
iprintf(Text);
while(1) {
swiWaitForVBlank();
}
}
Ready? Steady? BUILD! So… does it work? Well, why shouldn’t it?
You’ve just built your very first program for the DS, congratulations! Admittedly it’s simple, but with some dedication, soon enough you’ll be a pro at this! One thing is for sure, you’re no longer a Zero, you moved onto... 0,1… So there’s still a road ahead of you!
This concludes our first day, thank you for reading and I hope you all enjoyed! If you have any questions whatsoever or any suggestions about the format of these lessons, please, comment below!