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,

IC_

GBAtemp's ???
Member
Joined
Aug 24, 2017
Messages
1,569
Trophies
1
Location
The Forest
XP
5,395
Country
Antarctica
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!
I'm not exactly sure how these libraries work but don't you need to create your own struct object with that type first?
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,817
Country
Poland
Yes, I tried using it as a normal variable too
I suggest using time.h instead and getting seconds as such:

secs = timeStruct->tm_sec;

Relevant libnds example:
https://github.com/devkitPro/nds-examples/blob/master/time/RealTimeClock/source/main.c

You may be able to use the built-in RTC function in the same way, but at this stage I have no idea what does or doesn't work as expected in libnds, so I tend to go by what libnds creators themselves suggest.

Structure reference:
http://www.cplusplus.com/reference/ctime/tm/

I'm not at my PC right now so I can't compile on my end, but when in doubt, standardised functions come to the rescue.

EDIT: Did this resolve your issue @Dani24f, or should I start up my PC and look at your source? I'm back at my workstation if you need a hand.
 

safendrd

Member
Newcomer
Joined
Apr 20, 2020
Messages
13
Trophies
0
XP
253
Country
Italy
I suggest using time.h instead and getting seconds as such:

secs = timeStruct->tm_sec;

Relevant libnds example:
https://github.com/devkitPro/nds-examples/blob/master/time/RealTimeClock/source/main.c

You may be able to use the built-in RTC function in the same way, but at this stage I have no idea what does or doesn't work as expected in libnds, so I tend to go by what libnds creators themselves suggest.

Structure reference:
http://www.cplusplus.com/reference/ctime/tm/

I'm not at my PC right now so I can't compile on my end, but when in doubt, standardised functions come to the rescue.

EDIT: Did this resolve your issue @Dani24f, or should I start up my PC and look at your source? I'm back at my workstation if you need a hand.
Hi, I tried using time.h as you said, but I get a "'timeStruct' was not declared in this scope" error.

Here's my code, so you check it out (thanks for helping me btw!):
Code:
#include <nds.h>
#include <stdio.h>
#include <time.h>

u8 secs=0;
float fps=0;


int main(){
    consoleDemoInit();
    while(1){
        printf("Initializing..."); /*This displays while waiting for the first second to pass*/
        fps = fps + 1; /*This increases the fps counter every frame*/
        secs = timeStruct->tm_sec; /*This gives a "timeStruct' was not declared in this scope" error when compiling*/
        if (( timeStruct->tm_sec - secs ) == 1 ) { /*If a second is passed*/
            iprintf("\rHello world by Dani24f! FPS: %.2f ", fps);
            fps = 0; /*Resets the fps variable and waits for another second to display the current fps*/
            if ( secs == 58 ) { secs = 0; } /*This prevents any error in the subtraction tm_sec - secs*/
        }
        swiWaitForVBlank();  
    }
}
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,817
Country
Poland
Hi, I tried using time.h as you said, but I get a "'timeStruct' was not declared in this scope" error.

Here's my code, so you check it out (thanks for helping me btw!):
Code:
#include <nds.h>
#include <stdio.h>
#include <time.h>

u8 secs=0;
float fps=0;


int main(){
    consoleDemoInit();
    while(1){
        printf("Initializing..."); /*This displays while waiting for the first second to pass*/
        fps = fps + 1; /*This increases the fps counter every frame*/
        secs = timeStruct->tm_sec; /*This gives a "timeStruct' was not declared in this scope" error when compiling*/
        if (( timeStruct->tm_sec - secs ) == 1 ) { /*If a second is passed*/
            iprintf("\rHello world by Dani24f! FPS: %.2f ", fps);
            fps = 0; /*Resets the fps variable and waits for another second to display the current fps*/
            if ( secs == 58 ) { secs = 0; } /*This prevents any error in the subtraction tm_sec - secs*/
        }
        swiWaitForVBlank();
    }
}
You need a timeStruct first. :P

time_t unixTime = time(NULL);
struct tm* timeStruct = gmtime((const time_t *)&unixTime);

This will create a time structure "tm" in UTC format. Admittedly a bit overcomplicated, this would be used for something like a clock, so I'll see if it can done in a simpler way (it can be). Honestly, you should be able to get framerate by comparing CPU ticks vs. screen refreshes with acceptable accuracy.
 

KonPet

Active Member
Newcomer
Joined
May 2, 2020
Messages
31
Trophies
0
XP
445
Country
Germany
Thanks for this awesome guide! I wanted to start making NDS homebrew a while back, but I just didn't know where to look for a guide or sth like that, but about 2 months ago, PolyMars led me here. Nice work!
 
  • Like
Reactions: PolyMars

KonPet

Active Member
Newcomer
Joined
May 2, 2020
Messages
31
Trophies
0
XP
445
Country
Germany
I have a question: As you may know, updating too many sprites while also having the DS calculate a lot can lead to sprites not getting properly deleted and staying on the screen even in the same position even after moving or even deleting. They don't do anything there, they just don't do anything. I had that problem when I made a game where you had to dodge falling meteors and the only way around that issue was deleting those sprites after they were off screen so you couldn't see the artifacts. Do you know how to fix this?
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,817
Country
Poland
I have a question: As you may know, updating too many sprites while also having the DS calculate a lot can lead to sprites not getting properly deleted and staying on the screen even in the same position even after moving or even deleting. They don't do anything there, they just don't do anything. I had that problem when I made a game where you had to dodge falling meteors and the only way around that issue was deleting those sprites after they were off screen so you couldn't see the artifacts. Do you know how to fix this?
This shouldn't be the case, once you refresh the screen they should be gone. Can you provide a snippet?
 

KonPet

