Homebrew ctrulib sensetive key press

ground

Well-Known Member
OP
Member
Joined
Mar 22, 2007
Messages
907
Trophies
0
XP
572
Country
Netherlands
hello, since i m trying to create a game written in c, i got into another strange problem with ctrulib.
here it is:
I created a start menu for my game. I got into some problems with i could solve (like flickering selector in front of the option, and a really "sensitive"key press, meaning that if i press the key one time, it can skip up to 3 options).

Now the menu was working correctly i wanted to clean up my code and copied every function for it in another .c file. But right after I did the the menu got really sensitive again (without changing the core code).

I Think i know why it happens, as it scanning for the keysdown is included in the while loop, which happens really fast. so it can scan it pressed 3 times while i am actually pressing it one time (but then, what is the difference between hidKeysDown and hidKeysHeld?)

but right now I am riddled with this, so does anybody have an idea on how to "fix"this?
here is my part of the code

menu[0] = 0;
menu[1] = 1;
hidScanInput();
kDown = hidKeysDown();
enum Menu{
single = 0, multi = 1, highscores = 2, exit = 3
};
drawpicture(0);
drawline(5, 5, 315, 5, 47, 88, 17);
drawline(5, 5, 5, 235, 47, 88, 17);
drawline(5, 235, 315, 235, 47, 88, 17);
drawline(315, 5, 315, 235, 47, 88, 17);
printf("\x1b[10;3HSingle Player");
printf("\x1b[12;3HMulti Player");
printf("\x1b[14;3HHighscores");
printf("\x1b[16;3HExit");
printf("\x1b[28;24HVersion: %s", version);
while (true)
{
hidScanInput();
kDown = hidKeysDown();

if (kDown&KEY_DDOWN)
startselector(+1);
if (kDown&KEY_DUP)
startselector(-1);
if (kDown&KEY_A)
{
if (menu[0] == single)
start_single();
if (menu[0] == multi)
start_multi();
if (menu[0] == highscores)
start_highscores();
if (menu[0] == exit)
break;
}
//printf("\x1b[18;3H%d %d", menu[0], menu[1]);
if (menu[1] != menu[0])
{
clearrow1();// this clears the row with the "selector(X)"
if (menu[0] == single)
printf("\x1b[10;1HX ");
if (menu[0] == multi)
printf("\x1b[12;1HX ");
if (menu[0] == highscores)
printf("\x1b[14;1HX ");
if (menu[0] == exit)
printf("\x1b[16;1HX ");
}
if (kDown & KEY_START) break;
menu[1] = menu[0];

}
 

Foxi4

Endless Trash
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,821
Country
Poland
If ctrulib is anything like libnds, which it probably is, Held is a constant state between pressing the button till the button is released wheras Down is a single instance of pressing a button. If you're pressing the key for, say, 30 frames (half a second @ 60 FPS), Down will return 1 once wheras Held will return 1 30 times (once each frame).
 

ground

Well-Known Member
OP
Member
Joined
Mar 22, 2007
Messages
907
Trophies
0
XP
572
Country
Netherlands
You can try hidKeysUp();
this will always return true if the key is not pressed , so that is not gonna work ;).
If ctrulib is anything like libnds, which it probably is, Held is a constant state between pressing the button till the button is released wheras Down is a single instance of pressing a button. If you're pressing the key for, say, 30 frames (half a second @ 60 FPS), Down will return 1 once wheras Held will return 1 30 times (once each frame).
ah i see, but then i am still flabbergasted why it suddenly is so sensitive. Because right now it is useless:P.
 

Foxi4

Endless Trash
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,821
Country
Poland
this will always return true if the key is not pressed , so that is not gonna work ;).

ah i see, but then i am still flabbergasted why it suddenly is so sensitive. Because right now it is useless:P.
Is there any remote possibility that you're calling the "move menu pointer" function several times?

EDIT: Just noticed the code snippet lol, somehow it escaped my attention. You're calling hidScanInput() twice - why? AFAIK you should only use it once in your main(), either at the end or at the beginning of a frame.
 

Technicmaster0

Well-Known Member
Member
Joined
Oct 22, 2011
Messages
4,406
Trophies
2
Website
www.flashkarten.tk
XP
3,496
Country
Gambia, The
this will always return true if the key is not pressed , so that is not gonna work ;).

ah i see, but then i am still flabbergasted why it suddenly is so sensitive. Because right now it is useless:P.
kDown is only true when a key is pressed in this moment, kHeld is true while the key is held and kUp is only true when it gets released. (at least that's the case for me).
 
  • Like
Reactions: ground

Foxi4

Endless Trash
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,821
Country
Poland
kDown is only true when a key is pressed in this moment, kHeld is true while the key is held and kUp is only true when it gets released. (at least that's the case for me).
That's correct. Seems like it is the same as in libnds then - fancy. :P Now, I personally wouldn't use Up as a trigger for a button press event simply because it might cause input lag (say, the player wants to "jump" but the character only reacts after the button is released which is not a thing players are naturally inclined to do - they're inclined to hold the button, so you either use Down or Held), I'd probably look for the cause of this problem elsewhere rather than go for that solution.
 

Technicmaster0

Well-Known Member
Member
Joined
Oct 22, 2011
Messages
4,406
Trophies
2
Website
www.flashkarten.tk
XP
3,496
Country
Gambia, The
That's correct. Seems like it is the same as in libnds then - fancy. :P Now, I personally wouldn't use Up as a trigger for a button press event simply because it might cause input lag (say, the player wants to "jump" but the character only reacts after the button is released which is not a thing players are naturally inclined to do - they're inclined to hold the button, so you either use Down or Held), I'd probably look for the cause of this problem elsewhere rather than go for that solution.
Sometimes Up is usefull, too. Probably mostly when using the touchscreen (select the sprite that's below the finger when it gets released and not the sprite that is selected when it gets pressed).
 

Foxi4

Endless Trash
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,821
Country
Poland
Sometimes Up is usefull, too. Probably mostly when using the touchscreen (select the sprite that's below the finger when it gets released and not the sprite that is selected when it gets pressed).
That is correct - in that scenario using down and up to pick up and release wastes less cycles than checking for held each frame.
 

ground

Well-Known Member
OP
Member
Joined
Mar 22, 2007
Messages
907
Trophies
0
XP
572
Country
Netherlands
Is there any remote possibility that you're calling the "move menu pointer" function several times?

EDIT: Just noticed the code snippet lol, somehow it escaped my attention. You're calling hidScanInput() twice - why? AFAIK you should only use it once in your main(), either at the end or at the beginning of a frame.
well, i used it twice because the second one is in the while() loop. If i don't put it there it won't look for the "kDown"and so my menu becomes unresponsive. But i am checking if i might called the move menu pointer function twice (i highly doubt it, but you'll never know). And i will also test if keyUp works better than keyDown.

edit:
hmm strange,
even if i use hidKeysUp(); the pointer is still moving too fast (even when i held the key and not releasing it:S)

edit2:
ok this is how it works now:
if i print something on the screen after the menu pointer moved, it will work normally, but if if command the printf line out, it will go crazy (maybe because printf takes a frame or so?

edit 3:
ok, so a simple flushbuffer and the end of every loop will solve the problem. No need for swapbuffers (as it would make images you use flickering)
 
Last edited by ground,

dark_samus3

Well-Known Member
Member
Joined
May 30, 2015
Messages
2,372
Trophies
0
XP
2,042
Country
United States
well, i used it twice because the second one is in the while() loop.

Yes but what is the point of the first one? You said it was a snippet so obviously we aren't getting the whole picture, so maybe it's used later on? Also why the while loop at all, why not just have the code out there, again this is probably something else I'm missing because I don't have the full code
 

Foxi4

Endless Trash
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,821
Country
Poland
He's exactly right. You're running a loop in a loop since main() is already looping with the condition of while(1). There's no reason for you to check for inputs outside of that, just log them. Initialize your menu outside of the main loop and manipulate it inside of it.
 

ground

Well-Known Member
OP
Member
Joined
Mar 22, 2007
Messages
907
Trophies
0
XP
572
Country
Netherlands
Yes but what is the point of the first one? You said it was a snippet so obviously we aren't getting the whole picture, so maybe it's used later on? Also why the while loop at all, why not just have the code out there, again this is probably something else I'm missing because I don't have the full code
oh yeah i see, well that is not used anyore, a had a breakpoint there to check some values. but I took it out now, thanks:)

The while loop is there because it is a menu, otherwise it will display it once and you can't move the pointer.

He's exactly right. You're running a loop in a loop since main() is already looping with the condition of while(1). There's no reason for you to check for inputs outside of that, just log them. Initialize your menu outside of the main loop and manipulate it inside of it.

well the thing is that I have more than 1 menu. In fact the whole program is based on different menu's. But i see what you are saying. After I am done with all the bigger coding and testing I need to rewrite and clean most of it up ;)
 
Last edited by ground,

dark_samus3

Well-Known Member
Member
Joined
May 30, 2015
Messages
2,372
Trophies
0
XP
2,042
Country
United States
oh yeah i see, well that is not used anyore, a had a breakpoint there to check some values. but I took it out now, thanks:)

The while loop is there because it is a menu, otherwise it will display it once and you can't move the pointer.

No problem, glad to help :), still though you could have a separate loop for the menu then call it in the main loop and have the pointer display code be inside the menu loop, that way once the menu goes away so does the pointer then you don't need a while loop at all.... just a thought though, and I may be completely off too on this one

EDIT: looks like Foxi4 was saying this too so I guess I can't be too far off
 
  • Like
Reactions: ground

Foxi4

Endless Trash
Global Moderator
Joined
Sep 13, 2009
Messages
30,824
Trophies
3
Location
Gaming Grotto
XP
29,821
Country
Poland
Here's what I would do - I'd create a struct of bools for each button, say, ArrowDown.Pressed, ArrowDown.Held and ArrowDown.Released, I'd nest them together in a function UpdateInput() along the lines of:

void UpdateInput(){
hidScanInput();
ArrowDown.Pressed = hidKeysDown();
...
}

I'd run that function as first in the main while loop and I'd refer to that struct every time I need button input, as such:

if(ArrowDown.Pressed){...}

This way you only check for it once. Remember to wait for a blank at the end of main(), too!
 

ground

Well-Known Member
OP
Member
Joined
Mar 22, 2007
Messages
907
Trophies
0
XP
572
Country
Netherlands
Here's what I would do.- I'd create a struct of bools for each button, say, ArrrowDown.Pressed, ArrrowDown.Held and ArrowDown.Released, I'd nest them together in a function UpdateInput() along the lines of:

void UpdateInput(){
hidScanInput();
ArrowDown.Pressed = hidKeysDown();
...
}

I'd run that function as first in the main while loop and I'd refer to that struct every time I need button input, as such:

if(ArrowDown.Pressed){...}

This way you only check for it once. Remember to wait for a blank at the end of main(), too!
thanks :). that sounds like a good idea.
 

ground

Well-Known Member
OP
Member
Joined
Mar 22, 2007
Messages
907
Trophies
0
XP
572
Country
Netherlands
Mind you, I don't know the exact names of functions to call for each button, but I'm sure they're in the documentation. Adjust types as needed. :P
yeah i know, those are well documented in ctrulib, but i get the idea to get a separate function for it. it still will be a puzzle (as it is really messy now) but at least a good learning curve for C haha.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Xdqwerty @ Xdqwerty: @Psionic Roshambo, atleast there was some neat filler there