I'm in the process of replacing Microsoft CRT functions with allegro equivalents to remove my dependencies on console functions. One of them is _kbhit which is an ancient legacy command from conio.h
Here is the function definition from Microsoft:
The _kbhit function checks the console for a recent keystroke. If the function returns a nonzero value, a keystroke is waiting in the buffer. The program can then
call _getch or _getche to get the keystroke.
Here's my stab to do the same thing:
int keyboardhit() { if (al_peek_next_event(kbdQueue, &kbdState)) { return 1; //doesn't really matter what was hit } return 0; }
I then will write my own _getch() to get the next key, but it's not quite working the way it's supposed to.
I tried an attempt using microsoft's exmaple.
//keyboardhit() replaced _kbhit() while (!keyboardhit()) _cputs("Hit me!! ");
and it's not detecting the keypress. Am I missing something here?
Here's my whole example code
I use the following code when I need to wait for a keypress... this is an Allegro 5 function I created for Deluxe Pacman 2 (see link below), it will also respond to a mouse click or joystick input (see comments in code).
I added on additional functionality to this where you can send a wait_time in milliseconds so it will wait for a keypress OR however many seconds you want. So if you call it with wait_for_keypress(5000.0) It will wait 5000ms or 5 seconds and then continue on. If you want it to wait indefinitely, pass a zero to it and it will wait for input and not move.
ALLEGRO_EVENT_QUEUE *kbdQueue = NULL; //!< Keyboard Queue ALLEGRO_KEYBOARD_STATE kbdState; //!< Keybord State int keyboardhit() { if (al_peek_next_event(kbdQueue, &kbdState)) { return 1; } else return 0; }
That code shouldn't even compile. You're passing an ALLEGRO_KEYBOARD_STATE* to a function parameter that is expecting an ALLEGRO_EVENT*.
To keep in the fashion of _kbhit, you can use functions like these, in the same way you were attempting to. You just need to keep a separate queue of events, or at least store and remove them when they are received.
Thanks for the push in the right direction - I was sick yesterday... Also I'm not using C++, so I can't use namespaces.
I was writing kind of off the cuff. I'm making a little lab project where I can rewrite replace getch and kbhit with a little test unit.
==EDIT==
Something is up, I don't know if it's my foggy head and leftover flu, but I can't seem to get any keyboard input wot work anymore. Even your examples. I have a very basic system her just to get something out of the event queue and it's not working at all. Is there something I'm missing?
I'm trying to do a "drop in" replacement for these two commands. Keep in mind, the program I'm porting does not exactly have a "main loop", but a bunch of machine states that are executed depending on globals. There is a lot of pausing and waiting for input without rendering anything. My code is below.
Why was the original keypress() functions removed from allegro 5? They seem really useful!
++ ANOTHER EDIT ++
My original code was not making an allegro display. It doesn't work in the terminal. Makes sense as I'm trying to get rid of the terminal Now the keyboard is working (eyeroll)
here is the code for others to use. Mind you, It's not 100% compatible, but works well enough for all. I woudn't mind this in the actual Allegro library if it was cleaned up enough
Okay, you need to read through your code, and follow it along logically...
If a person presses a key, what line will this code return at?
If a person releases a key, what line will this code return at?
You are checking for a key down event, then clearing the queue and exiting with a return 0. You are also checking for a key up event in the same code. So no matter what happens, no matter what key is pressed, it will ALWAYS return 0 with nothing.
WHat you want to do, is to check if a key is pressed, or released, up to you (you can respond as soon as it is pressed, or wait for the person to release it). Anyhow, once it is pressed, you do not return right away, you then need to check which key was pressed INSIDE that same code, and respond to it accordingly... like this... in pseudo code.
Was a key pressed?
{
Get key that was pressed and respond to it.
return
}
else no key pressed, check for other events
{
...code here...
}
You're checking if a key was pressed and then returning without doing anything at all. Check the example I showed you. It is in C, I clipped it straight out of my Deluxe Pacman 2 code, unedited, so it works. You will notice when I check to see if a key is released, if one was, than I immediately extract the key that was pressed and respond inside that loop.
If you simply must do it in C, then just take advantage of allegro. If you get a key up or down event, discard it. If you get a char event leave it on the queue until _getch is called.
Thanks for all your input guys! You were right Neil, I wasn't thinking the logic though. But thanks especially to you Edgar! You have been overly helpful with all my silly questions to the point I feel like I'm being a bother. I guess it doesn't hurt I'm showing off my work and demonstrating I'm at least trying to get things right. I have gained such a larger grasp on Allegro with this project than I imagined I would.. Maybe I should be giving back to the community and helping out the newbies too.
I gave you bad code. Let me fix it.
int _getch() { ALLEGRO_EVENT ev; if (ev.type != ALLEGRO_EVENT_KEY_CHAR) {return 0;} return ev.keyboard.unichar; }
The above code could have passed back an uninitialized value for ev.keyboard.unichar in the case of ev.type being KEY_CHAR left over in memory.
int _getch() { ALLEGRO_EVENT ev; if (al_get_next_event(q , &ev)) { if (ev.type != ALLEGRO_EVENT_KEY_CHAR) {return 0;} return ev.keyboard.unichar; } return 0; }
This makes sure you actually received an event before checking its fields.