keyup, keydown,slowkeydown
#1
Three little functions to help in using _keyhit for user input.
keyup only returns the release of a key
keydown only returns key presses and doesn't return negative values when a key is released.
Slowkeydown throttles how quickly entries are returned while holding down a key.


Code: (Select All)
_ControlChr Off
Print "press any key, <ESC> to exit"
Do
    'edit the comments to see the differences in behavior
    ' k = keydown
    k = keyup
    ' k = slowkeydown(5)
    _KeyClear
    Print k 'just the key hit value
    If Abs(k) > 0 And Abs(k) < 256 Then Print Chr$(Abs(k)) 'show the ascii value of the key press if it has one
    _Limit 60
Loop Until Abs(k) = 27



Function keyup
    'only returns negative values when a key is released
    'this will keep user from entering mutiple keypresses
    Do
        k = _KeyHit
        _Limit 60
    Loop Until k < 0
    keyup = k
End Function

Function keydown
    'only returns positive values when a key is pressed
    Do
        k = _KeyHit
        _Limit 60
    Loop Until k > 0
    keydown = k
End Function
Function slowkeydown (r)
    'returns positive vlaues when a key is pressed
    'the variable r sets the frequency of the do loop   , 60 would match the other functions here
    'it wouldn't be slow at all if r had a high value but i didn't want to call it speedkeydown or ratekeydown
    'this allows for continuous presses if a key is held down but not at machinegun rates
    Do
        k = _KeyHit
        _Limit r
    Loop Until k > 0
    slowkeydown = k
End Function
Reply
#2
Just curious; you do know that we have a _KEYUP and _KEYDOWN set of commands?
Reply
#3
(08-11-2022, 10:40 AM)SMcNeill Wrote: Just curious; you do know that we have a _KEYUP and _KEYDOWN set of commands?

Can not find a _KEYUP command in Help or Wiki.
Reply
#4
(08-11-2022, 10:40 AM)SMcNeill Wrote: Just curious; you do know that we have a _KEYUP and _KEYDOWN set of commands?


the keydown function I posted here returns any key pressed and in effect waits until a key is pressed so it isn't identical to the _keydown command, the _keydown command confirms if a specific key was pressed when polled.

_keyup doesn't exist on the wiki and it isn't recognized by the version of the compiler I'm still using.
Reply
#5
Steve is always 2 steps ahead of us, he's probably talking about future developments :-))

_KEYUP(kh&) = NOT _KEYDOWN(kh&)
b = b + ...
Reply
#6
(08-11-2022, 03:42 PM)bplus Wrote: Steve is always 2 steps ahead of us, he's probably talking about future developments :-))

_KEYUP(kh&) = NOT _KEYDOWN(kh&)

Actually, I was thinking we had some simple commands somewhere which only listed when keys went up and down.  Apparently we don't and those were library functions which I'd written once.  My apologies.

For an example of what I'm talking about, try this little code:

Code: (Select All)
Dim Shared As Long KeyBuffer(10), KeyDownKey, KeyUpKey
UpdateKeys = _FreeTimer
On Timer(UpdateKeys, .01) CheckKeys
Timer(UpdateKeys) On


Do
    kd = KeyOnlyDown
    ku = KeyOnlyup
    If kd Then Print "Key"; kd; "Pressed down"
    If ku Then Print "Key"; ku; "Released"
    _Limit 30
Loop



Sub CheckKeys
    K = _KeyHit
    Select Case K
        Case Is < 0 'keyup
            For i = 0 To 10
                If KeyBuffer(i) = Abs(K) Then KeyUpKey = Abs(K): KeyBuffer(i) = 0
            Next
        Case Is > 0 'keydown
            For i = 0 To 10
                If KeyBuffer(i) = Abs(K) Then Exit For
            Next
            If i > 10 Then
                For i = 0 To 10
                    If KeyBuffer(i) = 0 Then KeyBuffer(i) = Abs(K): KeyDownKey = Abs(K): Exit Sub
                Next
            End If
    End Select
End Sub

Function KeyOnlyDown&
    If KeyDownKey <> 0 Then KeyOnlyDown = KeyDownKey: KeyDownKey = 0
End Function

Function KeyOnlyup&
    If KeyUpKey <> 0 Then KeyOnlyup = KeyUpKey: KeyUpKey = 0
End Function

This *only* lists when a key goes down, or when a key comes up.  No repeat messages from it!  Just glancing over James's code, I saw the comment "only returns positive values when a key is pressed", so my brain was thinking it was working in a similar manner.

What we have above is a set of routines which tells you *only* when a key is pressed down, or when a key is released.  Of course, most keyboards only report 6 keys at a time or so, due to basic USB limitations, so if you want to go crazy and press a dozen keys down at once and hold them all, you'll probably end up glitching out the buffer here as I didn't write this little demo to deal with something that complex.
Reply
#7
A quick little update to handle the keyboard overflow type issue. Note that if you press 7+ keys down, you won't get a report on any key being lifted up until after you release them down to no more than 6 actually being pressed. Keyboards have a natural limit of 6 keys that they can report on at a time, and if you flood them with extra presses, you end up making them not very happy!

Code: (Select All)
Dim Shared As Long KeyBuffer(10), KeyDownKey, KeyUpKey
UpdateKeys = _FreeTimer
On Timer(UpdateKeys, .01) CheckKeys
Timer(UpdateKeys) On


Do
    kd = KeyOnlyDown
    ku = KeyOnlyup
    If kd Then Print "Key"; kd; "Pressed down"
    If ku Then Print "Key"; ku; "Released"
    _Limit 30
Loop



Sub CheckKeys
    K = _KeyHit
    Select Case K
        Case Is < 0 'keyup
            For i = 0 To 10
                If KeyBuffer(i) = Abs(K) Then KeyUpKey = Abs(K): KeyBuffer(i) = 0
            Next
        Case Is > 0 'keydown
            For i = 0 To 10
                If KeyBuffer(i) = Abs(K) Then Exit For
            Next
            If i > 10 Then
                For i = 0 To 10
                    If KeyBuffer(i) = 0 Then KeyBuffer(i) = Abs(K): KeyDownKey = Abs(K): Exit Sub
                Next
            End If
    End Select
    For i = 0 To 10 'check for lost reports
        K = KeyBuffer(i)
        If K <> 0 Then
            If _KeyDown(K) <> -1 Then
                KeyUpKey = K: KeyBuffer(i) = 0 'we missed a key up event - probably due to keyboard reporting limits
                Exit Sub
            End If
        End If
    Next
End Sub

Function KeyOnlyDown&
    If KeyDownKey <> 0 Then KeyOnlyDown = KeyDownKey: KeyDownKey = 0
End Function

Function KeyOnlyup&
    If KeyUpKey <> 0 Then KeyOnlyup = KeyUpKey: KeyUpKey = 0
End Function
Reply
#8
Sorry Pete, but I think about the only place where this becomes relevant is when the cat sneaks in and sits on the keyboard!
Of all the places on Earth, and all the planets in the Universe, I'd rather live here (Perth, W.A.) Big Grin
Reply
#9
Oh I like. There's times when multi-key presses are desirable.
Reply




Users browsing this thread: 4 Guest(s)