gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > How to slow down keypresses

#1018 - imikeyi - Mon Jan 13, 2003 1:41 pm

I sample keypresses with the REG_KEY register. I want to be able to select options from a menu, but at the moment the keys get sampled _very fast_. How can I increase the delay between key presses?

#1019 - Scritch - Mon Jan 13, 2003 2:25 pm

imikeyi wrote:
I sample keypresses with the REG_KEY register. I want to be able to select options from a menu, but at the moment the keys get sampled _very fast_. How can I increase the delay between key presses?


I think you should just check this register less often...
From GBATEK:
It'd be usually recommended to read-out this register only once per frame, and to store the current state in memory. As a side effect, this method avoids problems caused by switch bounce when a key is newly released or pressed.

You can also check it even less often if you want.

#1020 - imikeyi - Mon Jan 13, 2003 2:30 pm

Scritch wrote:
I think you should just check this register less often...
From GBATEK:
It'd be usually recommended to read-out this register only once per frame, and to store the current state in memory. As a side effect, this method avoids problems caused by switch bounce when a key is newly released or pressed.


Ahh switch bounce.. I did a class on boards using stamp cpus and they talked about that, but I would have thought the GBA had its own debouncing mechanisms, because its much more sophisticated.

#1023 - Splam - Mon Jan 13, 2003 4:30 pm

Yep, you can debounce the buttons. GBA doesn't have its own.

obviously if you know how debounce works ignore this post :)

To do it you need to read the register every frame then have a routine that checks it against the previous frames entry. Only if the state has changed (the button has been pressed) do you then set a bit in the "debounce" variable. If the current and previous frames are the same the debounce for that button is cleared.

Your main code then reads the debounce variable to see if anything has been pressed, if you want to know if something is being held down you obviously just check the current frames variable.

Do this at the start of a frame then make sure to read the debounce and process presses every frame else you'll miss the presses as they only happen once per press and are cleared on the next frame (hence the debounce).

-edit-
If you want a sort of in between method so holding a button down still registers but not as often just add a timer to your debounce routine (or use a main game loop timer) if the desired time has passed clear out the debounce variables (last frame one should do it) then the "button pressed" part of the debounce variable will be set again and again etc

#2386 - Malefactor - Sun Feb 02, 2003 8:56 pm

I'm using this routine right now.. But sometimes it seems like it registers when I press the key AND when I let go of it :(

Code:
CurrentKey = *KEYS;
if(CurrentkKey != LastKey && !(CurrentKey & KEY_R)) //do stuff
LastKey = CurrentKey;


am I doing something wrong?
_________________
[Images not permitted - Click here to view it]

#2390 - Lord Graga - Sun Feb 02, 2003 9:59 pm

I just use timers when a key is pressed (wait 0.5 seconds).
Sometimes i do this instead:

if(k = 0)
{
if(!(*KEYS & KEY_UP))
{
dir--;
k = 1;
}
}

then i reset "k" if no keys are pressed.

#2392 - FluBBa - Sun Feb 02, 2003 10:27 pm

Splam:
Debouncing as talked about in the cowbite spec is when the switches repeatedly switch state even though you just pressed once or released the button. Not about how to tell if button has changed state.
But maybe that was what imikeyi wanted.

All:
To get rid of the bounce, just read the hardware register once a frame and store it in a variable. I repeat what Splam has said more or less said over and over again, base your code on the VBlank. ;-)
It's probably good for you.
Maybe he didn't say that but I hope he agrees with me.
_________________
I probably suck, my not is a programmer.

#2434 - DrakeX - Mon Feb 03, 2003 10:32 pm

i'm not exactly a GBA programmer (yet) but in other platforms (the computer..) it's easy to do something like this:

Code:

char upwait=15; // this is at the beginning of the program, you can change this to make the wait longer or shorter

if(!(UPKEY_PRESSED)) upwait=1; // up is not pressed
if(UPKEY_PRESSED) // up IS pressed
{
   upwait--;
   if(upwait==0)
   {
      upwait=15;
      // place upkey code in here
   }
}


basically it resets the wait to 1 if it's not pressed so it registers as soo as the up key is pressed, then every loop it decrements a variable until it's 0, where it resets the wait variable to 15 and does the code for when you press the upkey. :)

#2538 - Malefactor - Thu Feb 06, 2003 1:34 am

tried timers - can't get it precise enough, either too fast or too slow.

Well, all I had to do was make my function wait for the VBlank. Thanks to Blubba for pointing out the little paragraph in splams post that I missed.
_________________
[Images not permitted - Click here to view it]