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,

elezzar

Well-Known Member
Newcomer
Joined
Apr 6, 2023
Messages
45
Trophies
0
XP
203
Country
United States
Everything in it is still valid, although the Drunken Coders wizard is unfortunately no longer available. Not that it matters since you wouldn’t be using such an old release of Visual Studio anyway. You can just as easily do everything in Notepad. Some errors have slipped here and there due to multiple forum software transitions over the years (killing the formatting as a result), but they’re easily spotted.
Hi, I'm new to development in general and have no idea on how to do this. could you possibly elaborate on the steps to get everything set up with notepad or a newer visual studio? I read something about compiling a make.exe file as well and I'm pretty lost on the matter... I'd greatly appreciate any help


PS. thanks for the tutorial!
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,840
Country
Poland
Hi, I'm new to development in general and have no idea on how to do this. could you possibly elaborate on the steps to get everything set up with notepad or a newer visual studio? I read something about compiling a make.exe file as well and I'm pretty lost on the matter... I'd greatly appreciate any help


PS. thanks for the tutorial!
All you *really* need is devkitPro, the template that comes pre-packaged with NFLib and Programmer’s Notepad (or similar). The Visual Studio wizard has been lost to time, you’d have to set up the environment manually, and for most DS projects you really don’t need to do that.
 

elezzar

Well-Known Member
Newcomer
Joined
Apr 6, 2023
Messages
45
Trophies
0
XP
203
Country
United States
All you *really* need is devkitPro, the template that comes pre-packaged with NFLib and Programmer’s Notepad (or similar). The Visual Studio wizard has been lost to time, you’d have to set up the environment manually, and for most DS projects you really don’t need to do that.
so, if i have devkitpro installed and i have the template folder, all i need to do is put my code in the source folder and then use the compile.bat to compile my work? or am i misunderstanding
 

Turion64

New Member
Newbie
Joined
Feb 9, 2024
Messages
2
Trophies
0
Age
22
XP
14
Country
United States
Hello! I've been having a lot of fun following these tutorials, (10 years late?) but I seem to be stuck on getting tiled sprites to work. They physically load, but the pixels look like they've been run through a blender. :lol:

My process:
1. Create a 32x96 bmp file, using indexed color on GIMP. (three 32x32 sprites, like the 2d sprite tutorial.)

2. Run conver-sprites-autopal.bat.

3. Plonk the files in nitrofiles.

As you can see, my poor pokemon sprite looks a little rough. Oddly enough, if I only do a single 32x32 sprite, it seems to work just fine. But the 32x96 does not.
Screenshot 2024-02-09 165615.png


(The background is tan, so that's supposed to be there)
Anyone else run into this issue?



#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);
// Turn on MODE 0 on the Bottom Screen
NF_Set2D(1, 0);

// Set the Root Folder
NF_SetRootFolder("NITROFS");
// Initialize the Tiled Backgrounds System on the Top Screen
NF_InitTiledBgBuffers();
NF_InitTiledBgSys(0);
NF_InitTiledBgSys(1);
// Initialize the Tiled Sprites System on the Bottom and Top Screen
NF_InitSpriteBuffers();
NF_InitSpriteSys(1);
// Load and Create the Tiled Background
NF_LoadTiledBg("TopScreen", "Top", 256, 256); // Load a Background into RAM for the Top Screen
NF_LoadTiledBg("BottomScreen", "Bottom", 256, 256); // Load a Background into RAM for the Bottom Screen
NF_CreateTiledBg(0, 3, "Top"); // Create the Top Background
NF_CreateTiledBg(1, 3, "Bottom"); // Create the Bottom Background
// Load our Tiled Sprite
NF_LoadSpriteGfx("treecko5", 0, 32, 32);
NF_LoadSpritePal("treecko5", 0);
// Transfer our sprite to VRAM
NF_VramSpriteGfx(1, 0, 0, false);
NF_VramSpritePal(1, 0, 0);
// Create the Sprite!
NF_CreateSprite(1, 0, 0, 0, 100, 100);
int ScytherPositionX = 100;
int ScytherPositionY = 100;

while(1){
//Update NF OAM Settings
NF_SpriteOamSet(1);
swiWaitForVBlank();
//Update OAM!
oamUpdate(&oamSub);
scanKeys();
int keys = keysHeld();

if(keys & KEY_START) break;
if(keys)
{
if(keys & KEY_UP)
{

int ScytherPositionYU = ScytherPositionY--;
NF_MoveSprite(1, 0, ScytherPositionX, ScytherPositionYU);
NF_SpriteFrame(1, 0, 0);
//ScytherPositionY = ScytherPositionYU;


}
if(keys & KEY_LEFT)
{
int ScytherPositionXL = ScytherPositionX--;
NF_MoveSprite(1, 0, ScytherPositionXL, ScytherPositionY);
NF_SpriteFrame(1, 0, 1);
//ScytherPositionX = ScytherPositionXL;
}
if(keys & KEY_RIGHT)
{
int ScytherPositionXR = ScytherPositionX++;
NF_MoveSprite(1, 0, ScytherPositionXR, ScytherPositionY);
NF_SpriteFrame(1, 0, 2);
//ScytherPositionX = ScytherPositionXL;
}
if(keys & KEY_DOWN)
{
int ScytherPositionYD = ScytherPositionY++;
NF_MoveSprite(1, 0, ScytherPositionX, ScytherPositionYD);
NF_SpriteFrame(1, 0, 0);
}
}



}
return 0;
}
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,840
Country
Poland
Hello! I've been having a lot of fun following these tutorials, (10 years late?) but I seem to be stuck on getting tiled sprites to work. They physically load, but the pixels look like they've been run through a blender. :lol:

My process:
1. Create a 32x96 bmp file, using indexed color on GIMP. (three 32x32 sprites, like the 2d sprite tutorial.)

2. Run conver-sprites-autopal.bat.

3. Plonk the files in nitrofiles.

As you can see, my poor pokemon sprite looks a little rough. Oddly enough, if I only do a single 32x32 sprite, it seems to work just fine. But the 32x96 does not.
View attachment 419061

(The background is tan, so that's supposed to be there)
Anyone else run into this issue?



#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);
// Turn on MODE 0 on the Bottom Screen
NF_Set2D(1, 0);

// Set the Root Folder
NF_SetRootFolder("NITROFS");
// Initialize the Tiled Backgrounds System on the Top Screen
NF_InitTiledBgBuffers();
NF_InitTiledBgSys(0);
NF_InitTiledBgSys(1);
// Initialize the Tiled Sprites System on the Bottom and Top Screen
NF_InitSpriteBuffers();
NF_InitSpriteSys(1);
// Load and Create the Tiled Background
NF_LoadTiledBg("TopScreen", "Top", 256, 256); // Load a Background into RAM for the Top Screen
NF_LoadTiledBg("BottomScreen", "Bottom", 256, 256); // Load a Background into RAM for the Bottom Screen
NF_CreateTiledBg(0, 3, "Top"); // Create the Top Background
NF_CreateTiledBg(1, 3, "Bottom"); // Create the Bottom Background
// Load our Tiled Sprite
NF_LoadSpriteGfx("treecko5", 0, 32, 32);
NF_LoadSpritePal("treecko5", 0);
// Transfer our sprite to VRAM
NF_VramSpriteGfx(1, 0, 0, false);
NF_VramSpritePal(1, 0, 0);
// Create the Sprite!
NF_CreateSprite(1, 0, 0, 0, 100, 100);
int ScytherPositionX = 100;
int ScytherPositionY = 100;

while(1){
//Update NF OAM Settings
NF_SpriteOamSet(1);
swiWaitForVBlank();
//Update OAM!
oamUpdate(&oamSub);
scanKeys();
int keys = keysHeld();

if(keys & KEY_START) break;
if(keys)
{
if(keys & KEY_UP)
{

int ScytherPositionYU = ScytherPositionY--;
NF_MoveSprite(1, 0, ScytherPositionX, ScytherPositionYU);
NF_SpriteFrame(1, 0, 0);
//ScytherPositionY = ScytherPositionYU;


}
if(keys & KEY_LEFT)
{
int ScytherPositionXL = ScytherPositionX--;
NF_MoveSprite(1, 0, ScytherPositionXL, ScytherPositionY);
NF_SpriteFrame(1, 0, 1);
//ScytherPositionX = ScytherPositionXL;
}
if(keys & KEY_RIGHT)
{
int ScytherPositionXR = ScytherPositionX++;
NF_MoveSprite(1, 0, ScytherPositionXR, ScytherPositionY);
NF_SpriteFrame(1, 0, 2);
//ScytherPositionX = ScytherPositionXL;
}
if(keys & KEY_DOWN)
{
int ScytherPositionYD = ScytherPositionY++;
NF_MoveSprite(1, 0, ScytherPositionX, ScytherPositionYD);
NF_SpriteFrame(1, 0, 0);
}
}



}
return 0;
}
32x96 is not a compatible sprite size.

