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,825
Trophies
3
Location
Gaming Grotto
XP
29,850
Country
Poland
@plasturion Just try everything out and it work! It took a bit of experimenting with grit but everything seems to work. Looks like I have the basics up running for NDS development! Thank you everyone, including @Foxi4, @plasturion, and @akbat for all your help! :) :yaynds:

:nds:
My general recommendation when it comes to “glitchy sprites” is to not use any formats that compress the image, otherwise you run the risk of your transparencies not working correctly. If your sprites are surrounded by a halo of garbage pixels, chances are you’ve compressed the image at some point and what might seem like a solid colour actually isn’t solid at all. JPG’s and the like are non-starters, the graphics you use should be as raw as possible.
 

BlueFalconNDS

Member
Newcomer
Joined
Aug 16, 2023
Messages
20
Trophies
0
XP
16
Country
Canada
I got some questions about the background layers and the modes. I see that nflib say to pick from mode 0, 2, or 5. What happen to mode 1, 3, 4, and 6?

Another question relates about the layers. I'm using mode 0, so that's 4 (0-3) static layers. I'm messing around with the "bg" graphics example from nflib by getting each background image and modifying by putting random doodles in image to see how it will render. I see the changes I made in layer 3 and 2, but when I got to layer 1 I get a error of saying: "Can't allocate 2 blocks of tiles for layer_1 background Free 32 kb of VRAM or try to reload all Bg's again Error code 107" I couldn't find error code 107 anywhere, and I'm curious and want to know what it this error really means, as if it has something to do with colors, I thought each layer can have 8 bit, 256 colors.

