Archived

This topic is now archived and is closed to further replies.

MattS423

Macros and stuff

Recommended Posts

hey guys... can somebody tell me how this macro works? /////
  
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000 ? 1 : 0)

#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000 ? 0 : 1)
  
i didn''t quite understand the macro Definitions. also the book i''m reading says "you simply send the function [GetAsyncKeyState()] the virtual key code that you want to test, and if the high bit of the return value is 1, the key is pressed". now, the return value for GetAsyncKeyState is a SHORT. I assume a SHORT is a 2-bit interger. How do I check the high bit of a SHORT? (i assume it has something to do with < ? 0:1 > in the source above) thanks guys... --MattS423 the worlds worst pickup line: "If you were a hamburger at McDonalds, I''d call you the McBeutiful"

Share this post


Link to post
Share on other sites
a short is 2 bytes (or 16 bits). in hex, each digit represents 4 bits. so, 0x8000 (hex) == 1000 0000 0000 0000 (bin)... "&" is the bitwise AND operator, so "0x8000 & whatever" will return a non-zero value if and only if the first of 16 bits (high bit in a short) in "whatever" is set.

the "? :" stuff is the ternary operator, if is more or less a one-line "if...else" statement:
// see this?
if (expression)
SomeVar = DoThisIfTrue;
else
SomeVar = DoThisIfFalse;
// this is the same:
SomeVar = expression ? DoThisIfTrue : DoThisIfFalse;

Share this post


Link to post
Share on other sites
Just to build on the AND operator a little, here is a truth table.

(0 and 1 are ofcourse the bits that make up a byte)

1 AND 1 = 1
0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0

So as you can AND only returns 1 if both bits being "ANDed"(heh) are 1

For instance

use the decimal numbers 10 and 28...


10 AND 28 =


00001010
AND 00011100
------------
00001000


= 8(decimal)


I don''t know if that will help or not...

Share this post


Link to post
Share on other sites
so if i say 0x8000 that says to AND the first 16 bits by 1 such that...



//first param is the high 16 bits of the return value of
// GetAsyncKeyState()

1111 1111 1111 1111
AND 1111 1111 1111 1111 //this is the bitmask that i would use
-------------------------
1111 1111 1111 1111 //ok, the key is down



right?

Edit: oops

[edited by - MattS423 on November 1, 2002 4:06:12 PM]

Share this post


Link to post
Share on other sites
quote:
so if i say 0x8000 that says to AND the first 16 bits by 1 such that...


0x8000 = 1000 0000 0000 0000b (the "b" suffix stands for "binary")

GetAsyncKeyState(GAKS from now on) returns a 16bit number which I'm assuming varies in value. (You can get more info on it here, http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wceui40/htm/cerefGetAsyncKeyState.asp)

if the highest bit(the highest bit is the one farthest to the left) is "on" or is set to 1 it means the key is down, if it is "off" or is set to 0 the key is up.


So lets try the KEYDOWN "macro"... ANDing the value returned by GAKS by 0x8000 (see above) we can easily check to see if the highest bit is set (see truth table in previous post). So lets say that GAKS returns 35,900(decimal), (this is just a random value, so don't pay too much attention to it)...

Converting that to binary we'll see that it is 1000 1100 0011 1100b (Note: we don't have to worry about the conversion the computer always works in binary)

Moving on... Right away we can see that this values highest bit is turned on or set to 1, simple enough on paper, however we need to get a true or false out of this, this is where ANDing by 0x8000 comes in, so lets do it.



1000 1100 0011 1100
AND 1000 0000 0000 0000
-----------------------
1000 0000 0000 0000


Which gives us 0x8000, however we're interested not in the actual number but more in the fact that the number not zero, because any non-zero number evaluates to true, so applying this logic to the KEYDOWN macro we'll see in this case the key in question is indeed "DOWN".


Lets try this again, lets say GAKS returns 30,840, convert to binary...

0111 1000 0111 1000b

Again we can see what the highest bit is, this time it is turned off or set to 0, but as before we have to get a true or false out of it, so as before we have to manipulate the number so the computer can understand what seems obvious to us.



0111 1000 0111 1000
AND 1000 0000 0000 0000
-----------------------
0000 0000 0000 0000



And the survey says! Zero, and Zero evaluates to false, applying this to the KEYDOWN macro we know the key in question is not "DOWN".


So, I hope this helps, I know it is a little long winded, and I hope it doesn't have any bugs

I'd like to re-iterate that the numbers used above were for example ONLY, I've never used GAKS so I don't know if it has any pattern (Aside from the highest bit) when returning values.

[edited by - Xanth on November 1, 2002 6:28:19 PM]

[edited by - Xanth on November 1, 2002 6:29:26 PM]

Share this post


Link to post
Share on other sites
ok, i think i get it...thanks man.

an explaination to make sure i''ve got it...

0x8000 = 1000 0000 0000 0000

if GAKS returns any value with 1 in the first bit, then
if(GetAsyncKeyState(VK_KEY) & 0x8000) will evaluate true, otherwise false.

right?

Share this post


Link to post
Share on other sites
quote:
ok, i think i get it...thanks man.


You''re welcome


quote:
an explaination to make sure i''ve got it...

0x8000 = 1000 0000 0000 0000

if GAKS returns any value with 1 in the first bit, then
if(GetAsyncKeyState(VK_KEY) & 0x8000) will evaluate true, otherwise false.

right?


Yup, exactly!

Share this post


Link to post
Share on other sites