Tutorial DS Programming for Newbies!

  • Thread starter Foxi4
  • Start date
  • Views 154,578
  • Replies 323
  • Likes 55

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
28,423
Trophies
2
Location
Gaming Grotto
XP
25,876
Country
Poland
I agree with you though to the point that I will even bold it - using a switch is infinitelly less taxing on the CPU then using long set of if/else statements. :)

Though I believe that it's a good idea to do that for clean code, wouldn't the generated assembly be exactly the same?
Something like:
Code:
compare a,#0
jump if not equal, to next compare
//stuff for condition
jump to end of switch/if else block
compare a,#1
jump if not equal, to next compare
//stuff for condition
Nope, it would not, simply because if/if else/else constructs have multiple conditions wheras a switch makes a jump depending on the state of a single variable. In other words, a jump from if to else if will only happen if the first condition is false and the second one is true, otherwise the program will jump to the position of else if present, otherwise it will do nothing. You can create an infinite ammount jumps from the first if statement, you're really only limited by the ammount of available memory, but every next if else creates another condition that needs to be checked, hence it is more taxing. Switches jump over all that by checking the state and jumping only once, if/if else/else jumps from one statement to the next in order.
 

LeRodeur

Well-Known Member
Member
Joined
Dec 12, 2009
Messages
162
Trophies
0
Age
28
XP
170
Country
France
I agree with you though to the point that I will even bold it - using a switch is infinitelly less taxing on the CPU then using long set of if/else statements. :)

Though I believe that it's a good idea to do that for clean code, wouldn't the generated assembly be exactly the same?
Something like:
Code:
compare a,#0
jump if not equal, to next compare
//stuff for condition
jump to end of switch/if else block
compare a,#1
jump if not equal, to next compare
//stuff for condition
As I tried to explain it, switch on Myvar is quite the same as doing a jump to the label Myvar, it doesn't check all the values.. It only do 2 if statement max depending on the range of values used in the switch.
You could take a look at this for more examples :
http://www.eventhelix.com/realtimemantra/basics/CToAssemblyTranslation3.htm
 

CannonFoddr

Regular GBATemp Lurker
Member
Joined
Sep 23, 2006
Messages
4,134
Trophies
0
Age
54
Location
Sitting by computer
Website
www.youtube.com
XP
1,104
Country
Just stumbled across this - nice way to introduce newbies to 'C' programming
I've known a 'little' programming stuff (MANY years ago) like BASIC and PASCAL & I must say that this is a refreshing approach to learning 'C' (where other guides I've looked at seem to assume you already know 'stuff')

Keep up the good work

BTW - I noticed that 'Walthor' said
Ever thought of creating a pdf document with all the tutorials?
- despite foxi4 reply, I thought I'll help out & actually create such a thing. (easy for me to carry around on my Mobile etc for quick reference ;) )

It only contains the Chapters 1-4 so far but being on Filetrip - anyone can update it as-&-when new chapters come out
(I used my Works 'PDF Printer' feature to make this copy)

You'll find 'DS Programming for Newbies.PDF' on Filetrip Here
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
28,423
Trophies
2
Location
Gaming Grotto
XP
25,876
Country
Poland
Just stumbled across this - nice way to introduce newbies to 'C' programming
I've known a 'little' programming stuff (MANY years ago) like BASIC and PASCAL & I must say that this is a refreshing approach to learning 'C' (where other guides I've looked at seem to assume you already know 'stuff')

Keep up the good work

BTW - I noticed that 'Walthor' said
Ever thought of creating a pdf document with all the tutorials?
- despite foxi4 reply, I thought I'll help out & actually create such a thing. (easy for me to carry around on my Mobile etc for quick reference ;) )

It only contains the Chapters 1-4 so far but being on Filetrip - anyone can update it as-&-when new chapters come out
(I used my Works 'PDF Printer' feature to make this copy)

You'll find 'DS Programming for Newbies.PDF' on Filetrip Here
This looks really neat, well done mate! Would you mind carrying on when new chapters are released? An offline version for people on the go sounds like a great idea and I can see that you're doing fine with converting it into PDF form.

