QB64 bug or exception?
#1
This should detect a space bar press, when other keys are held down like arrow key combinations. It does, except in the code snippet below...

If you hold down the ARROW UP and ARROW LEFT keys at the same time, and press the space bar, you won't hear the sound. Other combos like arrow up and arrow right held down while pressing the space bar will produce the sound.

So what's up? I further tested noted in my QB64 version 2.1 Development Build that the software is blocking INKEY$, _KEYHIT, and _KEYDOWN from registering CHR$(32). the space bar, under some key combination conditions, but not others.

Code: (Select All)
DO
    IF INKEY$ = CHR$(32) THEN SOUND 1000, .2 ' Fails detection while holding down arrow up and arrow left keys.
LOOP

Change CHR$(32) to CHR$(9), no problem.

Code: (Select All)
DO
    IF INKEY$ = CHR$(9) THEN SOUND 1000, .2 ' Works with all one or two arrow key combinations, including arrow up + arrow left.
LOOP

Change INKEY$ to _KEYHIT = 32 and it gets blocked again.

Code: (Select All)
DO
    IF _KEYHIT = 32 THEN SOUND 1000, .2 ' Works with all one or two arrow key combinations, including arrow up + arrow left.
LOOP

Same issue with _KEYDOWN (I swapped out sound for print to avoid annoying build up of sound.)

Code: (Select All)
DO
    _LIMIT 30
    IF _KEYDOWN(32) = -1 THEN PRINT _KEYDOWN(32); ' Works with all one or two arrow key combinations, including arrow up + arrow left.
LOOP

Any ideas as to why, or is this a bug that's been fixed in a newer version?

Pete
Reply
#2
(10-03-2022, 07:30 AM)Pete Wrote: This should detect the space bar pressed, even if other keys are held won,like arrow keys, but...

If you hold down the arrow up and arrow left keys at the same time, and press the space bar, you won't hear a sound. Try other combos like arrow up and arrow right while pressing the space bar and you will hear the sound.

So what's up? QB64 version 2.1 Development Build is blocking INKEY$, _KEYHIT, and _KEYDOWN from registering CHR$(32).

Code: (Select All)
DO
    IF INKEY$ = CHR$(32) THEN SOUND 1000, .2
LOOP

Change CHR$(32) to CHR$(9), no problem. Change INKEY$ to _KEYHIT = 32 or to _KEYDOWN(32) and it gets blocked again.

Any ideas as to why, or is this a bug that's been fixed in a newer version?

Pete

IMHO they (Galleon/QB64Team?) totally screwed the entire keyboard input system with the transition from SDL to OpenGL. I don't know how often I complained about in the .net forum, because I wasn't able to type a simple file path into the IDE, as the german keyboards key sequence for a backslash (AltGr+?) wasn't recognized. This finally was the reason for my alternative input routine which another member extended for more languages (follow green "Best Answer") link.

However, these will probably not solve your problem with recognizing multiple keys, but I bet its some of the same issue I had with the backslash. The whole keyboard input system should be ripped out and rebuild in a manner using the systems language/keyboard layout settings.
Reply
#3
So bug then. Nothing important to have it designed that way. Well, that's a shame, since the space bar is such a nice shooter key. There really isn't a good ergonomic substitute for it. Anything else would be like piloting the Enterprise, and discovering warp drive is a stick shift. Oh wait, that's kind of cool. Never mind.

Pete
Reply
#4
Inkey$ seem to return the latest keypress in favor of the one you have been holding down for a while. It isn't just an issue with the space key.

see code: 


Inkey$ seem to return the latest keypress in favor of the one you have been holding down for a while. It isn't just an issue with the space key.

see code: 
Code: (Select All)
_ControlChr Off
Do
    k$ = InKey$
    If k$ = Chr$(32) Then Sound 1000, .2
    If k$ <> "" Then Print Asc(k$),
Loop


hold down a button its 'asc code is reported.  keep holding it down and press another key and the new key is reported and it will block reporting on the original key until it is released.
Reply
#5
Noted, but this is an issue about playing nice with _KEYDOWN(), which it does until you hold down the cursor key combo arrow up and arrow left. That's the combo that blocks it, _KEYHIT, or even _KEYDOWN(32) from being registered when those two arrow keys are held down. So, it's not really an INKEY$ issue. Also, if we change that CHR$(32) to something else like CHR$(9) then it works with all eight directional arrow keys (4 single and 4 double) combinations. I see no reason this same functioning shouldn't work with the space bar key since it does work with other third key presses like Tab. I'm with Rho on this one, bug! It's a shame, too, since QB64 added keyboard statements were the first breakthrough in detecting more than a two-key event. Maybe an alert should be placed in the Wiki to this regard, if it is not fixable in time?

Pete
Reply
#6
_keyhit doesn't report the mashed key after it is interrupted with another key either (as noted) until after the original mashed key is released

Code: (Select All)
_ControlChr Off
Do
    k = _KeyHit
    If k = 32 Then Sound 1000, .2
    If k <> 0 Then Print k,
Loop

