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,818
Trophies
3
Location
Gaming Grotto
XP
29,789
Country
Poland
What did you mean by "Within the main while(); loop of the program"? I don't see such a line in the default "template.c", and I can't seem to get my compiled nds file to scan the keys...

As you can see, the while loop in main is right here:

//Beginning of main function:
int main(void) {
scanKeys();
consoleDemoInit();
iprintf("Hold the A button to\ngenerate text.\n");
if(KEY_A & keysHeld()) {
iprintf("The A button is held.");
}
//While main function returns 1, aka, while main function is running:
while(1) {
swiWaitForVBlank();
}
}

You're supposed to scan for input and check conditions every frame, otherwise it just won't work:

//Beginning of main function:
int main(void) {
//Initialization of basic functionality:
consoleDemoInit();
//Will print once, upon initialization:
iprintf("Hold the A button to\ngenerate text.\n");
//While main returns 1, aka, while main function is running:
while(1) {
//Scan for input:
scanKeys();
//Check if Button is pressed:
if(KEY_A & keysHeld()) {
//Will print every time A is Held:
iprintf("The A button is held.");
}
//Wait for next VBlank
swiWaitForVBlank();
}
}

You can of course remove the comments, I added them only for consistency's sake.
 
  • Like
Reactions: 1 person

Kiaku

Well-Known Member
Member
Joined
Mar 22, 2010
Messages
273
Trophies
1
Age
30
XP
381
Country
United States
You're supposed to scan for input and check conditions every frame, otherwise it just won't work:

//Beginning of main function:
int main(void) {
//Initialization of basic functionality:
consoleDemoInit();
//Will print once, upon initialization:
iprintf("Hold the A button to\ngenerate text.\n");
//While main returns 1, aka, while main function is running:
while(1) {
//Scan for input:
scanKeys();
//Check if Button is pressed:
if(KEY_A & keysHeld()) {
//Will print every time A is Held:
iprintf("The A button is held.");
}
//Wait for next VBlank
swiWaitForVBlank();
}
}

You can of course remove the comments, I added them only for consistency's sake.

Wow. Thank you so much! I didn't know that the while(1) actually loops each frame. I know you noted that it's required for that part to be at the end of each nds file all the time, but it was to loop each frame so the DS's video frame doesn't exit out?
 

Snailface

My frothing demand for 3ds homebrew is increasing
Member
Joined
Sep 20, 2010
Messages
4,324
Trophies
2
Age
40
Location
Engine Room with Cyan, watching him learn.
XP
2,255
Here, I added a couple of lines to make this example program behave a little nicer. ^_^
Take note of the changes inside the /* */ comments and see what effects they have compared to the
previous example. Small changes in a program can have a big effect. ;)
Code:
#include 
//Beginning of main function:
int main(void) {
//Initialization of basic functionality:
consoleDemoInit();

//While main returns 1, aka, while main function is running:
while(1) {
//Scan for input:
iprintf("Hold the A button to\ngenerate text.\n");   /*moved inside loop to prevent disappearance*/
scanKeys();
//Check if Button is pressed:
if(KEY_A & keysHeld()) {
//Will print every time A is Held:
iprintf("The A button is held.");  
}
//Wait for next VBlank
swiWaitForVBlank();
consoleClear();						/*added to keep 'The A button is held.' from being persistent*/
}
}
 
  • Like
Reactions: 2 people

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,818
Trophies
3
Location
Gaming Grotto
XP
29,789
Country
Poland
@[member='Snailface']

Well-done, clearing the console does make the program tidier. I didn't include it since it wasn't mentioned in the original question, but knowing that it's an option does improve the overall output. ;)

Wow. Thank you so much! I didn't know that the while(1) actually loops each frame. I know you noted that it's required for that part to be at the end of each nds file all the time, but it was to loop each frame so the DS's video frame doesn't exit out?
Basically, the program launches main(){...} as its main function. It runs until it returns a 0 or you use exit(0); from the program, until then, everything that's before the while{...} is done during the initialization stage and everything that's in the while{...} is "the main flavour of the program", aka, what it actually does frame-by-frame. That's the easiest way I can explain it.
 
  • Like
Reactions: 2 people

Kiaku

Well-Known Member
Member
Joined
Mar 22, 2010
Messages
273
Trophies
1
Age
30
XP
381
Country
United States
How would I code an nds file so that instead of having a button generate only one statement, I can generate different statements with the same button?
For example, pressing A once would print "A button: 1" while pressing A twice would print "A button: 2", and so on?
 

DiscostewSM

Well-Known Member
Member
Joined
Feb 10, 2009
Messages
5,484
Trophies
2
Location
Sacramento, California
Website
lazerlight.x10.mx
XP
5,456
Country
United States
How would I code an nds file so that instead of having a button generate only one statement, I can generate different statements with the same button?
For example, pressing A once would print "A button: 1" while pressing A twice would print "A button: 2", and so on?

For such a case, where you want a "press this many times for a certain action", you need a time frame for the input, and a counter that holds the number of times you pressed the button. Here is a simple program I just made that will examine how many times you press the A button in a set amount of time.

Code:
#include 

#include 


// A few constant values

#define TIME_FRAME 180					// (TIME_FRAME / 60) seconds -> 180 = 3 seconds
#define RESULT_TIME_FRAME 240	// ((RESULT_TIME_FRAME / 60 ) seconds -> 240 = 4 seconds


// The entry function

int main(void) {

consoleDemoInit();	// Generates the mode for text

printf( "  Examine the number of times\nthe A button is pressed in\n%1.2f second(s).\n\n", (float)TIME_FRAME / 60.0 );

int timerCountDown = 0;	// A counter that decrements to 0
int timerState = 0;	// The current timer State ( 0 - Ready to start, 1 - Input in progress , 2 - Results )
int buttonCounter = 0;	// The number of times the button was pressed

while( 1 ) {
scanKeys();	// Get the current state of the input


if( timerState > 0 ) {		
if( timerCountDown > 0 )		// Timer countdown
timerCountDown--;
else {
if( timerState == 1 ) {		// Show results of test
timerState = 2;
timerCountDown = RESULT_TIME_FRAME;
iprintf( "\x1b[5;0HButton A was pressed %d time(s).   ", buttonCounter );

} else {			// Restart in ready mode
timerState = 0;
buttonCounter = 0;
consoleClear();
printf( "  Examine the number of times\nthe A button is pressed in\n%1.2f second(s).\n\n", (float)TIME_FRAME / 60.0 );				}
}
if( timerState == 2 ) {
if( timerCountDown < 60 )
printf( "\x1b[6;0HRestarting test in %.2f seconds.", (float)timerCountDown / 60 );
else
iprintf( "\x1b[6;0HRestarting test in %d seconds.", timerCountDown / 60 );
}
}


if( timerState < 2 && KEY_A & keysDown() ) {	// Is the test set for input?
buttonCounter++;

if( timerState == 0 ) {		// Switch to input mode

timerState = 1;
timerCountDown = TIME_FRAME;
}
}
if( timerState == 1 ) {
if( timerCountDown < 60 )
printf( "\x1b[5;0HIn progress...\n %.2f seconds remaining\n\n", (float)timerCountDown / 60 );
else
iprintf( "\x1b[5;0HIn progress...\n %d seconds remaining\n\n", timerCountDown / 60 );
}

swiWaitForVBlank();
}

return 0;
}
 
  • Like
Reactions: 1 person

Kiaku

Well-Known Member
Member
Joined
Mar 22, 2010
Messages
273
Trophies
1
Age
30
XP
381
Country
United States
For such a case, where you want a "press this many times for a certain action", you need a time frame for the input, and a counter that holds the number of times you pressed the button. Here is a simple program I just made that will examine how many times you press the A button in a set amount of time.

