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.