The problem with polling is you can miss something. If the user presses and releases a key before you get around to polling again, you will completely miss it. Mouse clicks are fast, and if your frame rate stalls for whatever reason (not even your program's fault; maybe the dreaded McAfee just started to do an update in the background...) and you're out of luck.
I get that you want to just poll to check if a key is pressed in your code. I like to do that too. But it's easy to do with events: (Rough pseudocode; haven't done win32 events in a while:
bool keystate[MAX_KEY];
bool mousebutton[MAX_MOUSEBUTTON];
int mousex, mousey;
#define MOUSE_LEFT 0
#define MOUSE_RIGHT 1
eventhandler(...)
{
while (event = getnextevent(...))
{
if(event==KEY_DOWN && keycode < MAX_KEY)
keystate[keycode] = 1;
if(event==KEY_UP && keycode < MAX_KEY)
keystate[keycode] = 0;
if (event==L_MOUSE_DOWN)
mousebutton[MOUSE_LEFT] = 1;
if (event==L_MOUSE_UP)
mousebutton[MOUSE_LEFT] = 0;
if (event==MOUSE_MOVE)
{
mousex = event_mouse_x;
mousey = event_mouse_y;
}
}
}
Then, in your code you can do if(keystate[KEY_L_CTRL]) all you want. Or sprite.draw(mousex, mousey).
The above could still suffer from missing presses. If the system slows down, and you call the event loop once per frame, if a keydown AND a keyup press bunch up against each other, then in one frame's processing of events you would set, and unset a single key in the same call to the loop. One way to do that is handle the player's inputs in the event handler itself:
if(event==KEY_DOWN && keycode < MAX_KEY)
{
keystate[keycode] = 1;
if (keycode == playerconfig.firekey)
player.fire=1;
if (keycode == playerconfig.jump)
player.jump= 1;
}
This way the event loop is looking for particular events, and sets those flags in the player object. Each frame, after the event handler is run, when the player's control code is run, it checks it's action flags and does the appropriate action. This way you can't miss a jump or fire event, even if the next event is the queue is releasing the button.
You can abstract that completely and do this:
while (event = getnextevent(...))
{
memset(keypressed, 0, sizeof(keypressed)); //clear pressed events
if(event==KEY_DOWN && keycode < MAX_KEY)
{
keystate[keycode] = 1;
keypressed[keycode] = 1;
}
if(event==KEY_UP && keycode < MAX_KEY)
keystate[keycode] = 0;
}
Now, you can't miss an event. If the key was pressed at all since the last frame, keypressed will be '1'. And if its still pressed keystate will be '1'. So now anywhere in your game loop you can do this:
if (keypressed[ player_config.fire_key] || ( keystate[player_config.fire_key] && (this_frame - last_fire_frame >= 20))
{
last_fire_frame = this_frame;
fire_a_bullet();
}
What this does is fire a bullet every time the player presses the fire key OR if the player holds down the fire key, one bullet every 20 frames.
Also this is all assume a single main loop thread, that looks something like this:
while(not_quitting)
{
handle_window_events();
increment_game_logic();
draw();
}