Skip to main content
gamedev.net
🔒 Locked

DirectInput problem

Started by Pelikaruga 6 replies 1.2k views
Original Post
Pelikaruga
Pelikaruga
I used many hours searching for a solution from the internet, reading my books and going trough dozens of DI related topics here, but finally gave up and decided to ask here. I have been doing all kinds of games, physic engines and AI systems for a long time, but I have never had the need to use DirectInput... the Win32 functions have been enough to suit my needs. I have been using DirectDraw for all my drawing, but now moved on to D3D, and at the same time started using DirectInput. My problem is that when I press a key, it reacts to it, then takes a 0.5 second brake and then continues reacting fluently, just like the auto repeat works when you type. Now, this happens each time I press a new key, and stops everything for a while, even reactions to other keys, but everything continues like before after the "auto repeat" delay has ended. There is no delay nor problem when a key is released. First I tought that I must be just doing something so badly that it tilts for a second when you do something new, but then I noticed another problem that changes my guess from the previouse one to "I do not know at all" or "must be something with the window being..... I do not know": When you release all keys, the movement stops totally. Let me first show you the code so you get it (yes, this is just a test, and nothing clean... I just wanted to see if I can get it working):
diDevice->GetDeviceState( sizeof(diKeyboard), (LPVOID)diKeyboard );

	if ( KEYDOWN( diKeyboard, DIK_LEFT ) && player1.xv > -10.0f )
		player1.xv -= 0.5f;

	if ( KEYDOWN( diKeyboard, DIK_RIGHT ) && player1.xv < 10.0f )
		player1.xv += 0.5f;

	if ( !KEYDOWN( diKeyboard, DIK_LEFT ) && player1.xv < 0 )
		player1.xv += 0.5f;

	if ( !KEYDOWN( diKeyboard, DIK_RIGHT ) && player1.xv > 0 )
		player1.xv -= 0.5f;

	
	if ( KEYDOWN( diKeyboard, DIK_UP ) && player1.yv > -10.0f )
		player1.yv -= 0.5f;

	if ( KEYDOWN( diKeyboard, DIK_DOWN ) && player1.yv < 10.0f )
		player1.yv += 0.5f;

	if ( !KEYDOWN( diKeyboard, DIK_UP ) && player1.yv < 0 )
		player1.yv += 0.5f;

	if ( !KEYDOWN( diKeyboard, DIK_DOWN ) && player1.yv > 0 )
		player1.yv -= 0.5f;

	player1.x += player1.xv;
	player1.y += player1.yv;
Player is a structure that includes the location, x and y, the velocities, xv and yv, and the texture of the player, texture. Also, as you can see, I am using the macro DI SDK suggests for testing key input; #define KEYDOWN(name, key) (name[key] & 0x80) So yeah, if no keys are pressed, the player just stops moving, like the game would stop and wait for input before continuing. If you are going max speed to the left, and releaste the left arrow, the player stops like into a wall, and then if you for example press the right arrow down, the player continues left like the xv is telling it, before the velocity is slowly turned around. So, to me it seems that the game like pauses, to wait for input. This problem is in both full screen and windowed mode, and does not depend on any window styles. Now, to the thing that made me just stare at the screen and want to call my mother is that when you move the mouse on the game window, everything works. Everything works smoothly when the mouse is constantly MOVING on the game window, thus sending input messages to the window, even tough I do not know why that would affect this, as at least I have not set anything that I could think of archieving this. Also, when you are moving max speed to a direction, and then stop pressing keys, the game stops, like I said. Now, if you move the cursor across the screen, the player starts moving again just like the velocity tells it to do. I am not sure, but I think this same problem occured when I used the Win32 functions for this.... now that I think of it.... I think that was actually why I wanted to try DI for this, so the problem might be something totally else. Here is the initialization code if it helps:
if ( FAILED( DirectInput8Create( application_hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&di, NULL ) ) )
		return E_FAIL;

	if ( FAILED( di->CreateDevice( GUID_SysKeyboard, &diDevice, NULL ) ) )
		return E_FAIL;

	if ( FAILED( diDevice->SetDataFormat( &c_dfDIKeyboard ) ) )
		return E_FAIL;

	if ( FAILED( diDevice->SetCooperativeLevel( main_window_handle, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE ) ) )
		return E_FAIL;

	if ( FAILED( diDevice->Acquire() ) )
		return E_FAIL;
Thank you very much in advance! I really appreciate your help. Pauli
Saruman
Saruman
Is there a reason that you are using DISCL_BACKGROUND:

if ( FAILED( diDevice->SetCooperativeLevel( main_window_handle, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE ) ) )		return E_FAIL;


instead of DISCL_FOREGROUND?

just curious :)
Pelikaruga
Pelikaruga
Because the function fails when using DISCL_FOREGROUND...

I tought that might be the cause of the problem, but could not try it.... then again I saw games getting input the same way as mine with DISCL_BACKGROUND without problems, so I tougt it might not have been it anyway.

If you tried to hint about some kind of key catcher program, no, if I want to do that kind of stuff, I do something totally different ;)
Saruman
Saruman
I don't think it is what is causing your problem, I was just wondering. DISCL_FOREGROUND will only keep devices and get input when your application is in the foreground, while DISCL_BACKGROUND will always be aquired and receiving input.

If you are developing an application that you want to be able to multitask with at peak performance, than imo DISCL_FOREGROUND is the way to go.

EDIT: Although it does seem really wierd that the method fails when using DISCL_FOREGROUND.
Pelikaruga
Pelikaruga
Yeah, I tought it should be working that way too, but this application of mine gets no information about input if it is not activated, so I guess the list of funny things grows :p
cardinals33
cardinals33
To use DISCL_FOREGROUND you need to combine it with DISCL_EXCLUSIVE. I dont think DISCL_FOREGROUND and DISCL_NONEXCLUSIVE can be combined when initialzing DirectInput. Maybe that could help?
IFooBar
IFooBar
getting an excludive device may very well solve the problem, but I do have my doubts on this one. I mean everytime a new key is pressed, you lose the device for half a second? What are the odds of that? Unless there is some other program you got on that has background exclusive access? But even then, if there are two apps with exclusivce access the one in the forground is given priority. Have you tried running in debug mode to see if directx spits out any debug messages at you?
[size=2]aliak.net
Pelikaruga
Pelikaruga
Thanks for the help.

I solved my problem yesterday just before I went to sleep. It was not about DI like I mentioned the case could be... I had changed my message processer from the one I have used to the one in the D3D samples, and it does not continue the loop before something happens that sends a message in Windows.... stupid me :p

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.