Code:
#include 

#include 


// A few constant values

#define TIME_FRAME 180					// (TIME_FRAME / 60) seconds -> 180 = 3 seconds
#define RESULT_TIME_FRAME 240	// ((RESULT_TIME_FRAME / 60 ) seconds -> 240 = 4 seconds


// The entry function

int main(void) {

consoleDemoInit();	// Generates the mode for text

printf( "  Examine the number of times\nthe A button is pressed in\n%1.2f second(s).\n\n", (float)TIME_FRAME / 60.0 );

int timerCountDown = 0;	// A counter that decrements to 0
int timerState = 0;	// The current timer State ( 0 - Ready to start, 1 - Input in progress , 2 - Results )
int buttonCounter = 0;	// The number of times the button was pressed

while( 1 ) {
scanKeys();	// Get the current state of the input


if( timerState > 0 ) {		
if( timerCountDown > 0 )		// Timer countdown
timerCountDown--;
else {
if( timerState == 1 ) {		// Show results of test
timerState = 2;
timerCountDown = RESULT_TIME_FRAME;
iprintf( "\x1b[5;0HButton A was pressed %d time(s).   ", buttonCounter );

} else {			// Restart in ready mode
timerState = 0;
buttonCounter = 0;
consoleClear();
printf( "  Examine the number of times\nthe A button is pressed in\n%1.2f second(s).\n\n", (float)TIME_FRAME / 60.0 );				}
}
if( timerState == 2 ) {
if( timerCountDown < 60 )
printf( "\x1b[6;0HRestarting test in %.2f seconds.", (float)timerCountDown / 60 );
else
iprintf( "\x1b[6;0HRestarting test in %d seconds.", timerCountDown / 60 );
}
}


if( timerState < 2 && KEY_A & keysDown() ) {	// Is the test set for input?
buttonCounter++;

if( timerState == 0 ) {		// Switch to input mode

timerState = 1;
timerCountDown = TIME_FRAME;
}
}
if( timerState == 1 ) {
if( timerCountDown < 60 )
printf( "\x1b[5;0HIn progress...\n %.2f seconds remaining\n\n", (float)timerCountDown / 60 );
else
iprintf( "\x1b[5;0HIn progress...\n %d seconds remaining\n\n", timerCountDown / 60 );
}

swiWaitForVBlank();
}

return 0;
}

Is there a way to only count the buttons w/o the timer?
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,818
Trophies
3
Location
Gaming Grotto
XP
29,789
Country
Poland
Just so that the timer confusion is cleared up, libnds already has built-in key repeat functionality.

keysHeld() checks whether the key is Held down since the last frame. You can use something different entirely though - keysDownRepeat().

By using keysSetRepeat(u8 DelayInFrames, u8 NumberOfRepeats) and keysDownRepeat() you can in fact create a macro on exactly how many presses you need and at what intervals, nullifying the need for a timer altogether, at least that's my understanding of the documentation, which by the way is very vague on the subject and I've never found a particular use for such timers except for maybe combos in fighting games or for scrolling lists.
 

CannonFoddr

Regular GBATemp Lurker
Member
Joined
Sep 23, 2006
Messages
4,134
Trophies
1
Age
56
Location
Sitting by computer
Website
www.youtube.com
XP
1,285
Country
hmm, just been brought to my attention that some people been having trouble downloading the PDF file from filetrip...
I've had a check & it seems that it doesn't work in Chrome, but does (at least) in IE8 and Firefox

I found a workaround in Chrome if you have trouble (well - it works for me)

In the popup box you see after clicking the 'Download selected version'
If your download doesn't start within the next 5 seconds, click here to start it manually.
If you RIGHT-Click on the 'Click Here' & then select 'Save Link As...' you should be able to download it...

If that fails - here's a link to a mirror of the 1-6.1 version
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,818
Trophies
3
Location
Gaming Grotto
XP
29,789
Country
Poland
An update to the guide is being written as we speak, I finally found some spare time.

