Handmade Hero » Forums » Code » Struggling with keyboard input (Window Messages)
Louring
Lionel Stephen
2 posts
#11629 Struggling with keyboard input (Window Messages)
1 month, 2 weeks ago Edited by Lionel Stephen on April 8, 2017, 12:18 a.m.

Hello,
I'm new to the series and brand new to the forum, but I'm loving the adventure so far...

However I don't like copying without really understanding and am always searching
deeper into how things work.

I'm following the series but every time I don't understand something I start implementing it myself,
usually with really ugly code, but I enjoy learning how it all works. However as you would expect
I've struggled with everything and only made it to episode 9 or so... just finished implementing
DirectSound in pure c... I hate COM xD

Anyway, my issue is window messages. I've tried to use WASD and Arrow keys for movement, but in a simple
test, Arrows key end up sending thousands of messages a second. While Characters send messages as you
would expect ( a pause, then repeat is activated ).
-- This is the code I'm using for testing at the moment:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
...
switch(message){
		//case WM_SYSKEYUP:
		//case WM_KEYUP:
		//case WM_SYSKEYDOWN: 
		case WM_KEYDOWN: {
			switch(wParam){
				case VK_LEFT: {
					arrow++; //arrow is a global variable for testing
				}break;
				case 0x41: { //'A'
					letter++;//same as arrow
				}break;
				default: {
				}break;
			}
		}break;
...

-- I then print out the variables:

printf("> arrow : %d \n> letter : %d \n", arrow, letter);

-- The output after holding down each key for (roughly) 2 seconds is this:
(both variables are initialised to zero)
arrow : 621096
letter : 31

If my keyboard isn't the culprit then I suggest
I have to manipulate the repeat-count of the messages,
or process a certain amount of messages per frame

This is probably normal behaviour but I can't find any reference to it
(that's why I'm making a post)
I've tried moving until the WM_KEYUP and WM_SYSKEYUP messages are processed
and I get better movement, the difference in messages
is still huge and it feels wrong and I don't understand it :-(

If someone knows what's going on here please let me know.


By the way this is my first forum post ever, I hope it's in the right place and such
Thankyou
mmozeiko
Mārtiņš Možeiko
1313 posts
1 project
#11631 Struggling with keyboard input (Window Messages)
1 month, 2 weeks ago Edited by Mārtiņš Možeiko on April 8, 2017, 7:54 a.m.

Are you sure you are not processing same message multiple times? Keyrepeat usually is far less than 621096 keydown messages per 2 seconds.
Are you sure you initialized arrow variable to 0 and its type is int (because of %d) ?
I just tried counting VK_LEFT's for wParam on WM_KEYDOWN message in my code and I get ~40 per 2 seconds on my machine. So error must be in some other part of your code.

Btw, instead of case 0x41 you can simply write case 'A'. That will save you some typing for a comment.
Louring
Lionel Stephen
2 posts
#11632 Struggling with keyboard input (Window Messages)
1 month, 2 weeks ago

Wow, I can't believe I'm so stupid, such a little thing giving me so much trouble :/
I had my Translate and Dispatch functions outside the PeekMessage if statement...

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
...
while(running == 1){
                BOOL bool_message = PeekMessage(&window_message, window_handle, 0, 0, PM_REMOVE);

		if(bool_message != 0){
			if(window_message.message == WM_QUIT){
				printf("> window_message.message : WM_QUIT \n");
				Running = 0;
				break;
			}
	        }
		TranslateMessage(&window_message);
	        DispatchMessage(&window_message);
...

I just changed it, and get expected results.
Thank you very much Mārtiņš Možeiko.
ripple
4 posts
#11639 Struggling with keyboard input (Window Messages)
1 month, 2 weeks ago

You are also missing the check for repeated key presses

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
{
    uint32 VKCode = (uint32)wParam;

    bool32 WasDown = ((lParam & (1 << 30)) != 0);
    bool32 IsDown = ((lParam & (1 << 31)) == 0);
    if (WasDown != IsDown)
    {
        if (VKCode == 'W')
        ...