I do have a creative comment though, a Table of Contents with links to given pages would probably be a good idea, I'm currently working on one for the online course as it is.
 

CannonFoddr

Regular GBATemp Lurker
Member
Joined
Sep 23, 2006
Messages
4,134
Trophies
0
Age
54
Location
Sitting by computer
Website
www.youtube.com
XP
1,104
Country
Just stumbled across this - nice way to introduce newbies to 'C' programming...Keep up the good work...You'll find 'DS Programming for Newbies.PDF' on Filetrip Here
This looks really neat, well done mate! Would you mind carrying on when new chapters are released? An offline version for people on the go sounds like a great idea and I can see that you're doing fine with converting it into PDF form.

I do have a creative comment though, a Table of Contents with links to given pages would probably be a good idea, I'm currently working on one for the online course as it is.
No problems - I will [try] & keep it as updated as possible (time permitting) ....

As for the table of Contents - I'll have a try & figure out how to do that from within Word, as that's what I used to make it (hopefully it won't be too hard)
FYI - basically all I did was copy/paste your posts,, spread it out a little so that paragraphs weren't split between pages & then use the 'Print as PDF995' option on my work's computer.This 'printed' a PDF file onto the PC instead of on a printer

EDIT: I've found/downloaded the same 'stuff' in work onto home PC (PDF955 printer driver) - seems like the driver DOESN'T allow links from within PDF files (I made a word document that has the links - but when making the PDF the links are 'lost')... still looking for a 'free' PDF editor that'll allow (at least) bookmarks &/or internal links
But there's a new version added to filetrip (remade using a DEMO PDF editor) that now has 'bookmarks' (although chapter 3 seems a little 'off')
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
28,423
Trophies
2
Location
Gaming Grotto
XP
25,876
Country
Poland
It's been a while, hasn't it? About time for the next chapter, huh? I couldn't find time to write lately, but here it is - the next part of our introduction to C!


Introductory Chapter 5 - Loops


Today we'll be having a look at Loops, to be more specific, the for() and while(). In programming, we use Loops to create cyclical action - we put functions we want to use repeatedly in them to save time. As always, we'll have a look at both and compare their features to know when to use each of them.

Let's start with the for() loop and its syntax, shall we?

for(Starting Expression; Testing Expression; Count Expression) {...}

Starting? Testing? Counting? What's all that? Well, let's have a look at a more practical example:
Code:
u8 i=0;
for(i=0;i<5;i++){
iprintf("This is a line of text.\n");
}

As we can see, we created a Variable to be used in the Loop called i, this Variable is incremented once each cycle as long as the Testing expression is true, which here means as long as it is less than 5. Until it reaches this state though, every Statement between the { } brackets will be executed once each cycle aswell! Thus, the end effect is:
This is a line of text.
This is a line of text.
This is a line of text.
This is a line of text.
This is a line of text.

You're going to ask "where's the weird "\n" you've ended the String with, huh? Well, this is the Newline Sign! Using it you can make sure that whatever new string you'll be inputting into the console will be printed in the next line!

Let's compare this for() to a loop we already know, the while() Loop.

while(Condition){...}

Looks a whole lot more simple, huh? Well, it also works slightly differently. As you can see, there is no place to put in the Start Condition, nor do we have a place where we could add or substract from our controlling Variable...

How do we use it then? The while Loop will execute the actions nested between its { } brackets as long as the Condition specified is true.

For example...
Code:
u8 i=0;
while(i!=5){
iprintf("This is a line of text.\n");
i++;
}

The idea here is clear - we have our Variable i which we use as a controller. The Loop prints text into the console with each cycle and then increments the Variable i. After 5 cycles, i reaches 5 and the Looped functions are no longer executed... Yes, you guessed it! The result is:
This is a line of text.
This is a line of text.
This is a line of text.
This is a line of text.
This is a line of text.

As you've seen, we can in fact utilize both Loops to do the exact same thing, but you will also notice that the for() Loop is very much independent - it sets the value for i itself and it also sets how this value will change each cycle. With while(), you have to plot the activation and deactivation of the Loop yourself. Both cases have their advantages and disadvantages so all I'm really going to say is that we will use for() Loops whenever we want a certain function to be repeated a specified number of times and leave the while() Loop for functions that only need to be executed repeatedly when a given event occurs, for example when constructing A.I's, but more on that in the Chapter about game logic later on.

I hope you enjoyed this chapter, even if it's a little bit short. There really isn't much to say about Loop, so bare with me. I'd also like to inform that there's been a slight change in the schedule - we'll jam a chapter about Arrays and Structures before we proceed to strictly DS-specific programming as I don't want to run into unintroduced concepts while we're at it. I'll do my best to introduce both briefly and clearly. Stay tuned and thanks again for reading, see you next time!
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
28,423
Trophies
2
Location
Gaming Grotto
XP
25,876
Country
Poland
Another week has passed, time for another chapter of the guide, right? You bet it is! It's about time to wrap up the very basics of C and move onto subjects of our primary interest - libnds functionality. That said, without further ado I present to you the chapter dedicated to two Containers of Variables - Structures and Arrays!

Introductory Chapter 6: Containers of Variables - Structures and Arrays


Structures and Arrays are nifty containers which will greatly improve our overall work. Rather then working on one Variable at a time, we can construct Arrays and Structures to work on multiple Variables at the same time. We've already seen a few Arrays, but we never really discussed how they work so we'll start with them.

In essence, an Array is a uniform set of numerous Variables of the same Type placed next to eachother that can be refered to using the same name.

Pcm3L.png



We already know how to declare an Array from the previous chapters:


Type ArrayName[NumberOfUnits];


But this is only one of possibilities. An Array declared in this fashion will have no values assigned, just empty slots ready to receive them. You can just as well do this:


Type ArrayName[]={1,2,3};


Here, we are not assigning a "total size" at all - the compiler deduces on its own that initially the Array has 4 slots - for the 1, 2, 3 and the NULL - there are no empty slots.

What's interesting is that you don't have to use all the values in an Array immediately.You may assign values to it later until you reach its maximum Size. For example, you may declare your Array as one with 255 slots while in reality you will be using less then that and add values further as the program progresses:


Type ArrayName[255] = {1,2,3};


Here, we assign values - 1, 2 and 3 to corresponding slots 0, 1 and 2, however, the number of slots is higher than that, thus the rest is left empty and a NULL is appended to them. Keep in mind though that going past the specified Size of the Array will result in assigning out-of-bounds values! You don't want that to happen!

All that said... why are Arrays useful? Afterall, we could just as well declare the exact number of Variables we need, surely declaring them in an Array has some advantages? Well, sometimes you may hold numerous values that refer to pretty much the same thing - having the capability to call them by the same Name is pretty useful. Earlier we saw Arrays of char's - the Array was a collection of signs that were later called as a whole String. Another use for Arrays is that their Values can easily be changed using Looping, like this:

Code:
for(i=0; i=5; i++){
MyArray[i]++;
}

With only a few lines of code we've incremented 6 Variables - MyArray[0] up to MyArray[5]. Normally it would take us 6 lines of code, here we're just looping through an Array and calling its elements using the Variable i.

This shows us how to call specific units within the Array - all you have to do to call up a given element is putting the appropriet number corresponding to the unit into the brackets []. As you can see, an Array can be called as a whole as previously shown, but at the same time you are not losing the capability to call its specific elements like you would normally call Variables, which is a big plus.

Arrays have another interesting feature. What we declared was a single-dimensional Array - a single row of Variables. We are not limited to this though - you can declare multi-dimensional Arrays easily:


MyArray[Rows][Columns];


This is for example a two-dimensional Array. Try to imagine how the Variables are situated in it. Why of course, on a two-dimensional grid. This kind of an Array could be used for example to track two values refering to the same object - for example the height and width of a sprite or its position on the screen.

I won't dwell into the details here - the posibilities in design are endless. What I will mention is the limitation of Arrays.

As I previously said, every element of an Array is of the exact same type. This can be quite a hindrance as even though Arrays are really versatile for holding data, all the data within them has to follow its strict Type rules. What can we do when we require a specific variable that will hold data of two or more types? Why, we create a Structure!


There are numerous ways to create a Structure, but I will only cover my favourite and most see-through method - creating a new type. It is only logical that once no available Type can suit your needs, you create a new one, isn't it? How do we declare a new type? Quite easily, really:

Code:
typedef struct{
type1 Element1;
type2 Element2;
type3 Element3;
} NameOfType;

As you can see, the syntax is quite clear - we create a definition of a type, and it is going to be a structure. The structure type in this template has three elements and its name is NameOfType... but this alone is just a type, how do we declare this structure? Easier than you think:



NameOfType MyStructure;


Yep - you use your newly-defined Type as you would with any other. How do you call the elements? Also rather easily - you call them using the name of the new Structure and the name of its element, here it would be for example:
dH3Re.png
MyStruct.Element1, MyStruct.Element2 or MyStruct.Element3


By using a Structure, you free yourself from the limitation of the Array - you can now use any type for any element freely. Unfortunatelly, you also lose some of the priviledges.

You cannot for example freely cycle through elements with a Loop as shown earlier as they are not numbered - they have separate names.

We'll end our adventure with C here for now... why?

Because what's comming up is libnds Input! I honestly believe that the information we've discussed allows us to jump into DS Programming head first without worrying of getting lost in it. The C introduction will still be expanded as we tackle new subjects, but our knowledge is sufficient for now. Can't wait? Me neither! Stay tuned and remember - do comment! Foxi over and out!
 

BassAceGold

Testicles
Member
Joined
Aug 14, 2006
Messages
495
Trophies
0
XP
420
Country
Canada
What's interesting is that the Array may in fact expand as you assign values to it - there's nothing that's stopping us from making it bigger and bigger as long as we have memory available despite the fact that we declared it as much smaller or with no size at all. Beware though, as this may cause a possible buffer overflow or overlap - you may expand it onto places where other values are kept or overflow the whole memory - when expanding Arrays remember to allocate memory for it first to avoid that, but more on that later.

I think this needs to be clarified to indicate that this only applies for declaring an array of types, otherwise, you need to expand the array first and then assign values to prevent from writing out of bounds in its later use.

Also you can expand structures similarily to arrays simply by making an array of structures.
Code:
NameOfType Mystructure[count];
The structure can be treated like any of the standard types for the most part, in terms of memory handling. Thus, one can also make pointers, dynamically allocate, free, return, and pass through a function argument, for structures among other possibilities.
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
28,423
Trophies
2
Location
Gaming Grotto
XP
25,876
Country
Poland

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
28,423
Trophies
2
Location
Gaming Grotto
XP
25,876
Country
Poland
@[member='CannonFoddr']
You probably will be thrilled about it, but I made another edit to the Arrays and Structures chapter, so do update it after the next one is released. ;) Sorry!
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
28,423
Trophies
2
Location
Gaming Grotto
XP
25,876
Country
Poland
@[member='CannonFoddr']
You probably will be thrilled about it, but I made another edit to the Arrays and Structures chapter, so do update it after the next one is released. ;) Sorry!
Right-o... thanks for the heads up
I'm half-way done with the next chapter, it should be up tomorrow. :)
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
28,423
Trophies
2
Location
Gaming Grotto
XP
25,876
Country
Poland
Practical Use of libnds Chapter 1: Input – Keys and Stylus