I got all the basics running so I just want to mess around with examples to learn more about the NDS hardware and how it really works. (Hopefully I'm not bombarding this thread with my question, and if this is the right place to ask this) Thanks!

:nds:
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,850
Country
Poland
I got some questions about the background layers and the modes. I see that nflib say to pick from mode 0, 2, or 5. What happen to mode 1, 3, 4, and 6?

Another question relates about the layers. I'm using mode 0, so that's 4 (0-3) static layers. I'm messing around with the "bg" graphics example from nflib by getting each background image and modifying by putting random doodles in image to see how it will render. I see the changes I made in layer 3 and 2, but when I got to layer 1 I get a error of saying: "Can't allocate 2 blocks of tiles for layer_1 background Free 32 kb of VRAM or try to reload all Bg's again Error code 107" I couldn't find error code 107 anywhere, and I'm curious and want to know what it this error really means, as if it has something to do with colors, I thought each layer can have 8 bit, 256 colors.

I got all the basics running so I just want to mess around with examples to learn more about the NDS hardware and how it really works. (Hopefully I'm not bombarding this thread with my question, and if this is the right place to ask this) Thanks!

:nds:
Different modes have different type layers available on different screens. In my guide I show how to use the (arguably most popular) Mode_0 which offers 4x 2D Text/Tiled layers, but there are other options including 3D, rotating or Bitmap layers. Read video.h documentation for further details:

https://libnds.devkitpro.org/video_8h.html
 

BlueFalconNDS

Member
Newcomer
Joined
Aug 16, 2023
Messages
20
Trophies
0
XP
16
Country
Canada
Different modes have different type layers available on different screens. In my guide I show how to use the (arguably most popular) Mode_0 which offers 4x 2D Text/Tiled layers, but there are other options including 3D, rotating or Bitmap layers. Read video.h documentation for further details:

https://libnds.devkitpro.org/video_8h.html
Oh Ok yeah that makes sense, mode 0 is probably the most friendliest to start with, just wanted to know if the other modes are supported by nflib as it only specifically mentions mode 0, 2, 5 in the docs.

@Foxi4 would you know anything about my second question in the previous post, regarding the error code 107?
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,850
Country
Poland
Oh Ok yeah that makes sense, mode 0 is probably the most friendliest to start with, just wanted to know if the other modes are supported by nflib as it only specifically mentions mode 0, 2, 5 in the docs.

@Foxi4 would you know anything about my second question in the previous post, regarding the error code 107?
Seems like you ran out of memory in the associated bank, which is odd because NFLib technically supports unlimited backgrounds. Not sure what’s up without a code snippet.

EDIT: Actually, I’m taking a bunch of crap. Your background has too many tiles, that’s why you ran out of space. “Infinite” just refers to the physical dimensions of the map, you’re still limited by the amount of VRAM you have. Most people design their backgrounds with this in mind and use various tiling software to draw them within a specific limit.
 
  • Like
Reactions: BlueFalconNDS

BlueFalconNDS

Member
Newcomer
Joined
Aug 16, 2023
Messages
20
Trophies
0
XP
16
Country
Canada
Seems like you ran out of memory in the associated bank, which is odd because NFLib technically supports unlimited backgrounds. Not sure what’s up without a code snippet.

EDIT: Actually, I’m taking a bunch of crap. Your background has too many tiles, that’s why you ran out of space. “Infinite” just refers to the physical dimensions of the map, you’re still limited by the amount of VRAM you have. Most people design their backgrounds with this in mind and use various tiling software to draw them within a specific limit.
Oh you know what, that make sense, so is it that my background as whole has too many tiles, or a layer with too many tiles?

EDIT: This may be a dumb question as I did some reading, and I’m pretty sure the layer has too many tiles as the error specifically points out the layer.

EDIT 2: Someone can fact check me on this, as I read a Static background can have 1024 unique tiles, so I’m pretty sure that means mode 0 with 4 static background can for 4096 unique tiles
 
Last edited by BlueFalconNDS,

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,850
Country
Poland
Oh you know what, that make sense, so is it that my background as whole has too many tiles, or a layer with too many tiles?

EDIT: This may be a dumb question as I did some reading, and I’m pretty sure the layer has too many tiles as the error specifically points out the layer.

EDIT 2: Someone can fact check me on this, as I read a Static background can have 1024 unique tiles, so I’m pretty sure that means mode 0 with 4 static background can for 4096 unique tiles
The question is more complicated than you think. You should understand not only what limits you, but also why those limitations are there in the first place. There are two main ones here - space in your VRAM banks and the maximum amount of tiles you can display at any given time.

The backgrounds you’re using have a 16-bit tile index, this permits you to use 1024 tiles at a time, so there’s your “maximum”. Now, why is that? You have 16-bits, 2 bits are reserved for flipping/mirroring, 4 bits are your palette number, this leaves you with a 10-bit range for your tile space, which translates to 0-1023. There’s your hard limit of 1024 tiles per background.

As for the second limitation, in NFLib you have 96KB of space reserved for tiles and 32KB reserved for maps *per screen* (grand total of 128KB, see chapter on VRAM banks), and you’re using a 256 (8-bit) colour palette. So long as you don’t exceed that number for all of your layers at any given time, you’re golden.

Now, you might ask how that breaks down into tiles, and that’s a fair question. Let’s do some math. The tiles are 8 by 8 and use a 256 (8-bit) colour depth - 8x8x8 = 512 bits. Every pixel on a tile is basically 1 byte, so 1 tile equals 64 bytes. This suggests that, per screen, you’re working with an absolute maximum of around 1500 tiles in VRAM, give or take. So, can you have more than 1024 then? Yes, but actually no - they can sit there in memory, but you’re working within a hard limit.

You have to ask yourself the question “do I want this many?”, and the answer is absolutely not, because you’re running into the very real danger of crashes like this. You do not want to run out of VRAM during runtime, so you necessarily must budget accordingly. You might think that technically you’re permitted to display 4096 tiles, but the DS physically can’t do that in this arrangement, you don’t have enough VRAM to display them simultaneously.

Does that make sense? Keep in mind, I can’t stress enough that I’m pretty rusty, so perhaps someone who’s touched a DS development environment within the last 10 years will correct me, but this makes sense in my head based on NFLib and libnds documentation. :P
As far I know nflib support only 256 (8-bit) colors sprites.
NDS engine support also 4-bit and 16-bit modes for sprites but that need some mod extension for nflib.
I would like to use 16-colors sprites and backgrounds, you could load bigger tileset (or frameset) in VRAM.
The tile index is 16-bit regardless of whether the background uses 8 or 4 bits per pixel (BgType_Text8bpp or BgType_Text4bpp), see BgType reference in libnds:

https://libnds.devkitpro.org/group__background__api__group.html#ga421d43ca799fd0c471335846da06cae1

That’s your maximum. You have the option of using an 8-bit tile index for a rotating, scalable background (BgType_Rotation) which is sometimes handy for those classic “giant pseudo sprites” that are actually a background layer. This used to get used a lot in retro games to depict huge bosses that would be impractical to display using traditional sprites. There’s also an extended version of this type (BgType_ExRotation) that uses a 16-bit index for a truly giant rotating, scalable background, useful for something like the special stage in Sonic the Hedgehog.

By default, a background’s colour depth is 8-bit and the tile index is 16-bit, as described in bgInit() and bgInitSub():

https://libnds.devkitpro.org/group__background__api__group.html#gaf2ba2b415bf8e02ccc0b30c55f878496

If you *could* use 16bpp sprites/backgrounds in tiled mode (which I don’t think is possible using the baked in types, it’s not an option in libnds, short of just using the 3D engine instead), all you’d achieve is a higher size of tiles in VRAM, you wouldn’t get to use more of them. In fact, you’d limit yourself to less due to the bank size.
 
  • Like
Reactions: plasturion

plasturion

temporary hermit
Member
Joined
Aug 17, 2012
Messages
1,216
Trophies
2
Location
Tree
XP
3,505
Country
Poland
Thanks for the clear things out how the map file addressing is constructed, I knew that some parameters are for tile flip and mirror, seems i didn't know everything... you say 2 bits that left are for tile addressing, that's how it works, ok. The mysterious 10-bit addressing has been releaved now.

I didn't make full load test, but once i was able to load 40KB map and nflib somehow suported it. (256x5120px). I remember nflib often screamed for not enough vram with no reason, but maybe it was false alarm or I don't remember. I don't know which bank is selected as is doing automaticly but we must believe and trust it is for our good. And it seems I'm rusty too.

Also i said before that it may be diffcult if you want to use nflib for init filesystem in DSi mode. I used old relase and noticed that actually nflib is still maintenanced on github and latest one release should work fine in this matter. I peeked how nf_basic.c looks and NF_SetRootFolder should also switch to DSi SD card filesystem. There's even support for new BlockDS SDK?... just wow nf_lib
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,850
Country
Poland
When I scroll background out of screen, part of this BG appears from opposite side. Can i do something with it?
According to libnds backgrounds always wrap, you can only disable the feature on affine (rotating/scaling) backgrounds. What you want to do is check when you’ve scrolled to the end of the background and if you have, disable further scrolling in that direction.

Thanks for the clear things out how the map file addressing is constructed, I knew that some parameters are for tile flip and mirror, seems i didn't know everything... you say 2 bits that left are for tile addressing, that's how it works, ok. The mysterious 10-bit addressing has been releaved now.

I didn't make full load test, but once i was able to load 40KB map and nflib somehow suported it. (256x5120px). I remember nflib often screamed for not enough vram with no reason, but maybe it was false alarm or I don't remember. I don't know which bank is selected as is doing automaticly but we must believe and trust it is for our good. And it seems I'm rusty too.

Also i said before that it may be diffcult if you want to use nflib for init filesystem in DSi mode. I used old relase and noticed that actually nflib is still maintenanced on github and latest one release should work fine in this matter. I peeked how nf_basic.c looks and NF_SetRootFolder should also switch to DSi SD card filesystem. There's even support for new BlockDS SDK?... just wow nf_lib
The DS is not the best at garbage collection - if you’re not 100% that your old unused resources have been destroyed, they’re probably still in memory, hence VRAM going bananas. It’s also worth noting that the actual size of your background is not equivalent to the height and width of your background since repeating tiles don’t “count” and NFLib supports infinite scrolling. At that point your only limit is the size of the map. Thanks to bank swapping, in theory you could make a background infinitely large.
 

Valkyrience

Member
Newcomer
Joined
Aug 12, 2023
Messages
14
Trophies
0
Age
25
XP
27
Country
Ukraine
According to libnds backgrounds always wrap, you can only disable the feature on affine (rotating/scaling) backgrounds. What you want to do is check when you’ve scrolled to the end of the background and if you have, disable further scrolling in that direction.
But if I need to scroll it out and dont see it on other side? There are some way?
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,850
Country
Poland
But if I need to scroll it out and dont see it on other side? There are some way?
The easiest way to do it is to stack blank tiles around your main background, they don’t cost you much extra memory (the tile already exists). For instance, if you have a 256x256 scrollable area, make it 512x512 instead and center it, so you have a 128px “edge” surrounding it, then stop scrolling when you reach a desired spot. It won’t wrap around until you’re more than half-way past the “edge”, if that makes sense.
 

Valkyrience

Member
Newcomer
Joined
Aug 12, 2023
Messages
14
Trophies
0
Age
25
XP
27
Country
Ukraine
The easiest way to do it is to stack blank tiles around your main background, they don’t cost you much extra memory (the tile already exists). For instance, if you have a 256x256 scrollable area, make it 512x512 instead and center it, so you have a 128px “edge” surrounding it, then stop scrolling when you reach a desired spot. It won’t wrap around until you’re more than half-way past the “edge”, if that makes sense.
I`ve thought about it and alredy done it. I`ve made my BGs 512x512 instead of 256x256 and fill free space with empty tiles. But now i can`t scroll this BG on negative value (it starts glitching) for some reason. Why could it be?
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,850
Country
Poland
I`ve thought about it and alredy done it. I`ve made my BGs 512x512 instead of 256x256 and fill free space with empty tiles. But now i can`t scroll this BG on negative value (it starts glitching) for some reason. Why could it be?
If there’s nothing else underneath and you’re using a transparent tile, the display is likely to go bananas. Hard to say without looking at it, but this should work. If this is your bottom layer, use black tiles as filler.
 

Valkyrience

Member
Newcomer
Joined
Aug 12, 2023
Messages
14
Trophies
0
Age
25
XP
27
Country
Ukraine
If there’s nothing else underneath and you’re using a transparent tile, the display is likely to go bananas. Hard to say without looking at it, but this should work. If this is your bottom layer, use black tiles as filler.
This glitch give me empty tiles if I scroll on value greater then -256, and random tiles from my BG on value less than-256. What should I give you to got more help from you?
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,850
Country
Poland
This glitch give me empty tiles if I scroll on value greater then -256, and random tiles from my BG on value less than-256. What should I give you to got more help from you?
Right, I see the problem. Did you change the background width/height in your code? Are you now starting from an adjusted position (0, 0 is now in the void for you if you’ve surrounded the background with nothing)? Is there anything underneath this layer? What are you testing on?
 

Valkyrience

Member
Newcomer
Joined
Aug 12, 2023
Messages
14
Trophies
0
Age
25
XP
27
Country
Ukraine
Right, I see the problem. Did you change the background width/height in your code? Are you now starting from an adjusted position (0, 0 is now in the void for you if you’ve surrounded the background with nothing)? Is there anything underneath this layer? What are you testing on?
I've put my BG on right left corner of enlarged bmp, so I don't need to correct start position. Now there is nothing underneath this layer, but later will another layer.
Post automatically merged:

Or it is necessarily exactly to surround it with empty tiles?
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,825
Trophies
3
Location
Gaming Grotto
XP
29,850
Country
Poland
I've put my BG on right left corner of enlarged bmp, so I don't need to correct start position. Now there is nothing underneath this layer, but later will another layer.
Post automatically merged:

Or it is necessarily exactly to surround it with empty tiles?
If you want to go into negative values I would, and you definitely should have something underneath if you’re exposing empty space.
 

Valkyrience

Member
Newcomer
Joined
Aug 12, 2023
Messages
14
Trophies
0
Age
25
XP
27
Country
Ukraine
If you want to go into negative values I would, and you definitely should have something underneath if you’re exposing empty space.
I`ve put a layer that cover all screen underneathe the scrolled layer, so emptyness is covered by it now. But it didn`t change anything.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    BakerMan @ BakerMan: It's Mayday fellas