Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Binding Keys Code

Credits go to CGamesPlay and Felipe Maia for helping out!
This thread is locked; no one can reply to it. rss feed Print
Binding Keys Code
Paladin
Member #6,645
December 2005
avatar

I'm trying to figure out how to bind keys and have it displayed to the user what key that have binded so they understand, but have it as a value so that the code can use it. Like have the variable be "KEY_W" but actually display "W". I wanted to know if there was a way to do this. I've tried a couple of methods but they end up sucking. I was wondering if there was a way to do this without halting the main loop.

My current code:

textprintf_centre_ex(activepage, media[MAINFONT].dat, SCREEN_W/2, 120, WHITE, BLACK, "Press a key...");
p1up = ureadkey(NULL);
textprintf_centre_ex(activepage, media[MAINFONT].dat, SCREEN_W/2, 240, WHITE, BLACK, "Up - %i", p1up);

The 3rd line is called later in a different function, but these are all the codes used. 'p1up' is an integer, and I set it to KEY_W. I do not think I'm doing this correctly at all, so any help would be appreciated.

Sorry for asking so many questions lately, I've just been trying a lot of new things.

CGamesPlay
Member #2,559
July 2002
avatar

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Paladin
Member #6,645
December 2005
avatar

That doesn't fully answer my question though, it still doesn't solve the problem that I have with the main loop. How do I get the scancode though? With readkey() or ureadkey()? Or is it detect_key();?

CGamesPlay
Member #2,559
July 2002
avatar

readkey() >> 8 gives you a scancode in the form like KEY_SPACE. To not halt the main loop, only call readkey() when keypressed() returns true.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Paladin
Member #6,645
December 2005
avatar

Ok, well I'm having it so that I click on an option to change it, so would something like this work?

pseudo-code:

if(optionclicked)
readingkey == true;

in main loop:

if(readingkey == true and keypressed())
key = readkey() >> 8;

Felipe Maia
Member #6,190
September 2005
avatar

Could have all together, no need to separate them.

Paladin
Member #6,645
December 2005
avatar

The reason I don't have it together is so that the main loop will continue. And I want to make sure that they have an option selected, otherwise they could just press random keys and they would assign those keys to the actual variables. And speaking of which, should I be using integer as the data type(scancode) or should it be something else? And which one should I be using to convert it to a readable character? Scancode_to_ascii or scancode_to_name?

Felipe Maia
Member #6,190
September 2005
avatar

scancode_to_name Works well. I don't see a reason why do you want to be running the game while the guy selects the key, but that's you who decides. A int is enough for the key scancode.

Paladin
Member #6,645
December 2005
avatar

Well I have a marquee running in the background and it freezes the deal. I know it's ridiculous, but of course it's all part of the learning experience. I'll edit this post if I get it working. ;D

EDIT:
Ok I got it working, but I have a bug. If I type in like 7 letters without clicking on the option, then it "saves" them I guess, so like if I press the option 7 times, then it shows each character, then finally it displays "Press a key". Here's the code:

1//Everytime the menu is displayed
2if((readingkey[0] == 1) || (readingkey[1] == 1) || (readingkey[2] == 1) || (readingkey[3] == 1))
3 textprintf_centre_ex(activepage, media[MAINFONT].dat, SCREEN_W/2, 120, WHITE, BLACK, "Press a key...");
4 
5textprintf_centre_ex(activepage, media[MAINFONT].dat, SCREEN_W/2, 240, WHITE, BLACK, "Up - %s", scancode_to_name(p1up));
6 
7//In a switch statement, everytime you click on the option:
8int i;
9for(i = 0; i < 4; i++)
10 readingkey<i> = 0;
11readingkey[0] = 1;
12play_sample(media[SELECT].dat, sound, 128, 1000, FALSE);
13break;
14 
15//The main loop
16if(keypressed())
17 getInput();
18 
19//Now get input:
20void getInput()
21{
22 if(game == 0)
23 {
24 if(readingkey[0] == 1)
25 {
26 play_sample(media[SELECT].dat, sound, 128, 1000, FALSE);
27 p1up = readkey() >> 8;
28 readingkey[0] = 0;
29 }
30 if(readingkey[1] == 1)
31 {
32 play_sample(media[SELECT].dat, sound, 128, 1000, FALSE);
33 p1down = readkey() >> 8;
34 readingkey[1] = 0;
35 }
36 }
37}

I'm sure a little explanation is necessary, so here I go. Readingkey[4] is an integer that when it's equal to 1, that means that I have clicked on an option and it's ready to read a key. I do this so that the main loop will still continue to run in the background. The p1up and p1down are integers that hold the scancode of the players up and down keys. Sorry for so many questions, I've just always wanted to know how binding keys would work. Can someone fix this for me, and can someone tell me what precautions I should make (Like to not allow users to type in the F1-F12 keys or something) ?

CGamesPlay
Member #2,559
July 2002
avatar

Because there is a readkey buffer (keyboard buffer), which can be cleared by calling clear_keybuf(). So when the user selects the option to change the binding, call clear_keybuf(), then wait for keypressed(), then call readkey().

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Paladin
Member #6,645
December 2005
avatar

Ahh ok, that makes a lot of sense now. Thanks a lot, I got it all taken care of. ;D

Go to: