Jump to content

  • Log In with Google      Sign In   
  • Create Account

Exit game from another class (Input)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
51 replies to this topic

#41 falcon93   Members   -  Reputation: 121

Like
0Likes
Like

Posted 05 August 2011 - 12:39 PM

Well, I don't have any good explanation Posted Image

So, I call the GetAsyncKeyState method, which returns a SHORT. How should I handle it?

If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState.



Sponsor:

#42 rip-off   Moderators   -  Reputation: 8222

Like
0Likes
Like

Posted 05 August 2011 - 01:26 PM

What have you tried?

#43 falcon93   Members   -  Reputation: 121

Like
0Likes
Like

Posted 05 August 2011 - 02:00 PM

I havn't tried anything as I have no idea what a SHORT is and what the method will return. I guess that a SHORT is somekind of string or "datatext", but I have no idea what it will contain when the method has been called. There's no info about this in the MSDN :/

#44 ApochPiQ   Moderators   -  Reputation: 15736

Like
1Likes
Like

Posted 05 August 2011 - 04:44 PM

SHORT, aka short, is just a 16-bit integer on Win32.

#45 falcon93   Members   -  Reputation: 121

Like
0Likes
Like

Posted 05 August 2011 - 05:01 PM

So if the button is pressed, the return value should be 1? And if it isn't pressed, it should be 0?

#46 rip-off   Moderators   -  Reputation: 8222

Like
1Likes
Like

Posted 05 August 2011 - 06:14 PM

I havn't tried anything as I have no idea what a SHORT is and what the method will return. I guess that a SHORT is somekind of string or "datatext", but I have no idea what it will contain when the method has been called. There's no info about this in the MSDN :/

My link was supposed to inspire you to do some independent research. Throwing "GetASyncKeyState" or "GetASyncKeyState example" into Google yields lots of results. They may be of varying quality, but you should get a good idea how to call this function by viewing a few examples.

So if the button is pressed, the return value should be 1? And if it isn't pressed, it should be 0?

No. If it were that simple, it would be documented as doing that.

#47 falcon93   Members   -  Reputation: 121

Like
0Likes
Like

Posted 06 August 2011 - 10:00 AM

Ok, so I tried this:

bool Input::KeyDown(USHORT key)
{
if (GetAsyncKeyState(VK_LEFT))
{
return true;
}

return false;
}

And it works fine. Is it "correct"?

Also, what purpose does the raw input have if checking keyboard events is this easy?

#48 rip-off   Moderators   -  Reputation: 8222

Like
0Likes
Like

Posted 07 August 2011 - 10:21 AM

Is it "correct"?

No. As the documentation describes, the key is down if the high bit is set. For a 16 bit SHORT, the high bit can be isolated by masking with the value 0x8000. This can be found in countless examples if you actually Googled like I had suggested earlier.

We're not going to write your programs for you. You need to demonstrate that you can look up trivial stuff yourself if you expect us to help you.

Also, what purpose does the raw input have if checking keyboard events is this easy?

My understanding is that it is not generally used with keyboards. See here for times when you might use it.

#49 falcon93   Members   -  Reputation: 121

Like
0Likes
Like

Posted 07 August 2011 - 12:42 PM

I'm trying to do my best, sorry. I've used google, but that only made me more confused.

http://www.mpgh.net/...nckeystate.html

The least significant bit:
"and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior; for more information, see the Remarks."


Pay special attention to that last sentence because here is why. In the days of DOS, programs ran one at a time all in order. In other words windows gave all programs full access to its CPU and if one program wanted to take a particularly long time running and not give up control of the CPU it could. However with modern operating systems Windows only gives programs a set amount of time to run, then it interrupts their process and share the CPU with other programs so that one can't hog all the fun. Posted Image
With this also came the process of multithreading, now you don't need to know what this is though by all means look it up if you want, but just understand that multithreading creates parallelism which speeds up the execution of code in multiprocessor systems.

What this means is code that was written like this:
if(GetAsynKeyState(VK_INSERT)); //first
if(GetAsynKeyState(VK_DELETE)&1); //second

can execute like this:
if(GetAsynKeyState(VK_INSERT)); //first
if(GetAsynKeyState(VK_DELETE)&1); //same time

So while this testing the least significant bit thing was okay for 16 bit DOS. It is not okay for modern multithreaded system. Now given it isn't exactly like that. This is more psuedo code thin anything, when ur accessing API functions this could very well be the case, and it is only still there for backwards compatibility.

Removing the least significant bit from the equation means that only the most significant bit is left. And since this:
if(GetAsynKeyState(VK_INSERT)&0x8000)

Does the same thing as this:
if(GetAsynKeyState(VK_INSERT))...

There is no longer any need to even mess with MSB or LSB at alll and you misewell save time as well as peace of mind and do it the easy way.



They say that the &0x8000 is unnececcary? You say that it is required? You see why I'm confused? :wink: So which one should I follow?

#50 rip-off   Moderators   -  Reputation: 8222

Like
1Likes
Like

Posted 07 August 2011 - 04:19 PM

If you don't mask out the bits, you may erroneously treat a just-released key as a pressed key for a frame. This may or may not be noticeable, depending on what you do when a key is released.

#51 falcon93   Members   -  Reputation: 121

Like
0Likes
Like

Posted 09 August 2011 - 09:28 AM

Ok, i've added the 0x8000 mask. Below is my current code in Input.cpp. Is there anything you think isn't correct here or is it ok?

[source lang="cpp"]#include <Windows.h>#include "Input.h"#include "Main.h"Input::Input(){}Input::~Input(void){}// --------------------------------------------------------------------------------// Name: ButtonDown// Desc: Checks if a specific keyboard/mouse button is pressed// Rtrn: Returns true if the button is pressed// --------------------------------------------------------------------------------bool Input::ButtonDown(USHORT key){ if (GetAsyncKeyState(key)&0x8000) { return true; } return false;}// --------------------------------------------------------------------------------// Name: ButtonDownOnce// Desc: Checks if a specific keyboard/mouse button is pressed// Rtrn: Only returns true once per click// --------------------------------------------------------------------------------bool Input::ButtonDownOnce(USHORT key){ if (ButtonDown(key)) { if (pressed_keys.empty()) { pressed_keys.push_back(key); return true; } else { for (std::list<USHORT>::const_iterator current = pressed_keys.begin(); current != pressed_keys.end(); current++) { if (*current == key) { return false; } } return true; } } if (ButtonUp(key)) { pressed_keys.remove(key); } return false;}// --------------------------------------------------------------------------------// Name: ButtonUp// Desc: Checks if a specific keyboard/mouse button is up// Rtrn: Returns true if the button is up// --------------------------------------------------------------------------------bool Input::ButtonUp(USHORT key){ if (!GetAsyncKeyState(key)&0x8000) { return true; } return false;}[/source]



#52 rip-off   Moderators   -  Reputation: 8222

Like
0Likes
Like

Posted 09 August 2011 - 12:52 PM

That looks ok, but I'm skeptical about you ButtonDown logic. It only adds buttons when the list is empty, which means it only works when you care about testing a single button.

I'd write it like so:
#include <algorithm>

bool Input::ButtonDown(USHORT key)
{
	return (GetAsyncKeyState(key) & 0x8000);
}

bool Input::ButtonUp(USHORT key)
{
	return !ButtonDown(key);
}

bool Input::ButtonDownOnce(USHORT key)
{
	std::vector<USHORT>::const_iterator it = std::find(pressed_keys.begin(), pressed_keys.end(), key);
	if (ButtonDown(key))
	{
		if(it == pressed_keys.end())
		{
			pressed_keys.push_back(key);
			return true;
		}
		return false;
	}
	else // Button is up
	{
		if(it != pressed_keys.end())
		{
			pressed_keys.erase(it);
		}
		return false;
	}
}
Note I'm using std::vector<> rather than std::list<>. While std::list is theoretically better for removing items in the middle of the list, for a small list like this std::vector<> will likely be the best choice. std::list involves allocation, which can fragment the heap and trash your cache, whereas std::vector provides roughly the same interface without incurring these costs.

Another would be to have a 256 length array of boolean values, which you can use to test if a key is moving from released to pressed.

However, you are not likely to be calling this many times a frame, so I wouldn't worry too much about it.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS