Handmade Hero » Forums » Code » Set Keyboard Input to not repeat
Zilarrezko
Jesse Coyle
37 posts
#2954 Set Keyboard Input to not repeat
4 years, 2 months ago Edited by Jesse Coyle on March 9, 2015, 3:17 a.m. Reason: more specific title

Sup everybody.

I've been following along with handmade hero for a bit, and I wanted to use what I have so far with school, and I was going to use SFML like the class was suppose to. But I got the go ahead to use this.

However I have encountered a small problem with using keyboard input... And that's the keys are repeating while you hold it down. I've looked on msdn (very intimidating to try and understand their terms and code usage). But I can't find a way that you press the key and it only processes the message once, until the key is lifted. I thought the (if(WasDown != IsDown)) was suppose to take care of that, but I'm probably wrong.

When I encompass the ProcessKeyboardMessage function call with an if statement of if(IsDown) then if I press the key once and release it, it will go on as if I still had the key pressed.

The project is over 10 days late, and I don't want to wade around msdn trying to read over.

Sorry if I seem a bit desperate...

I guess it would be unorthodox to not have the source... (attached)
mmozeiko
Mārtiņš Možeiko
1924 posts / 1 project
#2955 Set Keyboard Input to not repeat
4 years, 2 months ago Edited by Mārtiņš Možeiko on March 9, 2015, 3:56 a.m.

I don't see your source, but on WM_KEYDOWN MSDN page for bit 30 it says:
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.
It's pretty clear that if bit 30 == 1 then key was already down. Basically you could process WM_KEYDOWN message only if bit 30 == 0 and ignore otherwise.
Zilarrezko
Jesse Coyle
37 posts
#2956 Set Keyboard Input to not repeat
4 years, 2 months ago Edited by Jesse Coyle on March 9, 2015, 4:25 a.m. Reason: ...

Ah, so in place of WasDown != IsDown I should do: ((Message.lParam & (1 << 30)) == 0) right? Though it gives the same outcome as if I pressed the key and never let go.

I must not have pressed add file. I'll try again.

[attachment=27]singularity_win32.zip[/attachment]
Zilarrezko
Jesse Coyle
37 posts
#2959 Set Keyboard Input to not repeat
4 years, 2 months ago

Is this a loss cause? I still need help.

I need to move on to other stuff, so I may just instead keep my current code of having it only process the keyboard keys every few seconds. The problem with that is that it doesn't give immediate feedback, and is quite awkward.
knik
Krzysiek
17 posts
#2961 Set Keyboard Input to not repeat
4 years, 2 months ago

Casey's processing of these messages is clever indeed.

You can try something simpler, you can process WM_KEYUP and WM_KEYDOWN messages separately.
When processing WM_KEYUP you don't need to care about those extra flags, it just means the key went up and is no longer pressed.

Such separated code may be easier to understand.
Zilarrezko
Jesse Coyle
37 posts
#2962 Set Keyboard Input to not repeat
4 years, 2 months ago

I've tried it, Got rid of the wasdown != isdown check, and made keyup serperate as well as vice versa, no dice.

Pretty much giving up on that, maybe I'm just too stupid as far as manipulating bits to make it do what I want.

Thanks for your effort though guys, I appreciate it.
Kknewkles
11 posts
#2963 Set Keyboard Input to not repeat
4 years, 2 months ago Edited by Kknewkles on March 10, 2015, 2:08 p.m.

Day 6, 42:30 - Casey starts coding the keyboard input.
From what I remember, while you hold the key down there is no repetition of the button press register.

Yep, that's correct.
The trick is to assign the thing you want to do to IsDown only. Well, if it suits your need of course. In my case, I wanted to call a procedure each time I hit arrow up or down.


I skimmed through your source and I'd try this: you went for a smart thing and you pass the IsDown as a parameter to your custom function. Why not do the simpler, basically braindead-easy thing and not change this

1
2
3
4
else if(VKCode == VK_LEFT)
{
	Win32ProcessKeyboardMessage(&KeyboardController->ActionLeft, IsDown);
}


to this?

1
2
3
4
5
6
7
else if(VKCode == VK_LEFT)
{
	if(IsDown)
	{
		Win32ProcessKeyboardMessage(&KeyboardController->ActionLeft);
	}
}


You'd have to change the Win32ProcessKeyboardMessage, but seems to me it'd be worth it.


Or maybe you just mostly copy-pasted Casey's code without going over it. I've done that too many times to not know how freaking deadly a practice this is. Guess now you do too :/

This linguistic cadaver of a nickname is pronounced [K'nu:kls].
In case anyone's interested.

27.7.15
I had this in a signature? Wow! :D
Zilarrezko
Jesse Coyle
37 posts
#2969 Set Keyboard Input to not repeat
4 years, 2 months ago

I think the problem is that the key is down, and every frame it looks at the controller and sees if it's down. If the last thing wasn't wasdown then it processes it every frame. Or at least a scenario just like it?

Just as when Casey starts on his player movement in day... 28 I think or something, whenever tilemap is... His controller is being processed every frame to add the "velocity" to the players position.

I made a video, showing the points of question... and trying out your suggestion. Maybe I'm still too stupid to find the problem underneath my nose/can't figure out what you guys are suggesting.
Link
Kknewkles
11 posts
#2971 Set Keyboard Input to not repeat
4 years, 2 months ago Edited by Kknewkles on March 11, 2015, 7:59 a.m.

1) Sorry for implying the copy-paste.
2) I have no idea what the hell happened there, the pieces morphing wildly on escape? I wish I had a gamepad to fiddle with all that goodness... But it shouldn't be dependent on gamepad... boy. That's some weird stuff.

This linguistic cadaver of a nickname is pronounced [K'nu:kls].
In case anyone's interested.

27.7.15
I had this in a signature? Wow! :D
Zilarrezko
Jesse Coyle
37 posts
#2972 Set Keyboard Input to not repeat
4 years, 2 months ago

To be honest, almost word for word, my win32 is the same as Casey's, so you're actually almost right, I did however type it all myself (aside from the copy and paste from msdn). I'm just slapping Tetris into the game layer just as Casey has done (from what I know of).

What escape does, is it deletes the pointed to tetrimino, tetrimino buffer, and well (the game board) via their pointers. Then gives them new ones via the new keyword. (This works with a gamepad, and keyboard. With keyboard it's up left right and down, and escape and space. With gamepad it's X B Y and A, and Start and Back).

What I think is happening here... Is that Casey (probably because he never needed it) never implemented on game processing side for a button to only be needed to be pressed, then do something... And not do that thing again til we release the key, and press it again.

But I don't think that's true, as I believe when he did the throwing sword thing later, it doesn't appear he's creating a sword every frame. I guess somewhere in-between he implemented what I'm looking for somewhere between the latest thing I've watched, episode 28, and episode 62. Sadly I turned my homework in about 7 days late, so it really doesn't matter anymore, though for future reference I would like to know.

Now, I have the problem of how to use his File I/O since fstream is throwing errors from xlocale, probably something to do with not using VS, but I'll make a separate post for that...

I appreciate everyone's contribution, I probably should have just used SFML to make things a bit easier on me.
knik
Krzysiek
17 posts
#2973 Set Keyboard Input to not repeat
4 years, 2 months ago

Generally when you read keyboard input you can have two different approaches.

In games you typically need to know key state every frame so you need to buffer the state somehow.
When you get keydown message you set the key buffer, when keyup you reset the buffer. This way you always know if key is down or up.

The other case is e.g. text editor where you just respond to keydown events and you don't need to know key state.
In such case, if you want to disable key repeat you just ignore keydown message if wasdown is set.