What you can expect is some theory about the memory layout of the DS, but laid out in Layman's terms so that everybody can understand the idea behind dividing VRAM into Banks and so on and so forth, next we'll introduce graphics while using NightFoxLib, conversion of graphics into tiled graphics or bitmaps using GRIT software and file management under Visual Studio 2008.

The first part should be uploaded tonight, so stay tuned! ;)

EDIT: Looks like it won't afterall. Forces beyond my control. Tomorrow though. ;)
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,818
Trophies
3
Location
Gaming Grotto
XP
29,789
Country
Poland
It’s been a while, hasn’t it? Well, as I said, I was quite busy with my exams, but right now I have a little bit of spare time to write so I’ll dedicate it to moving forward with the guide. To re-cap, so-far we’ve learned everything we need to create conditions in our programs and to use both the buttons and the touchscreen as means of input. That’s all great, but other than console text, we still don’t know how to include graphics in our projects! The next few chapters will be dedicated to both the basic theory behind graphics on the DS and practical use of NightFoxLib, which will be our library of choice to facilitate the use of backgrounds and sprites. Before we get there though, we need to learn a little bit about the DS itself once more – to be exact, we have to review how exactly the memory of the DS works and how to use it properly. Without further ado, let us dig in to our next chapter, dedicated to RAM, VRAM and Screen Layers.

Introduction to DS Hardware: Chapter 1 – RAM and VRAM

Before we properly dive into the use of graphics and various other resources, first we need to learn a bit about how the DS manages memory. As you may or may not know, the DS has 4MB of Main RAM memory, shared between its two processors – the ARM9 and the ARM7. Main RAM is where your entire Binary will be stored during its execution and naturally it has to be used efficiently, as it isn’t a whole lot of space. For a long time, it was a huge bottleneck for homebrew programmers, but then came libraries such as FATlib, NitroFS and other file systems that facilitated streaming resources into RAM, nullifying this problem by the use of buffering. We won’t tackle that just yet, seeing that conveniently, NightFoxLib does it for us automatically, however we will talk about their use later-on when introducing Saving and Loading. Let’s move on to the next important part of the DS’s memory – the VRAM.

The fact that your resources are stored in RAM isn’t always enough to utilize them. Graphics have to fit within Video RAM before they are displayed. The size of VRAM is only 656KiB altogether, which is quite a bottleneck, considering the way it is structured. The memory is divided into several banks, all of which have different functions assigned to them. Let’s have a look at this diagram:
BEwSd.png
This should help you imagine how the system works. Again, conveniently, NightFoxLib will deal with the VRAM banks for us, but I figured that it’s best if you have a look at it to understand why sometimes you run out of VRAM blocks when using graphics.

To combat this inheritent problem of lack of space, Tiled graphics have been introduced back in the olden days. They take much less space than standard backgrounds, and these will be the first for us to tackle – specifically, tiled backgrounds converted with the GRIT (GBA Raster Image Transmogrifier) tool.
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,818
Trophies
3
Location
Gaming Grotto
XP
29,789
Country
Poland
I specifically picked NightFox Lib as the library of choice for this guide, simply because its use is incredibly simple and because the library is still in active developed, not to mention that it's well-documented. I believe that we will all get the quickest and best results if we focus on it as our graphics library, so let's get to it.

Practical Use of NightFox Lib – Chapter 1 – NightFox Lib Integration Part 1


Integrating the library with your Projects is incredibly easy – all you really have to do is copy/paste the Template provided in the lib’s folder into Your project… and that’s it! There are further integration options that you may choose that will be discussed in the second part of this chapter. As you’ve already noticed, a few new folder have appeared in your Project Folder – those will be used to store various Resources. Visual Studio is capable of linking those folders to particular elements of your Solutions. By doing that, you will always see the contents of your folders which will make coding this one bit easier. Including those folders in your solution is pretty straight-forward, but we’ll leave that for later as I already know you all can’t possibly wait any longer to get to the juicy parts.

For now, attempt to compile the Template. If everything goes well and without hiccups, you’ve just successfully included NightFox Lib in your Project – well done!

Additional Utilities - Chapter 1 - GRIT


Now that we’ve included NightFox Lib in our project and we’re all acustomed with how RAM and VRAM works, we can finally move on to what we’re really interested in – using Graphics in our games and applications. As I already mentioned, the DS mostly uses Tiled Graphics – they’re much easier to render and their size is lower, thus they don’t clutter the RAM and VRAM as much. To convert an image to that kind of a format, we will be using GRIT. The name stands for GBA RASTER IMAGE TRANSMOGRIFIER and it has been the tool of choice for both GBA and NDS development due to the variety of functions it offers. It’s been created and maintained by Jasper Vijn and it’s available at http://www.coranac.com/projects/grit/ however you already have it as it’s the default tool used by NightFox Lib – you can find it in the Tools directory at nflib/tools.

There, you will find several Batch files that we will be using to convert our Bitmaps with. Those include:
Convert_Affine - this Batch file will convert all the graphics in the BMP folder into Tiled Affine Backgrounds and copy them into the affine folder.
Convert_Backgrounds - this Batch file will convert all the graphics in the BMP folder into Tiled Backgrounds and copy them into the backgrounds folder.
Convert_bitmap8 - this Batch file will convert all the graphics in the BMP folder into 8-bit Bitmaps and copy them into the bitmap8 folder.
Convert_bitmap8_shared - this Batch file will convert all the graphics in the BMP folder into 8-bit Bitmaps with a shared palette and copy them into the bitmap8 folder.
Convert_bitmap16 - this Batch file will convert all the graphics in the BMP folder into 16-bit Bitmaps and copy them into the bitmap16 folder.
Convert_CMaps - this Batch file will convert all the graphics in the BMP folder into Collision Maps and copy them into the cmaps folder.
Convert_Fonts - this Batch file will convert fonts and copy them to the fonts folder.
Convert_Sprites - this Batch file will convert all the graphics in the BMP folder into DS-Compatible Sprites and copy them into the sprites folder.
Convert_Sprites_autopal - this Batch file will convert all the graphics in the BMP folder into DS-Compatible Sprites with a shared palette and copy them into the sprites folder.

As you can see, with NightFox Lib’s pre-prepared Batch converter files, converting resources will be a breeze! Remember, by default, all Tiled Graphics have a transparent colour selected, and this colour is Magenta (RGB 255,0,255) – use it whenever you want parts of your graphics to be transparent as it will not appear on the hardware. Another thing worth noting is that our Backgrounds must have sizes divisible by 256 pixels and our 2D Sprites must have sizes divisible by 8 pixels, 64 pixels being the maximum width/heigh, so keep that in mind before converting to avoid errors.

Practical Use of NightFox Lib – Chapter 2 – NightFox Lib 2D MODE-0 Part 1 - Tiled Backgrounds


I didn’t quite know how to start off the subject of Graphics in NightFox Lib to make it approachable to anyone, so I figured that the best way to do so would be to do it methodically. In the following few chapters I’m going to introduce the idea behind MODE’s that the DS’s 2D Engine uses, what they do and how to take the best advantage of them. We’re going to start with MODE 0 and climb upwards until we’ve discussed them all. Just so that nobody’s bored during these chapters, I’m also going to introduce the types of graphics most commonly used in the MODE in question, so that we get a little bit of practical and theoretical knowledge. This chapter will be dedicated to MODE 0 of the 2D engine in NightFox. This mode offers 4 layers of Tiled Graphics on the screen in question, and it’s likely going to be the MODE you use most commonly. To initialize a MODE, we use the command:
NF_Set2D(Screen, MODE);
Simply substitute Screen with use 0 or 1 to select the Top or Bottom one, and substitute MODE with 0, 2 or 5 – the default MODE’s of NightFox Lib.

Now, before we do anything else, we have to define the default Folder for our Resources, using this function:
NF_SetRootFolder("ROOT");
Now, to use the Internal filesystem, we substitute the ROOT with NITROFS, in all other cases, we simply input the folder name and the function will enable FAT instead.​


With that out of the way, we can start having fun with Tiled Graphics in our projects. We’ll start with Backgrounds. Before we can use any, we have to initialize the buffers for backgrounds, as NightFox streams them from NitroFS or FAT by default. To do so, we use these functions:
NF_InitTiledBgBuffers();
NF_InitTiledBgSys(Screen);
And again, we substitute the word Screen with the screen we are interested in – 0 or 1.
With that out of the way, we’re ready to select a background to load into VRAM. Our backgrounds have to be placed in the “nitrofiles” folder of our project, once they’re there, we can use this function:
NF_LoadTiledBg("Path", "Name", Width, Height);
It will open the background in question, load it into RAM, attach a name to it and store the parameters of its Width and Height (divisible by 256!) so that we don’t have to remember them later on as we code. It’s pretty convenient, but our Tiled Background is not ready to be displayed yet. As we learned from the previous chapter about RAM and VRAM, we still have to copy it over to VRAM to display it. To do so, we simply use this command:
NF_CreateTiledBg(Screen, Layer, "Name");
As you can see, NightFox will deal with RAM-VRAM communications for us and all we really have to do is to select the Screen and Layer on which we’d like to display our background. We won’t tackle the idea of Layers for now beyond the fact that there are 4 Layers on each Screen, numbered from 0 to 3, 0 being the top-most and 3 being the bottom-most Layer.

Okay, so we have our Background ready to be displayed – it’s going to appear on our screen right after the next swiWaitForVBlank(); - perfect!

Just to make sure, let's review our sample code, shall we?

Code:
/*
#############################################
##DS Programming Guide - From Zero To Hero!##
####Example #2 - MODE 0 Tiled Backgrounds####
#############################################
*/
 
/*
############
##Includes##
############
*/
 
// Include C
#include <stdio.h>
 
// Include Libnds
#include <nds.h>
 
// Include NFLib
#include <nf_lib.h>
/*
###############
##Main(){...}##
###############
*/
 
int main(int argc, char **argv) {
 
// Turn on MODE 0 on the Top Screen
NF_Set2D(0, 0);
 
// Set the Root Folder
NF_SetRootFolder("NITROFS");
 
// Initialize the Tiled Backgrounds System on the Top Screen
NF_InitTiledBgBuffers();
NF_InitTiledBgSys(0);
 
// Load the Tiled Background
NF_LoadTiledBg("Background", "Background", 256, 256);
NF_CreateTiledBg(0, 3, "Background");
 
while(1){
swiWaitForVBlank();
}
return 0;
}

Let's compile this... and... SUCCESS! We've just learned how to create, load and display Tiled Backgrounds! Just to make sure that everything is understandable, I'll attach the Example compile folder so that everyone can review the source:

http://www.mediafire...lg6tvxd78gw3kly

I hope that everybody had fun and stay tuned for the next chapters, which will concern Sprites! Foxi4 over and out!
 

CannonFoddr

Regular GBATemp Lurker
Member
Joined
Sep 23, 2006
Messages
4,134
Trophies
1
Age
56
Location
Sitting by computer
Website
www.youtube.com
XP
1,285
Country
FYI - the PDF been updated to include the Above (download it here)

Sorry, but I've changed the version number again - It now has the date instead...
So that you know it contains everything up to the corresponding Foxi4 post

EDIT: oopps - Just realised I've made a small mistake - the PDF is dated '11-Jun-2012', but the 'version' on filetrip is '30-Jun-2012'
The PDF contains everything up to the 30th & not the 11th.... Sorry
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,818
Trophies
3
Location
Gaming Grotto
XP
29,789
Country
Poland
FYI - the PDF been updated to include the Above (download it here)

