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,815
Trophies
3
Location
Gaming Grotto
XP
29,768
Country
Poland
Could you put in an example for the touchscreen use? Like:

if(Touchscreen is touched on a location)
{
This will be happen
}

Your tutorial really good! Keep going ;)
Oh, that's really easy! We already know how to read from the Stylus structure - touch.px and touch.py give us the current Stylus position. We also know how to make statements and how to connect them. For those who are new to programming, it's good to think of the conditions in plain language or draw a diagram of what the program is supposed to do. You want a given reaction when the Stylus is held in a given area, so why not create a rectangular area that would trigger it? For example, if the Stylus is held between Pixel 0 and Pixel 24 vertically and Pixel 0 and Pixel 24 horizontally - this would create a 25x25 square. We know the conditions - now we need to code them:
Code:
if(KEY_TOUCH & keyHeld() && //If the Stylus is Held down...
touch.px >= 0 && //If the returned pixel is 0 or higher...
touch.px = 0 && //If the returned pixel is 0 or higher...
touch.py = X1 && touch.px = Y1 && touch.py
 

frezziii

Member
Newcomer
Joined
Aug 14, 2012
Messages
10
Trophies
0
XP
3
Country
Gambia, The
Thanks, it's pretty simple but effective....I've already programed for the NDS....years ago xD But I've used Palib and the program wasn't written very well :3

Edit:
Code:
bool IfStylusInArea(s16 x1, s16 x2, s16 y1, s16 y2){

touchPosition touch;
scanKeys();
touchRead(&touch);

if(KEY_TOUCH & keysDown() && touch.px >= x1 && touch.px = y1 && touch.py
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,815
Trophies
3
Location
Gaming Grotto
XP
29,768
Country
Poland
Thanks, it's pretty simple but effective....I've already programed for the NDS....years ago xD But I've used Palib and the program wasn't written very well :3

Edit:
Code:
bool IfStylusInArea(s16 x1, s16 x2, s16 y1, s16 y2){

touchPosition touch;
scanKeys();
touchRead(&touch);

if(KEY_TOUCH & keysDown() && touch.px >= x1 && touch.px = y1 && touch.py
 

BassAceGold

Testicles
Member
Joined
Aug 14, 2006
Messages
496
Trophies
1
XP
441
Country
Canada
Most of those are actually not errors. You placed:

Code:
touchPosition touch;
scanKeys();
touchRead(&touch);
...within the function - you're not supposed to do that. By placing them inside a function that's not main(), you will deactivate scanKeys() and touchRead() the moment the function returns 0 and thus deactivates. Moreover, you are re-declaring the variable touch each time you activate the function and thus waste resources. All that is supposed to be at the beginning of the main() function in their respective places as shown in the tutorial about Input - correct it. ;)

You also edited keysHeld to keysDown - the function will only read the first touch, it will not read swiping. If that's your intention - fine. If not, change that as well. :)

The only error I see in my code is not closing the function and opening else - I did that accidentally and I fixed it now - thanks for picking that one up! ;)


Code:
touchPosition touch;
scanKeys();
touchRead(&touch);

This added to the function is redundant if you are checking keys outside the function. Otherwise, it is fine if that is the only input you are checking at a specific time. The function should not affect any previous stored results collected by these functions and will work fine for the current frame.

Declaring variables in a function is not really a bad thing or as much work as you might imagine. Declaring a variable on the stack and accessing it is usually much faster than accessing a globally declared variable, and the stack variable will no longer exist when the function exits itself. If there does happen to be a performance hit, it is very minimal. If you are actively avoiding declaring variables in functions for such a small performance gain, then your premature optimization will lead into less readable code over time.

In reality there is no "proper place" for variable declarations as it is entirely dependent on its needed locality and size.
 

frezziii

Member
Newcomer
Joined
Aug 14, 2012
Messages
10
Trophies
0
XP
3
Country
Gambia, The
Maybe so?:
Code:
#include 
#include 
touchPosition touch;

bool IfStylusInArea(s16 x1, s16 x2, s16 y1, s16 y2){

if(KEY_TOUCH & keysDown() && touch.px >= x1 && touch.px = y1 && touch.py
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,815
Trophies
3
Location
Gaming Grotto
XP
29,768
Country
Poland
Declaring variables in a function is not really a bad thing or as much work as you might imagine. Declaring a variable on the stack and accessing it is usually much faster than accessing a globally declared variable, and the stack variable will no longer exist when the function exits itself. If there does happen to be a performance hit, it is very minimal. If you are actively avoiding declaring variables in functions for such a small performance gain, then your premature optimization will lead into less readable code over time.

In reality there is no "proper place" for variable declarations as it is entirely dependent on its needed locality and size.
Oh, I know the difference between a local and global variable and I know their pros and cons Bass - I just honestly believe that the application should scan for Input at all times to prevent locking itself out in a point of no return - these two functions "should" be in main() rather than in a separate function just to have a method of input. If he suddenly decides to stop using the function, he will essentially lock his program - no input equals no way of influencing what's going on, right? ;)

As far as re-declaring is concerned, it does waste a fraction of resources since it allocates and re-allocates resources every single time and then destroys the space used upon function termination, and if it's done every single frame, it can be a bit silly to do so. I assumed that this is what this function would have to do to keep the program stable and responsive (meaning, read input). I choose to use globals for variables that are used at all times and locals for variables that are really only needed within a given function or variables that I need returned from a function. I think that's the most sensible option, but everyone to their own tastes I suppose - I'm just trying to teach people good habits. :)

As for "having a lot of globals declared", isn't that what header files are for? Each "module" of the application can have its own declarations in its own header file for consistency's sake. ;)

Maybe so?
*code snip*
Perfect! :) I like that a lot - it's consistent and easy to read.
 

BassAceGold

Testicles
Member
Joined
Aug 14, 2006
Messages
496
Trophies
1
XP
441
Country
Canada
Oh, I know the difference between a local and global variable and I know their pros and cons Bass - I just honestly believe that the application should scan for Input at all times to prevent locking itself out in a point of no return - these two functions "should" be in main() rather than in a separate function just to have a method of input. If he suddenly decides to stop using the function, he will essentially lock his program - no input equals no way of influencing what's going on, right? ;)

As far as re-declaring is concerned, it does waste a fraction of resources since it allocates and re-allocates resources every single time and then destroys the space used upon function termination, and if it's done every single frame, it can be a bit silly to do so. I assumed that this is what this function would have to do to keep the program stable and responsive (meaning, read input). I choose to use globals for variables that are used at all times and locals for variables that are really only needed within a given function or variables that I need returned from a function. I think that's the most sensible option, but everyone to their own tastes I suppose - I'm just trying to teach people good habits. :)

As for "having a lot of globals declared", isn't that what header files are for? Each "module" of the application can have its own declarations in its own header file for consistency's sake. ;)

You may know how things work, but the people who read this thread may not. I feel it is best to keep information as acurate as possible to prevent confusion further along someones education. Good coding practice seems to be very subjective, thus, one should refrain from suggesting practices unless they absolutely know what they are doing.

Everyone's opinions on optimization are different, but there are many things one should keep in mind. One example, redeclaring the touchPosition struct every frame; Its performance hit is overshadowed by the touchRead function that is also called every frame. You are basically saving nothing by removing the struct declaration while making the stylus in area function unsafe to use in certain situations where one may not be detecting more than stylus input. Perhaps a function such as:

Code:
bool StylusInArea(touchPosition *t, s16 x1, s16 x2, s16 y1, s16 y2){
return(KEY_TOUCH & keysDown() && t->px >= x1 && t->px py >= y1 && t->py
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,815
Trophies
3
Location
Gaming Grotto
XP
29,768
Country
Poland
I see what you mean - yes, this is a newbies tutorial and yes, I do owe a clarification.

Your approach is interesting since it does have a touch position argument, hence it's practicaly fool-proof. What I meant to say by having touch position global rather than internal, closed in a function was simply a matter of access - if it's locked in a function, it will be available in that function only, unless it is returned. Obviously it cannot be returned since we're already returning something else, plus, the type would be incorrect.

I'd rather see Input/Output variables in main merely because these are things that should be accessible anywhere within the program - this nullifies the need of pointing at the values or inputting them as arguments.

I'm not saying that every variable should be a global - that's imbalance as well since even if you free() it and even if you are not allocating space to it, it's still there when you're not using it cluttering memory for no reason. I wanted to say that variables, strings and structs used by a myriad of other functions, such as those related to input or those which hold vital data such as graphics should be global due to their nature.

It's true that these are very subjective matters and every programmer develops his or her own style as they learn, but it's good to know why some should be global, why some can be local and what are the advantages and disadvantages of both.

As for the case of re-declaring touchPosition Touch; each frame, I said that it's wrong merely because it's unnecessary. It leaves a small memory footprint, yes. It takes up less resources than scanning for keys or reading stylus input, yes. Thing is, it's unnecessary.

A penny saved is a penny earned, except here, it's in reverse. When you have a little bit of clutter in many areas, altogether it may impact final performace and you may end up between a rock and a hard spot, having to re-code large sections of code just to fix a minor issue, Being tidy is a good thing. ;)

Young programmers should know even of the smallest things that are wasteful and should be told why. If wastefulness can be avoided, it should be avoided a I'm glad that we're having this discussion here so that they can view it from different angles and I'm glad that you're visiting this thread for proof-reading.

So to conclude - when you can make a variable Local, make it Local - it will terminate and flush from memory the moment the function finishes its job and free up resources which can be scarce on platforms like the DS. If you will use a given variable throughout the program multiple times or all the time or if the function is supposed to work in the background, declare it as a Global. If you feel that certain variables should be kept separately in a module-like fashion (about which we will learn later on), keep them in separate, dedicated Header files and include them into your source.

Is that acceptable? ;)
 

BassAceGold

Testicles
Member
Joined
Aug 14, 2006
Messages
496
Trophies
1
XP
441
Country
Canada
As for the case of re-declaring touchPosition Touch; each frame, I said that it's wrong merely because it's unnecessary. It leaves a small memory footprint, yes. It takes up less resources than scanning for keys or reading stylus input, yes. Thing is, it's unnecessary.

A penny saved is a penny earned, except here, it's in reverse. When you have a little bit of clutter in many areas, altogether it may impact final performace and you may end up between a rock and a hard spot, having to re-code large sections of code just to fix a minor issue, Being tidy is a good thing. ;)
I'm not saying that it is not unecessary, I just think your reason if based purely on optimization is a bit misplaced. Code is only as fast as the slowest component, and little things like these will not be the slowest part of a program by a long shot. If you want to improve performance, start looking at the larger systems rather than ripping out unecessary variables that may (or may not) decrease readability. It is more advisable to program first for readability, and then optimize once the code is figured out.

I'd rather see Input/Output variables in main merely because these are things that should be accessible anywhere within the program - this nullifies the need of pointing at the values or inputting them as arguments.
That depends on how modular you want your code to be. Porting code over to a different platform in your method would require a lot of work and searching through code to fix input. By passing input data, it can be easily swapped out for a different format without rewriting everything.


So to conclude - when you can make a variable Local, make it Local - it will terminate and flush from memory the moment the function finishes its job and free up resources which can be scarce on platforms like the DS. If you will use a given variable throughout the program multiple times or all the time or if the function is supposed to work in the background, declare it as a Global. If you feel that certain variables should be kept separately in a module-like fashion (about which we will learn later on), keep them in separate, dedicated Header files and include them into your source.

Is that acceptable? ;)
The goal here is to make your code as readable as possible, within reason.

Young programmers should know even of the smallest things that are wasteful and should be told why. If wastefulness can be avoided, it should be avoided a I'm glad that we're having this discussion here so that they can view it from different angles and I'm glad that you're visiting this thread for proof-reading.
Wastefulness should be avoided, but again we are dealing with people who are still learning and may have different ideas on what looks wasteful or not.

For a tutorial, I think its goal should be to be written as least subjective as possible. The purpose of this tutorial is to introduce people to basic programming concepts; Such authority should not, and need not display opinion as fact. If people wish to further their knowledge on optimization and better coding practices, there are plenty of pages online that they can read up.

That being said, I do believe code examples should be written to the top expected standards of readability and portability.
 

shoyrumaster11

Well-Known Member
Member
Joined
Dec 12, 2011
Messages
296
Trophies
0
Age
25
Location
With the Thunderjuggling Cugglecats!
XP
343
Country
I'm sorry if this is unrelated to the tutorial that's been written here but, do any of you feel annoyed by people saying that the Nintendo DS Scene is dead? I mean, I know it's going through some hard times but, there's been some pretty recent homebrews out for the DS. I cannot remember the most recent one unfortunately. Than there's my signature which is announcing a project that I should get back to work on. Which is basically a tech demo stylized as a chiller music video that is made with a computer. And due to what I heard just today on GBAtemp, I think the scene is still alive.
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,815
Trophies
3
Location
Gaming Grotto
XP
29,768
Country
Poland
I'm afraid that Nintendo DS Scene *is* sort-of dead - the most prominent of coders moved on to stronger platforms or are busy hacking the 3DS and the Vita - now, it's only in our hands whether we let the DS Scene die or make it prosper. Coding for the DS is incredibly pleasant and easy, it's one of the best platforms to start on since it's been hacked through and through - the capabilities of the homebrew devkit are incredibly close to the real SDK. It's really worth to take some time and have a look at what you can do. :P

To clarify, it has a chance to thrive as long as we don't have proper hacks on current-gen consoles. :P
 

frezziii

Member
Newcomer
Joined
Aug 14, 2012
Messages
10
Trophies
0
XP
3
Country
Gambia, The
I'm afraid that Nintendo DS Scene *is* sort-of dead - the most prominent of coders moved on to stronger platforms or are busy hacking the 3DS and the Vita - now, it's only in our hands whether we let the DS Scene die or make it prosper. Coding for the DS is incredibly pleasant and easy, it's one of the best platforms to start on since it's been hacked through and through - the capabilities of the homebrew devkit are incredibly close to the real SDK. It's really worth to take some time and have a look at what you can do. :P

To clarify, it has a chance to thrive as long as we don't have proper hacks on current-gen consoles. :P

The NDS dev scene is not dead xD My latest project: http://frezziii.blog...label/VocableDS :D
 

Boy12

NOT a new member!
Member
Joined
Mar 8, 2012
Messages
536
Trophies
0
Location
Purmerend
XP
459
Country
Netherlands
I really like the tut, C is very difficult to learn for me, but you made it simple to follow :D
But i have one question.
I want to make a sokoban game, but would that be to difficult?
Also, is there a tut for it floating around the web?
Thanks!
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,815
Trophies
3
Location
Gaming Grotto
XP
29,768
Country
Poland
Sokoban shouldn't be very difficult at all, actually. Unfortunately, we haven't gone into video game logic, and I don't want to go that far ahead yet. I've been neglecting this guide for some time - each day I get up, I promise myself "today will be the day I'll cover sprites in NFlib" and in the end, I never do... :P

In any case, Sokoban is working according to a very simple logic check - if all "box sprites" are present at a given position on the background (have either of the pre-specified X, Y values, are in a given space on a collision map, are on a specific tile etc. - there's many ways to do it), you "win", it's quite simple when you think about it.

We'll get there eventually, I just need to get myself together and start writing again... call it "writer's block" for now. ;)

What I will do though is pointing you to nflib's examples, as well as libnds's - you can find interesting demo's there which could inspire you on how to make your Sokoban clone.
 

Boy12

NOT a new member!
Member
Joined
Mar 8, 2012
Messages
536
Trophies
0
Location
Purmerend
XP
459
Country
Netherlands
Sokoban shouldn't be very difficult at all, actually. Unfortunately, we haven't gone into video game logic, and I don't want to go that far ahead yet. I've been neglecting this guide for some time - each day I get up, I promise myself "today will be the day I'll cover sprites in NFlib" and in the end, I never do... :P

In any case, Sokoban is working according to a very simple logic check - if all "box sprites" are present at a given position on the background (have either of the pre-specified X, Y values, are in a given space on a collision map, are on a specific tile etc. - there's many ways to do it), you "win", it's quite simple when you think about it.

We'll get there eventually, I just need to get myself together and start writing again... call it "writer's block" for now. ;)

What I will do though is pointing you to nflib's examples, as well as libnds's - you can find interesting demo's there which could inspire you on how to make your Sokoban clone.
Ok, thanks for the info!
BTW, i found a source code of sokoban coded in C , could i tweak with the code, to make it work on the DS?
 

Boy12

NOT a new member!
Member
Joined
Mar 8, 2012
Messages
536
Trophies
0
Location
Purmerend
XP
459
Country
Netherlands
Ok, thanks for the info!
BTW, i found a source code of sokoban coded in C , could i tweak with the code, to make it work on the DS?
Probably, if you have the know-how... but you're better off inventing something by yourself, really. ;)
Ok, thanks!
Oh, and instead of Sokoban, i am making a Breakout clone.
I think that would be way easier to begin with, since i am a beginner.
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,815
Trophies
3
Location
Gaming Grotto
XP
29,768
Country
Poland
Ok, thanks!
Oh, and instead of Sokoban, i am making a Breakout clone.
I think that would be way easier to begin with, since i am a beginner.
Whatever floats your boat - I'm available over PM and in here if you'll have some code snippets you'd like to discuss. :)
 

T3GZdev

head of T3GZdev
Member
Joined
Apr 21, 2010
Messages
1,034
Trophies
1
Website
sites.google.com
XP
434
Country
United States
i always had ths puzzleing questions since im mostly work with 3D.
is anyone know how to put background with 3D in libnds?

also m looking in the background examples. theres a .grit file for each image, what is used to make that?
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    K3Nv2 @ K3Nv2: Sorry for accidentally bending over