Handmade Hero»Forums»Code
Iker Murga
43 posts
Question/Complaint about IsDown/WasDown
I think there might be something I don't understand in the logic of the windows message flags we use in IsDown / WasDown, and since it came up on last night's stream (and I guess we will continue using it on tonight's) I am trying to see if somebody will clear it out for me.

What is the logic by which the previous key-state flag and the transition-state flag seem to be inversed? As a reminder, these are the 30th and 31st bits on the lParam in the WM_KEYDOWN, WM_SYSKEYDOWN, WM_KEYUP and WM_SYSKEYUP messages. The 30th bit flags the "previous key state" as in was it down before the message was sent or not. The 31st bit is the "transition-state flag" , which we are pretty much using as a "is the button down or not" flag.

However, the bit values seem reversed: on the previous state bit a 1 means the key was DOWN, 0 if the key was UP. On the transition 1 means the key is UP and 0 DOWN. My guess is the we are simplifying the meaning of the 31st bit flag, but in the MSDN documentation all I found is that it flags "whether pressing a key or releasing a key generated the keystroke message" ... which didn't really clear it for me. This discrepancy creates these weird (to me) looking bool assignments:

1
2
bool32 WasDown = ((Message.lParam & (1 << 30)) != 0);
bool32 IsDown = ((Message.lParam & (1 << 31)) == 0);


Can anybody enlighten me or am I forever doomed be bothered by this strange looking "isEqual/isNotEqual even though we are both checking if a key is down" thing?
Allen Webster
476 posts / 6 projects
Heyo
Question/Complaint about IsDown/WasDown
If you visit this page on MSDN found by searching "WM_KEYDOWN" it lists what the bits mean for the lParam:

30 The previous key state. The value is 1 if the key is down before the message is sent, or it is zero if the key is up.
31 The transition state. The value is always 0 for a WM_KEYDOWN message.

The 30th bit is a 1 when it "was" down and is 0 when it "was" up. The 31st bit is always 0 for WM_KEYDOWN. When the key is being held windows will keep sending this message, so the 30th bit will be a 0 the first time it is sent, and a 1 after that.

For WM_KEYUP it says:
30 The previous key state. The value is always 1 for a WM_KEYUP message.
31 The transition state. The value is always 1 for a WM_KEYUP message.

The 30th bit is always a 1 and the 31st bit is always a 1. Windows only sends this message the moment you release, not every moment while the key is unpressed.

So in any case the 30th bit is a 1 when it was previously pressed and 0 otherwise. While the 31st bit is a 0 when it is being pressed and a 1 at the moment of release. So, unfortunately for you, the != and == are correct.
Iker Murga
43 posts
Question/Complaint about IsDown/WasDown
Edited by Iker Murga on
Oh, I apparently explained myself wrong. I do understand the code is right, what I don't understand is the logic that Microsoft followed to make a 1 mean key pressed in one case and 0 also mean key pressed in the other one, instead of 1 meaning key pressed on both the 30th and 31st bits.
Allen Webster
476 posts / 6 projects
Heyo
Question/Complaint about IsDown/WasDown
Oh I see. I agree that their system is silly. I personally would have flipped the 31st bit because making down mean true and up mean false makes the most sense to me.

The only thing I can think of that's *sort of* nice is that at the moment you press the key those bits are 00 and at the moment you release they are 11. So maybe they thought identifying presses and releases with the same bit was more important than identifying states with the same bits.