Sorry, but I've changed the version number again - It now has the date instead...
So that you know it contains everything up to the corresponding Foxi4 post

EDIT: oopps - Just realised I've made a small mistake - the PDF is dated '11-Jun-2012', but the 'version' on filetrip is '30-Jun-2012'
The PDF contains everything up to the 30th & not the 11th.... Sorry
Hey, no hurry! I'm already greatful that you're maintaining the offline version, take your time with tidying up things.
 

Skye07

Well-Known Member
Member
Joined
Dec 24, 2006
Messages
450
Trophies
0
Location
Belgium
Website
www.skyon.be
XP
469
Country
Belgium
Could you elaborate a bit on how to add the library into a new DS project? Copy paste the template folder into the source folder of your project? Or paste into the solution explorer, ...

I don't immediately see what I need to do.

Never mind, found it (also in the documentation of the lib). Thanks for the tutorials!

Also, how do you make a .map and a .pal file? When I run the Convert_Backgrounds.bat file it only makes an .img file. I checked the bat file and the parameters and looked them up and it really should make pal and map files, any idea why it doesn't?

The bmp file has to have 8bit color depth, mine didn't, it works now.


And another question: How would you go and write code to check if 2 buttons are pushed at the same time? (E.g. for diagonal movement)
I gave it a go myself but I'm not sure if this is the best way to do it.
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,818
Trophies
3
Location
Gaming Grotto
XP
29,789
Country
Poland
And another question: How would you go and write code to check if 2 buttons are pushed at the same time? (E.g. for diagonal movement)
I gave it a go myself but I'm not sure if this is the best way to do it.
Have a look at the Operators chapter, you can connect two Conditions using the operator AND (&&). ;)

Example:

Code:
//A quick wrapper over the two buttons, serves no real purpose other than clarifying the code and it can be omitted.
//Declarations
s16 Up;
s16 Right;

//Somewhere within while, after scanning for keys
Up = keysHeld() & KEY_UP;
Right = keysHeld() & KEY_RIGHT;


if (Up && Right){
...Statements...
}

This is just an example though, I would do it slightly differently - all you really have to do to apply full diagonal movement is to make the D-Pad add or decrease the X and Y and the sprite or whatever else you'd want to move will move diagonally unless you restrict it:


Code:
//A quick wrapper over the two buttons, serves no real purpose other than clarifying the code and it can be omitted.
//Declarations
s16 Up;
s16 Right;

//Somewhere within while, after scanning for keys
Up = keysHeld() & KEY_UP;
Right = keysHeld() & KEY_RIGHT;

if (Up){
//Pre-set your speed or define it if it's static.
Sprite.Y = Sprite.Y - Speed;
}
if (Right){
//Pre-set your speed or define it if it's static.
Sprite.X = Sprite.X + Speed;
}

If both are pressed, the movement will be diagonal as both conditions are returned true, thus both variables are updated.

The solution you proposed is good as well - there are really as many solutions to your question as many there are programmers - simply pick the one you feel comfortable with. :)

I personally like to declare the variables I will use with my keys in a separate header file and use shortened forms rather than the ones proposed by libnds and I keep them in a structure of bools just so that the names and outputs are clear, but hey! That's me.

Also, sorry for not replying for such a long time - I was away on a business trip for the last week or so. Indeed, tiled backgrounds have to be 8-Bit since each map only supports 256 colours unless you use Extended Palettes Mode which will be covered later or if you use Raster backgrounds which are sort of wasteful and should be avoided unless they're used for splash screens and such.
 

frezziii

Member
Newcomer
Joined
Aug 14, 2012
Messages
10
Trophies
0
XP
3
Country
Gambia, The
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 ;)
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    S @ salazarcosplay: let you transfer it all