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
46
Trophies
0
XP
222
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,844
Trophies
3
Location
Gaming Grotto
XP
29,930
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
46
Trophies
0
XP
222
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,844
Trophies
3
Location
Gaming Grotto
XP
29,930
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,844
Trophies
3
Location
Gaming Grotto
XP
29,930
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
2
Trophies
0
Age
29
XP
37
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,

nuclearemerald

New Member
Newbie
Joined
May 20, 2024
Messages
3
Trophies
0
Age
18
XP
8
Country
Portugal
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!
I was wondering, if px and py are calculated with rawx and rawy do you by any chance know what formula is used to convert between the two? Thank in advance
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,844
Trophies
3
Location
Gaming Grotto
XP
29,930
Country
Poland

nuclearemerald

New Member
Newbie
Joined
May 20, 2024
Messages
3
Trophies
0
Age
18
XP
8
Country
Portugal
It's quite possible I've just missed it but unfortunately, I couldn't find anything. The closest I got was the implementation for
C:
touchRead(touchPosition *data)
on the libnds github
C:
//---------------------------------------------------------------------------------
void touchRead(touchPosition *data) {
//---------------------------------------------------------------------------------


    if ( !data ) return;


    data->rawx = __transferRegion()->touchX;
    data->rawy = __transferRegion()->touchY;
    data->px = __transferRegion()->touchXpx;
    data->py = __transferRegion()->touchYpx;
    data->z1 = __transferRegion()->touchZ1;
    data->z2 = __transferRegion()->touchZ2;




}


which used this function from libnds_intenal.h
C:
//---------------------------------------------------------------------------------
typedef struct __TransferRegion {
//---------------------------------------------------------------------------------
    vs16 touchX,   touchY;        // TSC X, Y
    vs16 touchXpx, touchYpx;    // TSC X, Y pixel values
    vs16 touchZ1,  touchZ2;        // TSC x-panel measurements
    vu16 buttons;                // X, Y, /PENIRQ buttons
    time_t    unixTime;
    struct __bootstub *bootcode;
} __TransferRegion, * __pTransferRegion;


#define transfer (*(__TransferRegion volatile *)(0x02FFF000))


static inline void setTransferInputData(touchPosition *touch, u16 buttons)
{
    transfer.buttons = buttons;
    transfer.touchX = touch->rawx;
    transfer.touchY = touch->rawy;
    transfer.touchXpx = touch->px;
    transfer.touchYpx = touch->py;
    transfer.touchZ1 = touch->z1;
    transfer.touchZ2 = touch->z2;
}
static inline
__TransferRegion volatile * __transferRegion() {
    return &transfer;
}
(idk if the other code is relevant but I left it in just in case)
I believe transfer points to a memory address on the ds but I don't necessarily know what that means. Or it's something else and I'm just too dumb to see it XD. That is always a possibility.
 

Foxi4

Endless Trash
OP
Global Moderator
Joined
Sep 13, 2009
Messages
30,844
Trophies
3
Location
Gaming Grotto
XP
29,930
Country
Poland
It's quite possible I've just missed it but unfortunately, I couldn't find anything. The closest I got was the implementation for
C:
touchRead(touchPosition *data)
on the libnds github
C:
//---------------------------------------------------------------------------------
void touchRead(touchPosition *data) {
//---------------------------------------------------------------------------------


    if ( !data ) return;


    data->rawx = __transferRegion()->touchX;
    data->rawy = __transferRegion()->touchY;
    data->px = __transferRegion()->touchXpx;
    data->py = __transferRegion()->touchYpx;
    data->z1 = __transferRegion()->touchZ1;
    data->z2 = __transferRegion()->touchZ2;




}


which used this function from libnds_intenal.h
C:
//---------------------------------------------------------------------------------
typedef struct __TransferRegion {
//---------------------------------------------------------------------------------
    vs16 touchX,   touchY;        // TSC X, Y
    vs16 touchXpx, touchYpx;    // TSC X, Y pixel values
    vs16 touchZ1,  touchZ2;        // TSC x-panel measurements
    vu16 buttons;                // X, Y, /PENIRQ buttons
    time_t    unixTime;
    struct __bootstub *bootcode;
} __TransferRegion, * __pTransferRegion;


#define transfer (*(__TransferRegion volatile *)(0x02FFF000))


static inline void setTransferInputData(touchPosition *touch, u16 buttons)
{
    transfer.buttons = buttons;
    transfer.touchX = touch->rawx;
    transfer.touchY = touch->rawy;
    transfer.touchXpx = touch->px;
    transfer.touchYpx = touch->py;
    transfer.touchZ1 = touch->z1;
    transfer.touchZ2 = touch->z2;
}
static inline
__TransferRegion volatile * __transferRegion() {
    return &transfer;
}
(idk if the other code is relevant but I left it in just in case)
I believe transfer points to a memory address on the ds but I don't necessarily know what that means. Or it's something else and I'm just too dumb to see it XD. That is always a possibility.
It’s possible - you’d have to ask on the devkitPro board/the libnds board. My impression of this was always that one is a measurement of what the touch IC *thinks* is happening whereas the other is an actual, accurate number upon calibration and narrowed down to a pixel. A raw value is nice and fast to use for something like determining the direction of a swipe, but for anything requiring accuracy you wouldn’t use it anyway, so I never delved into it. Raw values have limited utility besides fast access.
 

nuclearemerald

New Member
Newbie
Joined
May 20, 2024
Messages
3
Trophies
0
Age
18
XP
8
Country
Portugal
It’s possible - you’d have to ask on the devkitPro board/the libnds board. My impression of this was always that one is a measurement of what the touch IC *thinks* is happening whereas the other is an actual, accurate number upon calibration and narrowed down to a pixel. A raw value is nice and fast to use for something like determining the direction of a swipe, but for anything requiring accuracy you wouldn’t use it anyway, so I never delved into it. Raw values have limited utility besides fast access.
oh ok I might try asking there then but tysm anyway for the help :lol:
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
  • K3Nv2 @ K3Nv2:
    why
  • Xdqwerty @ Xdqwerty:
    @K3Nv2, it's not funny
  • K3Nv2 @ K3Nv2:
    ok
  • BigOnYa @ BigOnYa:
    Wut?
  • K3Nv2 @ K3Nv2:
    That's not funny
    +2
  • Psionic Roshambo @ Psionic Roshambo:
    So two cannibals where eating a clown and one says to the other. Hey does this taste funny to you?
    +2
  • K3Nv2 @ K3Nv2:
    What do you call a slow car? Retired
    +1
  • Psionic Roshambo @ Psionic Roshambo:
    Did you hear about the police car that someone stole the wheels off of? The police are working tirelessly to find the thieves.
    +2
  • K3Nv2 @ K3Nv2:
    A firefighter got arrested for assault his main claim was what I was told he was on fire
    +2
  • BigOnYa @ BigOnYa:
    What do you call a hooker with a runny nose? Full
    +2
  • Psionic Roshambo @ Psionic Roshambo:
    What do you tell a woman with two black eyes? Nothing you already told her twice!
  • K3Nv2 @ K3Nv2:
    Diddy also works
  • K3Nv2 @ K3Nv2:
    A scientist heard the word batman so he put a naked lady in a cage with a bat
  • Psionic Roshambo @ Psionic Roshambo:
    Chuck Norris won a staring contest, with the sun.
  • K3Nv2 @ K3Nv2:
    A vampires favorite thing to do is moon you
  • BigOnYa @ BigOnYa:
    What's the difference between an airplane, and Ken's mom? Not everyone has been in an airplane.
  • K3Nv2 @ K3Nv2:
    What's the difference between @BigOnYa and his wife? Nothing both want to bone me
    +3
  • RedColoredStars @ RedColoredStars:
    How much wood could a wood chuck chuck if a wood chuck could chuck norris
    +1
  • BakerMan @ BakerMan:
    how do i know? you're a guy, and he wants to bone every guy on this site (maybe, idk)
    +1
  • K3Nv2 @ K3Nv2:
    He wants to bone anything with a dick
    +1
  • Xdqwerty @ Xdqwerty:
    Good night
    +1
  • BigOnYa @ BigOnYa:
    Nighty night, big day tomorrow. Congrats.
    K3Nv2 @ K3Nv2: https://www.instagram.com/reel/C7iLZ35NrQt/?igsh=MWd2Z3U0dmNlMmNxcw==