Active Member
Newcomer
Joined
May 2, 2020
Messages
31
Trophies
0
XP
445
Country
Germany
This shouldn't be the case, once you refresh the screen they should be gone. Can you provide a snippet?
I'm not sure what you mean, but if you mean what my update looks like, here it is:
Code:
NF_SpriteOamSet(0);
NF_ResetSpriteBuffers();
swiWaitForVBlank();
oamUpdate(&oamMain);
I may have misunderstood the question though
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,817
Country
Poland
I'm not sure what you mean, but if you mean what my update looks like, here it is:
Code:
NF_SpriteOamSet(0);
NF_ResetSpriteBuffers();
swiWaitForVBlank();
oamUpdate(&oamMain);
I may have misunderstood the question though
The maximum number of sprites the DS can handle is pre-set - if they stay on the screen after being destroyed/deleted one of a couple of things might be happening - you've created more than the maximum number allowed (NFLib should stop you from doing that, so it's unlikely), you've overflown some kind of buffer or the DS is unable to properly refresh for some reason. It shouldn't display anything that's not actively loaded and within the bounds of the screen, so there's an error somewhere along the line. Your screen update routine is correct, but I would review everything else as this should not be happening.

A good way to test this is to create a test environment. Isolate all the code relating to sprite generation, set one button to create a new sprite and one to destroy the last one you've made, and keep creating them until the error triggers - that will help you narrow things down.
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,817
Country
Poland
You will also see graphical glitches like this if you send more data into the screen buffer than the screen can handle, but normally NFLib handles that automatically as long as you refresh it at the end of the loop, if there are any errors in this regard it should dump them into the console, which you should be able to pull up.
 

Arrie

Member
Newcomer
Joined
May 12, 2020
Messages
14
Trophies
0
Age
25
XP
172
Country
Netherlands
This link doesn't work anymore and it's also not in the wayback machine's web archive.

pern . drunkencoders . com /download-wiz
 
Last edited by Arrie,

Arrie

Member
Newcomer
Joined
May 12, 2020
Messages
14
Trophies
0
Age
25
XP
172
Country
Netherlands
Oh, thanks for the quick reply! Also, I was wondering, is this still the most up-to-date tutorial? Since it's from 2012..
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,817
Country
Poland
Oh, thanks for the quick reply! Also, I was wondering, is this still the most up-to-date tutorial? Since it's from 2012..
Well, nothing concerning DS development is really up-to-date since the platform was phased out, but the guide was written at the tail end of the life cycle, not to mention that the coding concepts are applicable regardless of the platform - C is C. Just keep in mind that many links might be dead and I have no backups of the software, so you may have to get creative sometimes. The forum has migrated since this was posted as well and I did my best to clean up the code since, but some fragments may be poorly formatted. Still, if you read thoroughly, you'll figure it out. :)
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,817
Country
Poland
I'm very new to libnds and I'm not sure how to compile my code with programmer's notepad
You should be able to find a template inside the devkitPro folder - save your code as the main file and then go to Tools - - > Make in PN. There are various templates available depending on what hardware you need to use, but if you're a newbie, you can just grab the Hello World example and start from there. :)
 
  • Like
Reactions: PolyMars

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
  • Xdqwerty @ Xdqwerty:
    also gonna install twilight menu in my r4 flashcard
  • Psionic Roshambo @ Psionic Roshambo:
    One thing that just occurred to me.... The sound on the 2600 sucked less back then the harsh sound we hear now is from infinitely better speakers we have now, back when the 2600 was new speakers produced a almost muffled sound, like CRTs made old graphics look slightly better.
  • Psionic Roshambo @ Psionic Roshambo:
    I wonder if I could recommend that to some emulation devs that perhaps the sound could use some smoothing out to simulate those old TVs
  • Psionic Roshambo @ Psionic Roshambo:
    I think a few of the early systems could benefit from that, at least up to the 8 bit generation, by the 16 bit generation I think TVs had gotten a lot better in almost every way
  • Xdqwerty @ Xdqwerty:
    i dont have an sd card adapter but I have an usb sd card adapter
  • K3Nv2 @ K3Nv2:
    Old people games
  • Xdqwerty @ Xdqwerty:
    its not the one that comes with the r4
  • Xdqwerty @ Xdqwerty:
    doesnt work (my flashcard is from r4isdhc.com)
  • Xdqwerty @ Xdqwerty:
    might install ysmenu first
  • Psionic Roshambo @ Psionic Roshambo:
    Try Wood firmware
  • Psionic Roshambo @ Psionic Roshambo:
    For your R4
  • Psionic Roshambo @ Psionic Roshambo:
    It's old but it's the best firmware out for DS stuff
  • Xdqwerty @ Xdqwerty:
    it says it only works for the original R4, R4i Gold (r4ids.cn), R4iDSN (r4idsn.com) and Acekard R.P.G.
  • Xdqwerty @ Xdqwerty:
    nvm it does support mine
  • Xdqwerty @ Xdqwerty:
    but why choose it over ysmenu @Psionic Roshambo?
  • Xdqwerty @ Xdqwerty:
    bc im stupid?
  • Xdqwerty @ Xdqwerty:
    yea ik im stupid
  • Xdqwerty @ Xdqwerty:
    good night
  • Psionic Roshambo @ Psionic Roshambo:
    Just give it a try, but honestly if you have a 3DS you can play DS games without a card just off the internal SD card
  • Psionic Roshambo @ Psionic Roshambo:
    Slightly slower loading but a bit more convenient
  • BakerMan @ BakerMan:
    guys, my fuckin headphones have an out of place speaker
  • K3Nv2 @ K3Nv2:
    Did you try wearing them?
    B @ btjunior: @Xdqwerty 16