With the basic introduction of C behind us, I believe we're ready for what you've all been waiting for – the basics of libnds.

Until now, even with everything we've learned so-far, we were unable to utilize any user input whatsoever, as we didn't know how to use the Keys or the Touchscreen – these are platform-specific afterall. Today we're going to learn how to detect the state of Keys and the Touchscreen and how to use it.

Let's start with Keys. First and foremost, to use Key Input, we need to scan for their use. To do that, we place the function:
scanKeys();

Within the main while(){...} loop of the program. This will initialize the Key scanner and thus allow us to use them as a method of input.

Their use is divided into two portions – Key Detection and State Detection. These are of equal importance – one cannot work without the other, so keep that in mind!

Keys are neatly put into an easy-to-remember structure of Enumerators. We're not going to tackle what exactly Enumerators are, all you need to know that each Key corresponds to a value, the Lid and Touchscreen taps are also treated as a Key. This is the list of all Keys you can use:

Code:
KEY_A = BIT(0)
KEY_B = BIT(1)
KEY_SELECT = BIT(2)
KEY_START = BIT(3)
KEY_RIGHT = BIT(4)
KEY_LEFT = BIT(5)
KEY_UP = BIT(6)
KEY_DOWN = BIT(7)
KEY_R = BIT(8)
KEY_L = BIT(9)
KEY_X = BIT(10)
KEY_Y = BIT(11)
KEY_TOUCH = BIT(12) (Refers to touchscreen tapping)
KEY_LID = BIT(13)

As you can see, each Key has its respective Name. Using those we can create Statements that will depend on their values, but not just them alone. We will also require their State, and for that we have a set of useful functions:

Code:
keysDown();
keysHeld();
keysUp();
keysCurrent();

Down, Held and Up are relatively self-explainatory – Down is the State occouring directly after a button is pressed, Held is a State that occours when the key is pressed and kept down and Up is a State that occours when the key is released. All three return different values when different keys enter the specified state. Current is an interesting State, as rather then Returning a value to a specific State immediatelly, it first detects which state it is.

Now that we know that, we're able to compose our first condition based on Key input!


if(KEY_A & keysHeld()){
Statements;
}

This if statement is quite clear – if the A button is held down, the Statements within the { } will be executed. The Statements will be executed until the State of the Key changes, in this case, when it is Released. You can do the exact same thing with any combination of button + state. To make it easier and more sensible, it's worth to declare some special Variables before you begin your program

Code:
u16 Pressed;
u16 Held;
u16 Released;

...and update them at the beginning of every while(1); cycle.

Code:
Pressed = keysDown();
Held = keysHeld();
Released = keysUp();

This way we save valuable calculation power by checking the States of buttons once each frame at the beginning of the program rather then with each button press.

if(KEY_A & Held){
Statements;
}