https://libnds.devkitpro.org/sprite_8h.html#a1b3e231e628b18808e49a2f94c96b1ea

You have a couple different options here - you can split your sprite into two sections (32x32 + 32x64), use a background layer for your large sprites, use 3D sprites or mess around with the Double attribute (only works for rotating sprites, not recommended, it looks like garbage imo). By far the easiest thing to do would be to use multiple sprites to represent one object, but 3D sprites are ostensibly better suited for sprites with custom sizes like this.
 

Turion64

New Member
Newbie
Joined
Feb 9, 2024
Messages
2
Trophies
0
Age
22
XP
14
Country
United States
Nooo I typed up a reply but wasn't logged in, haha...

Just to clarify, my goal is not to make one 32x96 sprite, but to have 3 32x32 sprites on one .bmp like the tic-tac-toe tutorial. (E.g. X, O, and blank)

Then use nf spriteframe to change the frames. :)

I probably didn't explain that well the first time around, so sorry about that!

I tested with the .png from the tic-tac-toe tutorial, (the .png with blank, X, O) by converting it to a .bmp, and it worked with my code. (E.g. down arrow changes the sprite frame from X to O) So I suspect I screwed up the color formatting, and that's what's turning my sprite into a pixel smoothie.
Edit: I see now that I referenced the wrong tutorial for my original question, by referencing the basic sprite tutorial instead of the tic-tac-toe tutorial. My bad!
:)
 
Last edited by Turion64,

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,840
Country
Poland
Nooo I typed up a reply but wasn't logged in, haha...

Just to clarify, my goal is not to make one 32x96 sprite, but to have 3 32x32 sprites on one .bmp like the tic-tac-toe tutorial. (E.g. X, O, and blank)

Then use nf spriteframe to change the frames. :)

I probably didn't explain that well the first time around, so sorry about that!

I tested with the .png from the tic-tac-toe tutorial, (the .png with blank, X, O) by converting it to a .bmp, and it worked with my code. (E.g. down arrow changes the sprite frame from X to O) So I suspect I screwed up the color formatting, and that's what's turning my sprite into a pixel smoothie.
Edit: I see now that I referenced the wrong tutorial for my original question, by referencing the basic sprite tutorial instead of the tic-tac-toe tutorial. My bad!
:)
Ah, so it was just the converter derping then, no harm done. :lol:
 

Chrono_Nightmare

New Member
Newbie
Joined
Apr 6, 2024
Messages
1
Trophies
0
Age
29
XP
17
Country
United States
Currently on "Chapter 2 – NightFox Lib 2D MODE-0 Part 1 - Tiled Backgrounds" and MelonDS (and a real DSi) gives the error: "NitroFS Init Error. Abnormal Termination. Check if your flashcard is Argv compatible".
Screenshot (4280).png



When tinkering with my code I noticed that it works fine when I remove the line: "NF_SetRootFolder("NITROFS");"
Granted it tells me my tileset image needs to be larger than 250 pixels, but still weird that I get a flashcard error when I have the root set.

I tried moving the example code over and it gave the same error, the example files did work on it's own just an fyi.
And while I could continue from the example build, I don't want to encounter it with no way to fix it if I ever get to that point in the future.

These are files I have in my folder
1712835556372.png


With "nitrofiles" having the same background files from the example code.
1712835628082.png


Any reason why I get the error for having the root set?
Sorry if I put too much info here, I wanted to have all the context possible just in case.
 
Last edited by Chrono_Nightmare,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Xdqwerty @ Xdqwerty: