Input Debounce

To us there is a difference between pressing a key, holding a key down and letting go of a key. On a menu it is generally important that pressing a key is only detected once no matter how long it is held, but in a game the same action should make a character move continously. In other situations it could be important to know when a key was released.

To the hardware there is merely a contact being made or a contact not being made. The transition between the two needs detecting by us.

Fortunately it seems some level of hardware debounce is done inside the Next. A dirty joystick contact or a user hitting a key hard that physically bounces its contacts is correctly interpreted as a single press, so all our code is basic logic based on remembering the key states between frames.

You can use the same logic for joystick buttons.

All of what follows is basic boolean logic instead of using any selection operations. These functions will also operate together as expected, so a key pressed will register both a “pressed once” and a “released” state if both are checked for, and a key being held will generate all three as appropriate.

Key Pressed Once

Here is logic for working out if a key has been pressed down and then let go. Or when a key is pressed and held but should only register as a single event.

// pressed means it wasn't pressed last time but is now
inline bool_t keyboard_is_key_pressed(uint8_t key)
{
    // the logic is reversed because 0 means pressed, 1 not pressed(?!)
    return (previous_buffer[KEYBOARD_BUFFER_INDEX(key)] & KEYBOARD_BUFFER_BIT(key)) &&
        !(current_buffer[KEYBOARD_BUFFER_INDEX(key)] & KEYBOARD_BUFFER_BIT(key));
}

This works by looking at the state of the key in the previous frame, comparing it to this frame and if it was not pressed last frame but is pressed this frame, the key is considered pressed.

Key Held Down

Here is the logic for a key being held down where the intention is to repeat an action until the key is not pressed down.

// held means it was pressed last time and is pressed now
inline bool_t keyboard_is_key_held(uint8_t key)
{
    // the logic is reversed because 0 means pressed, 1 not pressed(?!)
    return !(previous_buffer[KEYBOARD_BUFFER_INDEX(key)] & KEYBOARD_BUFFER_BIT(key)) &&
        !(current_buffer[KEYBOARD_BUFFER_INDEX(key)] & KEYBOARD_BUFFER_BIT(key));
}

This works by looking at the state of the key in the previous frame, comparing it to this frame and if it was pressed last frame and is pressed this frame, the key is considered being held down.

Key Released

Here is the logic for a key being released.

// released means it was pressed last time but isn't now
inline bool_t keyboard_is_key_released(uint8_t key)
{
    // the logic is reversed because 0 means pressed, 1 not pressed(?!)
    return !(previous_buffer[KEYBOARD_BUFFER_INDEX(key)] & KEYBOARD_BUFFER_BIT(key)) &&
        (current_buffer[KEYBOARD_BUFFER_INDEX(key)] & KEYBOARD_BUFFER_BIT(key));
}

This works by looking at the state of the key in the previous frame, comparing it to this frame and if it was pressed last frame and is not pressed this frame, the key is considered being released.