Now that we've covered Keys we can safetly progress to the Touchscreen which is also quite simple to use. We'll start by declaring a Variable to hold all the data recovered from the screen:

touchPosition TouchStructure;

We are yet unfamiliar with the type touchPosition - it's a type declared within libnds and platform-specific. It's a Structure type and holds the data on numerous stylus readings:

Code:
u16 px (Pixel X value)
u16 py (Pixel Y value)
u16 rawx (Raw X value)
u16 rawy (Raw Y value)
u16 z1 (Raw cross panel resistance)
u16 z2 (Raw cross panel resistance)

rawx and rawy are exactly what their names imply - raw values read from the screen. What makes them raw? Well, they're not exactly user-friendly as they are not translated to pixel positions on the screen, they're large and require further calculations to be used in pointing and clicking, however they are read much quicker then other values, thus are useful at for example implementing swiping and dragging with the stylus. px and py values are calculated from raw values and refer to specific pixels on the screen. The screen is 192 pixels high and 256 pixels wide, with the top left-hand corner marked as pixel 0,0 - knowing this alone will help you use the px and py values successfuly. As for z1 and z2 values, they refer to the panel resistance and are useful (from what I know) at reading the pressure, however it's not something you'd normally use and thus we won't talk much about them.

You can use any name you feel comfortable with in this declaration rather then "TouchStructure", it doesn't in any way influence the readouts... which we're not getting yet anyways.

To recieve readouts of the stylus position, we need to initialize a screen scan function at the beginning of our main while() loop as we did with the keys. In case of the touchscreen, we use:

touchRead(&TouchStructure);

Sigh, I know what you're going to ask, oh-ever-so-inquisitive reader. "What's that & doing there? That shouldn't be there, right?". Well, yeah, it should. This "&" refers to a Pointer, you don't know what those are yet and for now you don't need to. What I will tell you though is that to save space and calculation power, rather then using the whole structure inside this function, we just Point at the location of the structure in memory with a Pointer.

After using this function, all the readouts from the touchscreen will be immediatelly sent to the TouchVariable structure, out of which we'll be able to draw elements as we normally would with a Structure, as we already know its elements. For example, the position of the Stylus Horizontal-wise and pixel-wise will be kept under TouchVariable.px.

This concludes this Chapter, I hope it was a pleasant read. I'll do my best to include a nice excersize concerning Key and Touchscreen use soon, for now, experiment on your own and if you have any questions or if you'd like to boast a bit with your newly-written code, go ahead and post! It'll only get better from now on! :D

Foxi over and out!
 

smealum

growing up sucks.
Member
Joined
May 1, 2006
Messages
635
Trophies
0
Age
29
Location
SF
Website
www.smealum.net
XP
2,471
Country
United States
I didn't read the tutorials, so I can't say how good they are, but two things kind of ticked me off in the last two chapters :
In essence, an Array is a uniform set of numerous Variables of the same Type placed next to eachother that can be refered to using the same name, ending with a NULL value to signify its end.
LCJIR.png


That's, well, not true ? Null-termination is in no way a requirement for C-style arrays. A '\0' character does signal the end of a C string, but even then it doesn't *have* to be in the last slot of the array. IMO, this drawing should read myarray[0] , myarray[1] , myarray[2]. That means there's no need for the +1 in "Type ArrayName[NumberOfUnits+1];" either. Also, the drawing seems to have inverted value2 and value1 ? Not really important but I figured I might as well point it out while I'm at it.

Code:
KEY_A = BIT(0) (Returns a Value of 1)
KEY_B = BIT(1) (Returns a Value of 2)
KEY_SELECT = BIT(2) (Returns a Value of 3)
KEY_START = BIT(3) (Returns a Value of 4)
KEY_RIGHT = BIT(4) (Returns a Value of 5)
KEY_LEFT = BIT(5) (Returns a Value of 6)
KEY_UP = BIT(6) (Returns a Value of 7)
KEY_DOWN = BIT(7) (Returns a Value of 8)
KEY_R = BIT(8) (Returns a Value of 9)
KEY_L = BIT(9) (Returns a Value of 10)
KEY_X = BIT(10) (Returns a Value of 11)
KEY_Y = BIT(11) (Returns a Value of 12)
KEY_TOUCH = BIT(12) (Returns a Value of 13, refers to touchscreen tapping)
KEY_LID = BIT(13) (Returns a Value of 14)
So first of all, just nitpicking, but BIT() being a preprocessor macro it doesn't "return" anything. But more importantly, BIT(n) is really (1
 
  • Like
Reactions: 1 person

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
28,423
Trophies
2
Location
Gaming Grotto
XP
25,876
Country
Poland
-proof reading-
OUPSIE! Thanks for that, I didn't notice the error in the picture nor did I notice the double && where there's only supposed to be one! See, this is what I meant by "this kind of stuff needs proof-reading".

As for "returning a value", I meant that strictly in a linguistic sense. Assigning "KEY_A" to a Variable is basically equal to assigning the Value "0" to it. It's sort of hard for me to properly phrase it in English, how would you phrase it?

EDIT: Wait, I see what you mean about the Array not ending with a NULL - it had 3 members as specified, [0], [1], [2] as specified and neither of them has to be a NULL - I'm a dummy, you're absolutely right. Sorry about that, I got confused. NULL's are only placed when a given member of the Array hasn't got a value assigned, right? I'll fix that now, thanks. I probably wasn't thinking straight that day lol.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
    Psionic Roshambo @ Psionic Roshambo: So now it's killer weed lol