Tutorial  Updated

DS Programming for Newbies!

3Lwpv.png

Table of Contents:

Introductory Chapters:
  1. Preparing the environment
  2. Variables!
  3. Functions!
  4. Operators in C
  5. Conditions - if/else Statements and switches
  6. Looping - for() and while() Loops
  7. Containers of Variables - Arrays and Structures
Introduction to DS Hardware:
  1. RAM and VRAM
  2. OAM and 2D Sprites
Practical use of libnds:
  1. Input: Keys and the Touchscreen
Practical Use of NightFox Lib:
  1. NightFox Lib Integration
  2. 2D MODE-0 Part 1 - Tiled Backgrounds
  3. 2D MODE-0 Part 2 - Tiled Sprites
Excercises:
  1. Your first program!
  2. MODE-0 Tiled Backgrounds Example
  3. MODE-0 Tiled Sprites Example
  4. Our very first game: Tic Tac Toe!
Additional Utilities:
  1. GRIT


:download: PDF Version maintained by CannonFoddr available on FileTrip HERE!

:download: PDF Version maintained by Pomegrenade GBAtemp Mirror HERE!




Preface


Hello and welcome! If you are reading this then it’s likely that you’re interested in getting to know more about programming for the Nintendo DS! If you are not, then you likely took the wrong turn, but let’s not get into that. Let’s also start with establishing one important thing – as the title suggests, this is a “From Zero to Hero” guide. If you are an experienced programmer then it is likely that you will not benefit from it much, if at all. It is going to introduce the very basics to users who have never even seen a compiler before and never coded in their life – stuff that you probably already know and aren’t interested in anymore. You are however still welcome as this is my first tutorial and will likely require a certain degree of proof-reading, plus, you may of course have useful suggestions! Keep in mind the target audience though, I’m doing my best not to introduce complicated concepts early on. If you’re not an experienced programmer or never programmed at all, this is a great place to start!

I’ve seen many guides approaching this subject – some were more helpful, some were rather vague, but there is one thing that was common in all of them, and it became apparent to me that something has to be done about it. The guides I’ve seen so-far are dedicated to users who are familiar with programming and only require an introduction to the DS environment, none of them are actually “tutorials” from the ground up. Does this mean that a non-experienced user simply cannot program for the DS or should not begin his adventure with programming on this exact platform? No, it does not! In fact, the DS is likely the easiest platform to program for when it comes to consoles – libnds is really not that hard to wrap your mind around and there are numerous libraries out there that facilitate programming for it even further. You probably want to ask: “If it’s so easy, why do You think it requires some sort of an explanation? The libraries are well-documented, do you expect the readers to be dill-wits who can’t follow simple examples?” and the answer to that is “No, in fact, I do believe that everybody is capable of programming, however one has to learn and acquire some basic programming habits and have some practice in C to be successful at it” and this is exactly the main goal of this tutorial. Depending on the interest shown by users and my workload at Uni this may or may not be a full-featured guide, however I promise that I will at least try to keep it up-to-date and expand upon it from time to time.

Now that the purpose is established, let’s move on to the juicy parts! I hope you will enjoy learning together and in case of any questions or suggestions, do write! Dear readers, keep in mind that the first few tutorials will be an incredibly rapid course in C, applicable to any type of programming, not just for the DS! We won’t be compiling much until this material is covered and thoroughly understood! So… Let’s get it on!
 
Last edited by Foxi4,

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,819
Country
Poland
Can Someone help me out? I cant build a .plg file with the build.bat because i get a ton of errors.

I tried to build it from an backup of the source - Errors
Local Copy - Errors
Official Plugin with source from RyDog - Errors

I always get a lot of "undefined reference to new_enty_with_note"
But how is it possible that i can´t build the plugin with original source files?
Am I missing something? Devkit and Phyton is installed...
You don't need Python. What exactly are you trying to compile? Which example? Are you sure you're in the right place? :)
 
  • Like
Reactions: zoogie

toberkel

Well-Known Member
Member
Joined
Nov 21, 2016
Messages
184
Trophies
0
Location
Germany
XP
164
Country
Germany
You don't need Python. What exactly are you trying to compile? Which example? Are you sure you're in the right place? :)
Do u have discord? I could send u a few screenshots ther...
I try to build a plugin but whenever i use the build.bat i get a lot of error codes...
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,819
Country
Poland
Do u have discord? I could send u a few screenshots ther...
I try to build a plugin but whenever i use the build.bat i get a lot of error codes...
You are most definitely in the wrong section. This is a DS programming tutorial, you seem to be having problems with the Switch - I suggest looking there.
 
D

Deleted_501387

Guest
Yeah, there's no more wizard unfortunately, you have to compile with MAKE.exe from the devkit as usual. You might want to switch from Visual Studio to Notepad ++ as well.

in my devkitPro folder there is no file named MAKE.exe. am i missing something or what?
 
Last edited by ,

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,819
Country
Poland
Thanks! It's admittedly a little out-of-date at this stage, but the core concepts still apply. I'm not sure if NightFox Lib is still maintained, so as you progress through it you may find yourself needing to use pure libnds, which is admittedly a better option if you intend to write serious code.
 

PolyMars

Member
Newcomer
Joined
Feb 29, 2020
Messages
18
Trophies
0
Age
21
XP
245
Country
United States
Thanks! It's admittedly a little out-of-date at this stage, but the core concepts still apply. I'm not sure if NightFox Lib is still maintained, so as you progress through it you may find yourself needing to use pure libnds, which is admittedly a better option if you intend to write serious code.
I haven't really wrapped my head around creating sprites with pure libnds yet, but now that I understand the basics of DS programming with NFLib I should get there soon enough! Even when using NFLib, I was pretty lost on how to create proper sprites for my dumb Flappy Bird clone before I came across your tutorial, so thank you so much :bow:
 

Attachments

  • qEYaJx.png
    qEYaJx.png
    4.3 KB · Views: 191
  • 8r6bYk.png
    8r6bYk.png
    5.9 KB · Views: 185

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,819
Country
Poland
I haven't really wrapped my head around creating sprites with pure libnds yet, but now that I understand the basics of DS programming with NFLib I should get there soon enough! Even when using NFLib, I was pretty lost on how to create proper sprites for my dumb Flappy Bird clone before I came across your tutorial, so thank you so much :bow:
That looks like fun, well done!

Sprites converted with GRIT should work exactly the same in pure libnds as they do in NFlib - you just need to load the palette file correctly in order for them to display on the screen - there's a bit more fumbling and more setup involved, but in the end it's cleaner and closer to hardware. I suggest having a look at the wealth of examples that come with the devkit - they'll take you through everything you need to know about the DS's sprite system. You seem to have the groundwork already covered, I'm glad that I was able to help. It's a bit of a shame that I lacked the foresight to backup all the software I used when making this tutorial, but I guess hindsight is always 20/20. :)
 
D

Deleted member 513667

Guest
@Foxi4 Hey! I was learning from your tutorial (really great btw!) and needed some help with GRIT when making a background.
I converted my image to an 8bit bmp, but when i put it through grit (convert_background.bat), i get the image, but 1 colour missing. Any help? Thanks!
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,819
Country
Poland
@Foxi4 Hey! I was learning from your tutorial (really great btw!) and needed some help with GRIT when making a background.
I converted my image to an 8bit bmp, but when i put it through grit (convert_background.bat), i get the image, but 1 colour missing. Any help? Thanks!
That'll be your transparency, if I recall correctly. The first colour in the palette file will be transparent - I think there's a way to pre-set it to something. I'll have to re-check it though, it's been literally years since I wrote this.
 
D

Deleted member 513667

Guest
That'll be your transparency, if I recall correctly. The first colour in the palette file will be transparent - I think there's a way to pre-set it to something. I'll have to re-check it though, it's been literally years since I wrote this.
In GIMP you can manually edit the palettes of indexed bitmaps, so I always set the first slot of the palette to be magenta (#FF00FF), even if my background doesn't use it, to fix that issue.
View attachment 201367
Thanks!!!!!!! Helps a lot!
 
  • Like
Reactions: PolyMars

Just_A_Musician

Member
Newcomer
Joined
Apr 9, 2020
Messages
11
Trophies
0
Age
19
XP
81
Country
United States
Introductory Chapter 0: Preparing the Environment


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…

Introductory Chapter 1: Variables!


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”.

Introductory Chapter 2: Functions!


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!

Exercise #1 - Your first program!


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!

So, like, none of the links for the software actually work, at least not on windows 10. Are there up to date links, or am I screwed?
 

PolyMars

Member
Newcomer
Joined
Feb 29, 2020
Messages
18
Trophies
0
Age
21
XP
245
Country
United States
You can get NightFox's Lib here, and this wiki page explains how to install and set up the latest devKitPro toolchain. As for the Drunken Coders plugin/VS Code editor, they're outdated and not necessary. Instead, you can use Programmer's Notepad (included with devKitPro) as your code editor and compile your code with the command line (or, if you're using NFLib, the included batch file).
 
  • Like
Reactions: Foxi4

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,819
Country
Poland
So, like, none of the links for the software actually work, at least not on windows 10. Are there up to date links, or am I screwed?
As mentioned above, you don't really need the wizard. 8 years ago when I originally wrote this I recommended using VS with the Drunken Coders template because it made for a good development environment, but both are entirely optional. After many years of messing around with code I've switched entirely to various flavours of Notepad - Programmer's Notepad comes bundled with devkitPro, Notepad++ is also a good choice. Sadly I didn't backup any of these old resources simply because I myself switched away from them, so I can't offer a reupload.
 
  • Like
Reactions: PolyMars

safendrd

Member
Newcomer
Joined
Apr 20, 2020
Messages
13
Trophies
0
XP
253
Country
Italy
Hello! I've being trying to make a Hello World program with an FPS counter built in just for fun, but I have this problem when compiling the program:

"expected primary-expression before '.' token" (see attached file)

The RTC seconds are stored into the "seconds" variable situated into the "RTCtime" struct (system.h library).

Do you have any fixes for this? Thanks in advance!
 

Attachments

  • Error.jpg
    2 MB · Views: 173

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Psionic Roshambo @ Psionic Roshambo: https://www.youtube.com/@legolambs