Skip to main content
GameDev.net gamedev.net
🔒 Locked

Need help using Direct Input

Started by kingpinzs Feb 15, 2007 at 6:56 PM 14 replies 2.3k views
Original Post
kingpinzs
kingpinzs
I am trying to move a dx3dsprite dwon the screen by using the up and down arrow keys but I also want it to just go to the menu iteams. Is there a simple way to increment only by 25 and not keep going like mine does tell it hits the bottom. I think my if loop is worng. if(Key_Down(DIK_DOWN)) { if(hlight.y <= 200) { hlight.y = (hlight.y + 25); } } I tryed this but it just keeps going tel it reaches 200.
GambitSnax
GambitSnax
Perhaps you could use the Key_Up event instead of Key_Down? This would mean it would only be called once with each key press.

Also,
hlight.y = hlight.y + 25 ;
is the same as
hlight.y += 25;
Trip99
Trip99
When you use DirectInput you do not get all the automatic key repeat delays etc. built into Windows so have to handle it all yourself. You will find holding a key will give you lost of key down events very quickly. The best solution is to take time into account - what is the time between key presses ?
------------------------See my games programming site at: www.toymaker.info
kingpinzs
kingpinzs
Quote:
Original post by GambitSnax
Perhaps you could use the Key_Up event instead of Key_Down? This would mean it would only be called once with each key press.


I tryed that but I dont know how to do Key_Up event.


Quote:
Original post by Trip99
When you use DirectInput you do not get all the automatic key repeat delays etc. built into Windows so [you] have to handle it all yourself. You will find holding a key will give you [lots] of key down events very quickly. The best solution is to take time into account - what is the time between key presses ?


I put in a timer for 30 milseconds but it still dont work like I want it to.
DeafManNoEars
DeafManNoEars

When you use DirectInput you do not get all the automatic key repeat delays etc. built into Windows so have to handle it all yourself. You will find holding a key will give you lost of key down events very quickly. The best solution is to take time into account - what is the time between key presses ?[/quote]

Microsoft recommends against using direct input as it is just a wrapper around the WM_INPUT data (see the quote below). The onlu suggested use for it would be to read joystick data.

Quote:
DirectInput is a set of API calls that abstracts input devices on the system. Internally, DirectInput creates a second thread to read WM_INPUT data, and using the DirectInput APIs will add more overhead than simply reading WM_INPUT directly. DirectInput is only useful for reading data from DirectInput joysticks; however, if you only need to support the Xbox 360 controller for Windows, then use XInput instead. Overall, using DirectInput offers no advantages when reading data from mouse or keyboard devices, and the use of DirectInput in these scenarios is discouraged.


Quote:
Original post by Trip99
See my games programming site at: www.toymaker.info


phenominal website, I have been there MANY, MANY, MANY times and learned tons a while back.

As far as the key-up event:
you want to have an input event when a key is released so you need to store the states of the keys from the last frame as well. you should have two arrays of chars to store the keyboard states. One array takes the current key states and one stores the keys from the last frame. If you want to know if a key was just
released it must have been pressed in the last frame but must not be
pressed in the current frame.

Hope this helps.

-Seth
kingpinzs
kingpinzs
Quote:
Original post by DeafManNoEars

As far as the key-up event:
you want to have an input event when a key is released so you need to store the states of the keys from the last frame as well. you should have two arrays of chars to store the keyboard states. One array takes the current key states and one stores the keys from the last frame. If you want to know if a key was just
released it must have been pressed in the last frame but must not be
pressed in the current frame.

Hope this helps.

-Seth


ooooh I was looking for something 100% different like it was an actual read in state not that it was just seen as a the same sate just not being executed if that makes since at all. Thanks I know what it needs now thanks for every ones help.

I think this issue should be covered under the FAQ just my opinion.
Evil Steve
Evil Steve
I have to ask - why are you using DirectInput? You'd be just as well using WM_INPUT since you get more control and less overhead. Or, if it's just basic input, use the WM_KEYDOWN and WM_KEYUP messages, as recommended by Microsoft.
kingpinzs
kingpinzs
Quote:
Original post by Evil Steve
I have to ask - why are you using DirectInput? You'd be just as well using WM_INPUT since you get more control and less overhead. Or, if it's just basic input, use the WM_KEYDOWN and WM_KEYUP messages, as recommended by Microsoft.


Why would they have directinput then? Which one is faster overall?
Elias
Elias
I'm studying computer engineering, and we usually use an automate which is a good method for reading such input. I'm not sure if this is the right way to do it in software, but in hardware it really works well.

So basically, you have an enumeration that is the state of the automate, and based on the state you decide what to do using a switch (select case in vb)

So in your case you will have say: up, down ...etc cases
in the up section of the switch, you read the input, and if you're not in the same state anymore, change the state variable to the new state, and so on

I hope this helps :D .. If you want, I can give you a more detailed example
kingpinzs
kingpinzs
I tryed this

#define KEYDOWN(name,key) (name[key] & 0x80) ? true:false
#define KEYUP(name, key) (name[key] & 0x80) ? false:true

but it says the key is always up I just want it to only change once I release the key so key down has to be excuted first
Cigguh
Cigguh

