Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » get all pressed keys?

This thread is locked; no one can reply to it. rss feed Print
get all pressed keys?
Shadowblitz16
Member #16,818
March 2018

does anybody know how to get all currently pressed keys?

I have a function called getMouseButtons which does this..

#SelectExpand
1 int getMouseButtons() 2 { 3 ALLEGRO_MOUSE_STATE state; 4 al_get_mouse_state(&state); 5 return state.buttons; 6 }

and I( was trying to make a keyboard version..

#SelectExpand
1 int getKeyboardKeys() 2 { 3 ALLEGRO_KEYBOARD_STATE state; 4 al_get_keyboard_state(&state); 5 return state.keys; 6 }

the problem is ALLEGRO_KEYBOARD_STATE doesn't have a member called keys like ALLEGRO_MOUSE_STATE has a member called buttons.

MikiZX
Member #17,092
June 2019

With ALLEGRO_KEYBOARD_STATE you have to use function called al_key_down ( https://www.allegro.cc/manual/5/al_key_down ) to read a single key.

Otherwise if the function alone is not sufficient and you would like to always have something similar to the mouse buttons variable then you will need to create an array of keys and update it yourself by reading each key. Something along the lines of:

bool pressed_key[ALLEGRO_KEY_MAX];
...
al_get_keyboard_state(&kbdstate);
for (int i=0; i<ALLEGRO_KEY_MAX; ++i)
{
   if (al_key_down(&kbdstate, i))
      pressed_key[i] = true;
    else
      pressed_key[i] = false;
}

Edgar Reynaldo
Member #8,592
May 2007
avatar

Polling is outdated, and honestly shouldn't have been included in A5. :/

The proper way to monitor the state of the keyboard and mouse is through the event system.

If you poll, you stand the risk of losing events in-between polls.

Some example code to get you started :

#SelectExpand
1int main(int argc , char** argv) { 2 3//... 4 ALLEGRO_EVENT_QUEUE* q = al_create_event_queue(); 5 if (!q) {Bail();} 6 7 al_register_event_source(q , al_get_keyboard_event_source()); 8 al_register_event_source(q , al_get_mouse_event_source()); 9 al_register_event_source(q , al_get_display_event_source(display)); 10 11 /// Some variables to track our key and mouse state 12 int mx = 0; 13 int my = 0; 14 int mb = 0;/// bitfield 15 16 bool keys[ALLEGRO_KEY_MAX] = {0}; 17 18 /// Typical event loop 19 bool quit = false; 20 bool redraw = true; 21 22 while (!quit) { 23 if (redraw) { 24 Draw(); 25 redraw = false; 26 } 27 do { 28 ALLEGRO_EVENT e; 29 al_wait_for_event(q , &e); 30 if (e.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 31 quit = true; 32 } 33 if (e.type == ALLEGRO_EVENT_KEY_DOWN && e.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 34 quit = true; 35 } 36 if (e.type == ALLEGRO_EVENT_KEY_DOWN) { 37 keys[e.keyboard.keycode] = true; 38 } 39 if (e.type == ALLEGRO_EVENT_KEY_UP) { 40 keys[e.keyboard.keycode] = false; 41 } 42 if (e.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { 43 mb |= (1 << e.mouse.button); 44 } 45 if (e.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { 46 mb &= ~(1 << e.mouse.button); 47 } 48 if (e.type == ALLEGRO_EVENT_MOUSE_AXES) { 49 mx = e.mouse.x; 50 my = e.mouse.y; 51 } 52 } while (!al_is_event_queue_empty(q)); 53 } 54 55 return 0; 56}

Shadowblitz16
Member #16,818
March 2018

can events be used in a way that I can do..
key_is_down()
key_is_held()
key_is_up ()

I would rather not have to keep my game logic in main's events

Edgar Reynaldo
Member #8,592
May 2007
avatar

Yes.

You can use pointers, you can pass variables, you can do whatever you want.

Hint (you only need one event loop)

Shadowblitz16
Member #16,818
March 2018

hmm ok I think I am going to go with this..

#SelectExpand
1bool pressed_key[ALLEGRO_KEY_MAX]; 2... 3al_get_keyboard_state(&kbdstate); 4for (int i=0; i<ALLEGRO_KEY_MAX; ++i) 5{ 6 if (al_key_down(&kbdstate, i)) 7 pressed_key[i] = true; 8 else 9 pressed_key[i] = false; 10}

Go to: