Debouncing Multiple-Keypress PRGM GetKey

From WikiPrizm
Jump to: navigation, search

Synopsis

The below code is not a single function, but rather a group of functions for fulfilling a single purpose: providing key debouncing and multi-keypress detection to the PRGM GetKey function. The needed function and variable declarations are as follows:

Definition

 const unsigned short* keyboard_register = (unsigned short*)0xA44B0000;
 unsigned short lastkey[8];
 unsigned short holdkey[8];
 
 void keyupdate(void) {
    memcpy(holdkey, lastkey, sizeof(unsigned short)*8);
    memcpy(lastkey, keyboard_register, sizeof(unsigned short)*8);
 }
 int keydownlast(int basic_keycode) {
    int row, col, word, bit; 
    row = basic_keycode%10; 
    col = basic_keycode/10-1; 
    word = row>>1; 
    bit = col + 8*(row&1); 
    return (0 != (lastkey[word] & 1<<bit)); 
 }
 int keydownhold(int basic_keycode) {
    int row, col, word, bit; 
    row = basic_keycode%10; 
    col = basic_keycode/10-1; 
    word = row>>1; 
    bit = col + 8*(row&1); 
    return (0 != (holdkey[word] & 1<<bit)); 
 }


These functions are used to check the current state of a key in the key array during the current loop runthrough, or check the value from the last loop. These use the KEY_PRGM_<key> key codes, and should be used in something like a game loop to provide clean debouncing. Here is an example of these functions at work in an example game loop:

 while(running) {
   keyupdate(); // update both key arrays
 
   ...
 
   // checking to see if the up key has been held down for a while
   if(keydownlast(KEY_PRGM_UP) && keydownhold(KEY_PRGM_UP))
 
   // checking to see if the up key has not been held down for a while
   if(!keydownlast(KEY_PRGM_UP) && !keydownhold(KEY_PRGM_UP))
 
   // checking to see if the up key has just been pressed
   if(keydownlast(KEY_PRGM_UP) && !keydownhold(KEY_PRGM_UP))
 
   // checking to see if the up key has just been released
   if(!keydownlast(KEY_PRGM_UP) && keydownhold(KEY_PRGM_UP))
 }

Inputs

keyupdate: None

keydownlast: int (KEY_PRGM_<key> keycode)

keydownhold: int (KEY_PRGM_<key> keycode)

Outputs

keyupdate: None

keydownlast: 1 if key has been pressed during last keyupdate() call, 0 otherwise

keydownhold: 1 if key has been pressed two keyupdate() calls ago, 0 otherwise

Comments

It's a bit more wordy to use than its simple PRGM GetKey sibling, but it's also very flexible and can even be used to check for pseudo keydown/keyup key events. It also reads directly from keyboard hardware ports, so it's very fast and doesn't rely on the OS's control.