KeyUp?
Don't know maybe there's a better way but here's what i do:


#define KEYDOWN( name, key )			( (bool)( ( name[ key ] & 0x80 ) > 0 ) )#define KEYDOWN_PREV( name, key )		( (bool)( ( name[ key ] & 0x80 ) > 0 ) )#define BUTTONDOWN( name, key )			( (bool)( ( name.rgbButtons[ key ] & 0x80 ) > 0 ) )#define BUTTONDOWN_PREV( name, key )	( (bool)( ( name.rgbButtons[ key ] & 0x80 ) > 0 ) )void CGDInput::ReadKeys( void ){// saving buffers	CopyMemory( &DI_prMouseState, &DI_MouseState, sizeof(DI_MouseState) );	CopyMemory( &DI_prKeys, &DI_Keys, sizeof(DI_Keys) );//// then read new states	HRESULT hr;	hr = DI_KeyDev->GetDeviceState( sizeof(DI_Keys), (void*) &DI_Keys );	hr = DI_MouseDev->GetDeviceState( sizeof(DI_MouseState), (void*) &DI_MouseState );	}// these functions simply check if the state has changed to 'true' since previous update call.bool CGDInput::IsPrevKeyDown( byte key ){	return		(	( KEYDOWN( DI_Keys, key ) == true ) &&					( KEYDOWN( DI_prKeys, key ) == false ) );}bool CGDInput::IsPrevMouseDown( byte btn ){	return		(	( BUTTONDOWN( DI_MouseState, btn ) == true ) &&					( BUTTONDOWN( DI_prMouseState, btn ) == false ) );}
i make the game so i be ballin
Demirug
Demirug
Quote:
Original post by kingpinzs
Quote:
Original post by Evil Steve
I have to ask - why are you using DirectInput? You'd be just as well using WM_INPUT since you get more control and less overhead. Or, if it's just basic input, use the WM_KEYDOWN and WM_KEYUP messages, as recommended by Microsoft.


Why would they have directinput then? Which one is faster overall?


Mainly historical reasons. The Windows 9X based line had a message pipe that was not that well suited for real time applications like games. Therefore they build DirectInput to get more on the real metal. On the Windows NT based systems we have a complete different message pipe system and other Win32 functions to query input devices. On these systems DirectInput is even more away from the hardware as it is implements based on the Win32 functions. It is still supported because there is no good replacement for joystick inputs but in the case of keyboard and mouse vents you could use the Win32 functions instead of DirectInput.
kingpinzs
kingpinzs
well I went through this tut

http://www.gamedev.net/reference/articles/article1607.asp

mine is almost exactley the same but for some reason it thinks the key is always up but I want it to prosses key up only after key down and also it still jumps to the very bottom of the screen as soon as I press the key. Any ideas?


//----------------------------------------------------------------////keyboard//---------------------------------------------------------------//int Init_Keyboard(HWND hwnd){    //set the data format for mouse input    HRESULT result = dikeyboard->SetDataFormat(&c_dfDIKeyboard);    if (result != DI_OK)        return 0;    //set the cooperative level    result = dikeyboard->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);    if (result != DI_OK)        return 0;    //acquire the mouse    result = dikeyboard->Acquire();    if (result != DI_OK)        return 0;    //give the go-ahead    return 1;}void Poll_Keyboard(){    dikeyboard->GetDeviceState(sizeof(keys), (LPVOID)&keys);}int Key_Down(int key){	return ((keys[key] & 0x80) ? true:false);}int Key_Up(int key){	return ((keys[key] & 0x80)? false:true);}



this is were I am using it
I want it so no matter how long I hold down the down arrow key it will only move down once and wait tell I let up and press it again
void Menu(){     if(Key_Down(DIK_DOWN)&& hlight.y <= 175)	  {             hlight.y +=25;       }/* if(Key_Up(DIK_DOWN))	  {             hlight.y +=25;       }*/	  if(Key_Down(DIK_UP))	  {		   if(hlight.y >=140)		  {	        hlight.y -=25;  }	  }}

kingpinzs
kingpinzs
Any one know how to fix this issue
Evil Steve
Evil Steve
This is one of the nice things about Win32 that you don't get with DirectInput [wink]

Your Key_Down macro only checks if the key is pressed down. As soon as the key is pressed, this will return true until you let go. And since your app is probably running at several hundred FPS, you'll get that loop firing hundreds of times before you let go of the key.
What you want to do is record some sort of state, so you know that the key has been pressed, but not released yet.
kingpinzs
kingpinzs
Quote:
Original post by Evil Steve
This is one of the nice things about Win32 that you don't get with DirectInput [wink]

Your Key_Down macro only checks if the key is pressed down. As soon as the key is pressed, this will return true until you let go. And since your app is probably running at several hundred FPS, you'll get that loop firing hundreds of times before you let go of the key.
What you want to do is record some sort of state, so you know that the key has been pressed, but not released yet.


Thank you that is exactley what I did after trying to figure out how to do up key I just saved the pervouse state then waited for it to change. It works now thanks for every ones help could not of done it with out all of it.

Topic Locked

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

Sign in to reply to this topic.