definitely in bug land.
Reply
#7
Yah I discovered a problem last night with this code:
Code: (Select All)
_Title "Use arrow keys to move our hero, spacebar to shoot."
Type bullet
    As Integer x, y, dx, dy, alive
End Type
nBullets = 100
Dim bullets(1 To nBullets) As bullet

heroX = _Width \ 2: heroY = _Height \ 2 ' middle
Do
    Cls
    For i = 1 To nBullets
        If bullets(i).alive Then
            bullets(i).x = bullets(i).x + bullets(i).dx: bullets(i).y = bullets(i).y + bullets(i).dy
            If bullets(i).x > 0 And bullets(i).x <= _Width Then
                If bullets(i).y > 0 And bullets(i).y <= _Height Then

                    Locate bullets(i).y, bullets(i).x: Print "*";
                Else
                    bullets(i).alive = 0
                End If
            Else
                bullets(i).alive = 0
            End If
        End If
    Next
    dx = 0: dy = 0
    Locate heroY, heroX: Print Chr$(1);
    If _KeyDown(19200) Then heroX = heroX - 1: dx = -1
    If _KeyDown(19712) Then heroX = heroX + 1: dx = 1
    If _KeyDown(18432) Then heroY = heroY - 1: dy = -1
    If _KeyDown(20480) Then heroY = heroY + 1: dy = 1
    If _KeyDown(32) And (dx Or dy) Then GoSub shoot
    If heroX < 1 Then heroX = 1
    If heroX > _Width Then heroX = _Width
    If heroY < 1 Then heroY = 1
    If heroY > _Height Then heroY = _Height
    _Limit 10
Loop

shoot:
For i = 1 To 100
    If bullets(i).alive = 0 Then
        bullets(i).alive = -1
        bullets(i).x = heroX + dx * 2: bullets(i).y = heroY + dy * 2
        bullets(i).dx = dx * 2: bullets(i).dy = dy * 2
        Exit For
    End If
Next
Return

I can shoot (3 keypresses) Spacebar + Up and Right or Spacebar + Down and Left but not Spacebar + Up and Left Nor Spacebar + Down and Right. No problems if just Spacebar and one arrow key.

Even tried this mod:
If _KeyDown(32) And ((dx <> 0) Or (dy <> 0)) Then GoSub shoot 
no difference.
b = b + ...
Reply
#8
Ok, this explains the strange results I was getting in my Mario particle fountain in the tutorial:

https://www.qb64tutorial.com/lesson18#h.z8t9row5ze9h

The space bar is used through _KEYHIT and the enter key is used through _KEYDOWN

If you hold the space bar down the enter key will never be seen. If you hold the enter key down however the space bar will be seen. I thought this might have been a bug but was too busy working on the tutorial and forgot to mention it.
Reply
#9
I edited the above post to demonstrate a bit more of what I described. I included this snippet to show the keyboard output with the 5 keys in question, arrow key(s) and space bar...

Code: (Select All)
' Hold down any two or three arrow keys at once then repeatedly press the space bar.
' You will see the arrow keys register as 1 for on or 2 for off.
' You will see the space bar output flicker 0 to 1 as your toggle the space bar,
' except when the arrow up and arrow keys are held down.
WIDTH 87, 25
DO
    _LIMIT 30
    IF _KEYDOWN(18432) THEN a = 1 ELSE a = 0 ' Up-arrow.
    IF _KEYDOWN(19712) THEN b = 1 ELSE b = 0 ' Right-arrow.
    IF _KEYDOWN(20480) THEN c = 1 ELSE c = 0 ' Down-arrow.
    IF _KEYDOWN(19200) THEN d = 1 ELSE d = 0 ' Left-arrow.
    IF INKEY$ = CHR$(32) THEN e = 1: SOUND 1000, .1 ELSE e = 0 ' Space bar.
    LOCATE , 1: PRINT "Arrow up key ="; a;
    LOCATE , 19: PRINT "Arrow rt key ="; b;
    LOCATE , 37: PRINT "Arrow dn key ="; c;
    LOCATE , 55: PRINT "Arrow lt key ="; d;
    LOCATE , 73: PRINT "Space bar ="; e;
LOOP

Thanks for checking into this, guys. I think it should be reported as a bug and as Rho pointed out, there are apparently other issues that need to be addressed in the QB64 keyboard functions.

Pete
Reply
#10
playing with key input because of other posts brought me to this horrible calamity.... the beeping doesn't stop if you press the spacebar/

Why?  It stops if you uncomment the _limit command it behaves like I'd expect but otherwise it keeps playing....

I don't understand why this happens.

Yes a _limit inside a loop is sensible .... but should this be expected? 

Code: (Select All)
Do
    If _KeyDown(32) Then Sound 1000, 0.1 'rerally don't press the spacebar you'll be sorry

    If _KeyDown(27) Then GoTo exitloop
    If _KeyDown(97) Then Print "A";

    _Display
    '_Limit 60
Loop
exitloop:

What is _limit actually doing?   Why does it work (just reads each key press) with _limit uncommented?
Reply




Users browsing this thread: 5 Guest(s)