ALLEGRO_KEYBOARD_STATE internal working
brisingr123

Hello there!

I was wondering exactly how Allegro managed it's keyboard state... As most of you might be knowing, Allegro's input method does not work properly if the window loses focus. That's a huge problem for my current project, so I'm trying to find a temporary hack to suppress that behavior. Let me first brief out my idea : a key is pressed only and only if allegro detects it as pressed, and windows detects it as pressed. That way, i'll only get the keystrokes meant for my application, and it won't cause any problem when losing focus either. The best I could come up with was this:

#SelectExpand
1 al_get_keyboard_state(&keyboardState); 2 3 //TEMP HACK!!! 4 std::vector<std::pair<int, int> > hackKeyList; 5 hackKeyList.push_back(std::make_pair((int)ALLEGRO_KEY_ENTER, VK_RETURN)); 6 for (int i = 0; i < hackKeyList.size(); i++) 7 { 8 int n = hackKeyList[i].first / 32; 9 int b = hackKeyList[i].first % 32; 10 int keystate = keyboardState.__key_down__internal__[n]; 11 12 if ((keystate & (1 << b)) != al_key_down(&keyboardState, hackKeyList[i].first)) //Only for debug 13 exit(-1); 14 15 bool kDown = (keystate & (1 << b)) && GetAsyncKeyState(hackKeyList[i].second); 16 17 kDown ^= 1; 18 19 keystate &= (0xffffffff ^ (kDown << b)); 20 21 keyboardState.__key_down__internal__[n] = keystate; 22 } 23 //

The main idea behind it is this : since _key_down__internal_ is an int array of size (ALLEGRO_KEY_MAX + 31/32), I assume it stores the key states as bits, where the k-th bit represents the state of the k-th key in ALLEGRO_KEY enum. So, working with that hypothesis, __key_down__internal__[n] will contain 32 key states, starting from 32*n. However, for some reason, this reasoning appears to be wrong, or I'm missing out on something obvious, since the line marked as debug exits the application. Does anyone have any idea exactly what's the problem?

SiegeLord

I didn't read your code, but here's the macro that Allegro uses to update they keyboard state:

#define _AL_KEYBOARD_STATE_SET_KEY_DOWN(STATE, KEYCODE)                 \
   do {                                                                 \ 
      int kc = (KEYCODE);                                               \ 
      (STATE).__key_down__internal__[kc / 32] |= (1 << (kc % 32));      \ 
   } while (0) 

brisingr123

Oh cool, thanks a lot for that :D

And if you don't mind me asking, why does the code have a do{...}while(0) condition? Isn't it better to simply remove the while?

SiegeLord

I think what might be happening is that the result of al_key_down gets converted to an integer (namely, 1) and that likely won't be equal to that binary AND. Try this:

if (((keystate & (1 << b)) != 0) != al_key_down(&keyboardState, ALLEGRO_KEY_ENTER))
            exit(-1);

And if you don't mind me asking, why does the code have a do{...}while(0) condition? Isn't it better to simply remove the while?

http://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for/257425#257425

brisingr123

Yeah, you were right, I figured it out a bit later, although I used a bool cast.

Also, thanks for your help :)

Thread #614995. Printed from Allegro.cc