-
Notifications
You must be signed in to change notification settings - Fork 0
3.1. Let's hello world (on our own)
Cool thing about devkitARM & libnds is that they let you literally #include <stdio.h>
and printf
C-style as you'd usually do on a boring school day in the CS class. Except for some small things that worth be noted.
Let's have the following example:
#include <nds.h>
#include <stdio.h>
int main()
{
consoleDemoInit();
iprintf("Hello world!");
while(1)
{
swiWaitForVBlank();
}
}
We meet a new good friend called consoleDemoInit
, which does the "dirty" job of initializing a console-like interface for us. If you ran the example from chapter 3, you saw that the ROM does absolutely nothing apart from showing two impecable white screens. By calling consoleDemoInit
, one of the screens turns black and we can basically use it as our own terminal on the DS.
Note that in this example we can print the text outside the loop (at the initialization step) because "Hello world!"
is a static string and it's unlikely we would need to change that in the game loop. We will later face situations where we need to work with variable text and therefore print inside the while
loop;
Alright, all clear, but... what in the world is that iprintf
? Let me tell you it is the same as printf
, but without a drawback. Every DS programming forum you visit will tell you the exact same story: iprintf
is a light-weight implementation of printf
that doesn't involve floating point arithmetics which are too harsh on the ARM9 and may dramatically affect the execution time. Oh yes, libnds allows you to use both printf
and iprintf
, but let's try something out:
The code above but using ... | .NDS ROM size |
---|---|
printf |
171KB |
iprintf |
150KB |
Can you spot the difference? printf
produces a larger in size ROM, which means more code to be executed to do the very same thing as iprintf
. So, I can surely say printf
is a no-no in NDS programming.
What's more, iprintf
behaves exactly the same on the DS as printf
on a PC. So, does that mean we are permitted formatted strings and stuff?
Asolutely! Consider the following code:
#include <nds.h>
#include <stdio.h>
int main()
{
consoleDemoInit();
int x=0;
while(1)
{
swiWaitForVBlank();
iprintf("x=%d\n",x);
x++;
}
}
Not much rocket science here, so let's just see the ROM in action:
Well... it works as expected.
Now if you are asking, you can do a lot of fun tricks only with iprintf
. Here are some useful examples I can think of:
I know, it's scary-looking at first glance, but let's make this line seem less aggressive:
inline void clrscr() { iprintf("\e[1;1H\e[2J"); }
Now I guess it's pretty clear what it does. It CLeaRs SCReen. So, what? Well, this:
while(1)
{
swiWaitForVBlank();
clrscr();
iprintf("x=%d",x++);
}
Now the program at least looks more natural to the human eye:
Another crazy beast that we put into a body of a cute doggy:
inline void goto_xy(int x,int y) { iprintf("\033[%d;%dH", y, x); }
That being said, how about ...?
goto_xy(14,7);
iprintf("x=%d",x);
Well, that a lot better:
Yeah, sure! For that we only need to learn some little additional facts.
Meet DeSmuME's debugging Tools, and from them the Palette Viewer!
There's a lot to say about palettes, but now we'll focus on the Sub Engine Background palette, which looks like this:
Surprisingly, we see colors! And guess what? They're the same as the Windows' 16 system color. Does that mean we can print something like "iprintf(“\033[0;31m”);"
and get a cosy dark red text? Well yes, but actually no. Not all ANSI color codes work with libnds. To get the red color, you'll need iprintf("\x1b[31m");
.
Fun fact: unlike Windows, on DS you can change the console system colors! That refrains to overriding the color code in the background palette:
// replace the red color with orange
// As we see in the picture above, console color 1 (red) has index 31=0x1F, therefore:
BG_PALETTE_SUB[0x1F] = RGB15(15,11,0);
// set text foreground
iprintf("\x1b[31m");
iprintf("x=%d\n",x++);
There are also more advanced console tricks which imply knowledge about video engines & representation and memory banks, but we'll discuss that later. Actually, I can name some of them right here:
- Make console appear on top screen (that's actually easy to achieve, try playing with
lcdMainOnTop()
,lcdMainOnBottom()
,lcdSwap()
after initing console) - Have consoles on both screens
- Console background image (for enhanced Kali Linux experience)
- Override charset images and create your new font/special characters
libnds Practical Wiki - This is an independent work of learning and exposing the facts about NDS programming. I am not affiliated in any way with Nintendo, devkitPro organization or libnds developers.