Programmer Question
Well, I'm trying to avoid using the deprecated DirectInput.
But I need, at each "frame" or "iteration" of the game to snatch ALL KEY STATES so that I can act accordingly. For example, if the player is down on the VK_RIGHT key then he will move just a smidgen right on that frame.
The problem with WM_INPUT messages is they can appear an unpredictable number of times per frame, because of the way the game loop is written:
MSG message ;
while( 1 )
{
if( PeekMessage( &message, NULL, 0, 0, PM_REMOVE ) )
{
if( message.message == WM_QUIT )
{
break ; // bail when WM_QUIT
}
TranslateMessage( &message ) ;
DispatchMessage( &message ) ;
}
else
{
// No messages, so run the game.
Update() ;
Draw() ;
}
}
So if more than one WM_INPUT message is stacked there then they will all get processed before Update()/Draw().
I resolved this issue by using an array of BOOL to remember what keys were down:
bool array_of_keys_that_are_down[ 256 ] ;
case WM_INPUT :
if( its keyboard input )
{
array_of_keys_that_are_down[ VK_CODE ] = TRUE ;
}
That works fine because the Update() function checks
void Update()
{
if( array_of_keys_that_are_down[ VK_RIGHT ] )
{
// Move the player right a bit
}
}
BUT the problem is now that WM_INPUT messages don't get generated often enough. There's a delay of about 1 second between the first press of VK_RIGHT and subsequent VK_RIGHT messages, even if the player had his finger down on it the whole time. Its not like DirectInput where you can keyboard->GetDeviceState( 256, (void*)array_of_keys_that_are_down );
(snatch out all key states each frame with a single call)
So I'm lost. Other than resorting to GetAsyncKeystate() function calls for each key I need to monitor, I see no way to avoid using DirectInput if you can't snatch out all key states each frame reliably.
It seems to me that DirectInput was a very good solution to this problem, but if it was deprecated, then there really must be some way to do this conveniently using Win32 api only.
Currently array_of_keys_that_are_down
gets reset back to all FALSE's every frame.
memset( array_of_keys_that_are_down, 0, sizeof( array_of_keys_that_are_down ) ) ;
*EDIT
I've been working on this problem and one solution is to only reset a key state, once its been released
case WM_INPUT :
if( its keyboard input )
{
if( its a down press )
array_of_keys_that_are_down[ VK_CODE ] = TRUE ;
else
array_of_keys_that_are_down[ VK_CODE ] = FALSE ;
}
I don't like this solution though because it seems flimsy. If the user switches away from the application while down on a key, then that key will be "stuck" until he switches back and presses that same key again because we'll never get the upstroke WM_INPUT message. It makes for weird "sticky key" bugs.
No comments:
Post a Comment