Author Topic: Odd multiple input problem  (Read 4016 times)

0 Members and 1 Guest are viewing this topic.

Offline johannhowitzer

  • Forum Regular
  • Posts: 118
    • View Profile
Odd multiple input problem
« on: July 11, 2019, 02:44:13 am »
Hey all.  I'm working on a prototype for a shooter, and it has aimable shooting.  Here's the code block that handles inputs.

Code: QB64: [Select]
  1.    throw.x = 0
  2.    if _keydown(cvi(arrow(left))) = true then throw.x = -1
  3.    if _keydown(cvi(arrow(right))) = true then throw.x = 1
  4.    throw.y = 0
  5.    if _keydown(cvi(arrow(up))) = true then throw.y = -1
  6.    if _keydown(cvi(arrow(down))) = true then throw.y = 1
  7.    if throw.x = 0 and throw.y = 0 then throw.x = 1
  8.  
  9.    if _keydown(asc(" ")) = true and spacepress = false then
  10.       spacepress = true
  11.       call spawn_shot(0, throw.x, throw.y)
  12.    end if
  13.  
  14.    if _keydown(asc(" ")) = false and spacepress = true then spacepress = false

arrow() just contains the ASCII arrow key data.  The arrow key section acts like a joystick and respects held inputs to aim 8-way, with "neutral" position resulting in aiming to the right by default (sidescroller like Gradius).  I have an aiming indicator and this is behaving properly.

What's unusual is that this IS working for shooting in all of the 8-way input directions... except up-left.  It will aim that way, but the spacebar isn't causing a shot to spawn.  There is shot to ship collision, but every shot carries the index of the ship that created it - that's what the first parameter "0" is in spawn_shot, and the collision routine ignores matching ships and shots to avoid friendly fire, so the shot isn't immediately hitting the player's ship here.

EDIT: This is really weird.  Further bug testing showed that only certain combinations of three keys do not play nice with _keydown.  Specifically, it doesn't like up, left, and space together.  When I held left, then added holding space, then pressed up, the aiming indicator did not move to aiming up-left.
« Last Edit: July 11, 2019, 02:53:47 am by johannhowitzer »

FellippeHeitor

  • Guest
Re: Odd multiple input problem
« Reply #1 on: July 11, 2019, 06:07:51 am »
You’ve found your keyboard’s hardware limitation to detect multiple keys down at once. https://en.wikipedia.org/wiki/Rollover_(key)

You’re likely to get different results across different systems you’ll test your game in.
« Last Edit: July 11, 2019, 10:18:24 am by FellippeHeitor »

FellippeHeitor

  • Guest
Re: Odd multiple input problem
« Reply #2 on: July 11, 2019, 07:45:38 am »
Try this:
Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(400, 400, 32)
  2.  
  3.  
  4. midx = _WIDTH / 2
  5. midy = _HEIGHT / 2
  6.  
  7.     xdir = 0
  8.     ydir = 0
  9.  
  10.     IF _KEYDOWN(18432) THEN ydir = ydir - 1
  11.     IF _KEYDOWN(20480) THEN ydir = ydir + 1
  12.     IF _KEYDOWN(19200) THEN xdir = xdir - 1
  13.     IF _KEYDOWN(19712) THEN xdir = xdir + 1
  14.  
  15.     shooting = _KEYDOWN(32)
  16.     IF shooting THEN col = _RGB32(255, 0, 0) ELSE col = _RGB32(255)
  17.  
  18.     CLS
  19.     COLOR col
  20.     PSET (midx, midy)
  21.     DRAW "D " + STR$(150 * ydir) + "R " + STR$(150 * xdir)
  22.     _DISPLAY
  23.     _LIMIT 30

On my machine I can go all directions and still shoot with space. What results do you get with the snippet above?
« Last Edit: July 11, 2019, 07:58:43 am by FellippeHeitor »

Offline johannhowitzer

  • Forum Regular
  • Posts: 118
    • View Profile
Re: Odd multiple input problem
« Reply #3 on: July 11, 2019, 08:36:32 am »
With your code, the lines turned red in every direction but up-left.  "Key jamming and ghosting" section of that Wikipedia article seems relevant to my situation.  Necessary to use the arrow keys here, but I bet keys other than spacebar will work well for "fire."  Z has already worked - this is a common choice among some PC release shooter games, such as Touhou.

While QB64 won't be my final language for the project and I'm just doing proof of concept stuff right now, this is a hardware issue and I'll need to go searching for more complete info about keyboard jamming so this won't be an issue for people in the final version.

Thanks for your help!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Odd multiple input problem
« Reply #4 on: July 11, 2019, 12:35:55 pm »
Hi johannhowitzer

about
Quote
arrow() just contains the ASCII arrow key data.
look here what it happens to use a string data and convert it into integer with CVI function
Code: QB64: [Select]
  1. CONST left = 1, right = 2, up = 3, down = 4, true = -1
  2. DIM arrow(1 TO 10) AS STRING
  3. arrow(left) = "19200"
  4. arrow(right) = "19712"
  5. arrow(up) = "18432"
  6. arrow(down) = "20480"
  7. COLOR 11, 2
  8. PRINT CVI(arrow(left)), CVI(arrow(right)), CVI(arrow(up)), CVI(arrow(down))
  9. PRINT (arrow(left)), (arrow(right)), (arrow(up)), (arrow(down))
this experience comes out trying to emulate your error with _keydown input
but using an array of integer I have no problem
see here
Code: QB64: [Select]
  1. CONST left = 1, right = 2, up = 3, down = 4, true = -1
  2. DIM arrow(1 TO 10) AS INTEGER
  3. arrow(left) = 19200
  4. arrow(right) = 19712
  5. arrow(up) = 18432
  6. arrow(down) = 20480
  7. COLOR 11, 2
  8.  
  9. PRINT (arrow(left)), (arrow(right)), (arrow(up)), (arrow(down))
  10.     CLS
  11.     throw.x = 0
  12.     LOCATE 3, 1: PRINT "Xmove=";
  13.     IF _KEYDOWN((arrow(left))) = true THEN throw.x = -1: PRINT " Left   "
  14.     IF _KEYDOWN((arrow(right))) = true THEN throw.x = 1: PRINT " Right "
  15.     throw.y = 0
  16.     LOCATE 5, 1: PRINT "Ymove=";
  17.     IF _KEYDOWN((arrow(up))) = true THEN throw.y = -1: PRINT " UP    "
  18.     IF _KEYDOWN((arrow(down))) = true THEN throw.y = 1: PRINT " Down "
  19.     IF throw.x = 0 AND throw.y = 0 THEN throw.x = 1
  20.  
  21.     IF _KEYDOWN(32) = true AND spacepress = false THEN
  22.         spacepress = true
  23.         LOCATE 1, 1: PRINT "Spacepress="; spacepress; "  "
  24.         '     CALL spawn_shot(0, throw.x, throw.y)
  25.     END IF
  26.     IF _KEYDOWN(27) THEN END
  27.     IF _KEYDOWN(32) = false AND spacepress = true THEN spacepress = false
  28.     LOCATE 1, 1: PRINT "Spacepress="; spacepress; "   "
  29.     _LIMIT 10
Programming isn't difficult, only it's  consuming time and coffee

Offline johannhowitzer

  • Forum Regular
  • Posts: 118
    • View Profile
Re: Odd multiple input problem
« Reply #5 on: July 11, 2019, 02:41:50 pm »
Thanks, but I ran your program and it had the same issue as before on my laptop - it's a hardware thing.  It's not something you can code out, as everyone's hardware is different; it's something you have to design your inputs around.  Presumably it's why many PC shooters use Z for fire, perhaps the hardware conflict doesn't exist or isn't as common between arrow keys and Z.

As an aside, the arrow() array doesn't contain the numbers in string format, it contains the following, a throwback to my QBasic days.

Code: QB64: [Select]
  1. dim arrow(4) as string * 2
  2. arrow(up) = chr$(0) + chr$(72)
  3. arrow(right) = chr$(0) + chr$(77)
  4. arrow(down) = chr$(0) + chr$(80)
  5. arrow(left) = chr$(0) + chr$(75)
  6.  

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Odd multiple input problem
« Reply #6 on: July 11, 2019, 03:49:11 pm »
Hi  johannhowitzer

sorry but I don't agree more about hardware issue, I think that it is about  code... (also because when I see some terrific combo used in some games I think of a player of piano and not a gamer)

make this experience with me

please run the original your code with your array initialization...
well with my printing results modification you cannot get these combo keys

1. holding spacebar (32 keycode)  AND
   1.2 holding Left arrow key you cannot see UP arrow  but you can get another combinations of two arrow keys  AND viceversa if you hold together Left+ Up arrow key you cannot get spacebar keydown event
   1.3 holding Right arrow key you cannot see DOWN arrow  but you can get another combinations of two arrow keys AND viceversa if you hold together Right+ Down arrow key you cannot get spacebar keydown event

2. holding 2 arrow  keys
   2.1you cannot detect the third arrow key
(Yes here someone can affirm " But this is illogic, why must someone press and holding 3 arrow keys in the same moment?"
right as logic of programmer, wrong as function that must give back to me if a key is down and not if there is no more 2 key down!)
  2.2 you cannot detect spacebar when you press together Left+Up  or Right+Down...

in fact also using your newer array AS STRING *2  and  initializing as you have posted, I got the same result of you, the third key holded is not always got by I/O functions...
all this happens on a HP notebook 64bit windows 10  and CPU  AMD E 450 APU.

I'll test on another Notebook later
Programming isn't difficult, only it's  consuming time and coffee

FellippeHeitor

  • Guest
Re: Odd multiple input problem
« Reply #7 on: July 11, 2019, 04:40:52 pm »
It’s a hardware issue, TempodiBasic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Odd multiple input problem
« Reply #8 on: July 11, 2019, 05:53:51 pm »
_KEYDOWN is limited by hardware restrictions.  Most USB keyboards will never register any more than 6 keys simultaneously, due to USB specifications/limitations.  (Some might, but require either custom drivers, or multiple virtual drivers, and both options are unreliable.). You’d need a PS/2 N-key Keyboard to read more keys than that.

The best way to handle this type of input is to use _KEYHIT, instead of _KEYDOWN.

Use _KEYDOWN to check modifier keys (such as Shift-Ctrl-Alt with work with normal key presses), and _KEYHIT to handle normal keyboard input.

A nice write up on N-key keyboards, rollover, and USB limitations can be found here: http://blog.controlspace.org/2010/08/n-key-rollover-what-it-is-and-how-to.html
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline johannhowitzer

  • Forum Regular
  • Posts: 118
    • View Profile
Re: Odd multiple input problem
« Reply #9 on: July 11, 2019, 06:41:22 pm »
How does _KEYHIT function with holding keys down, though?  This game will involve holding down the arrow keys a lot for movement, and holding other keys as well for certain auxiliary functions.  All of this is moot at the end of the day for my purposes, of course, since I'll be moving to Unity for this project soon.  I appreciate the help, I've learned some important things here.

FellippeHeitor

  • Guest
Re: Odd multiple input problem
« Reply #10 on: July 11, 2019, 07:19:38 pm »
KEYHIT returns a positive key code at key down, a negative key code at key up.

Wouldn’t likely help in the current case as the third key in the faulty combo won’t register in your hardware anyway.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: Odd multiple input problem
« Reply #11 on: July 11, 2019, 09:42:33 pm »
Well, I don't know the PEEK state of the spacebar key, but I do know the value to detect Shift, Ctrl, and Alt; so, if you don't mid exchanging a Shift key for the spacebar, you could get a triple key detection with Windows API + a PEEK routine.

Code: QB64: [Select]
  1. CONST VK_LEFT = &H25
  2. CONST VK_UP = &H26
  3. CONST VK_SPACE = &H20
  4.  
  5.     FUNCTION GetAsyncKeyState% (BYVAL vkey%)
  6.     DEF SEG = 0
  7.     x = PEEK(&H417) MOD 16
  8.     DEF SEG
  9.  
  10.     _LIMIT 30
  11.     a%(0) = GetAsyncKeyState%(VK_LEFT)
  12.     a%(1) = GetAsyncKeyState%(VK_UP)
  13.     a%(2) = GetAsyncKeyState%(VK_SHIFT)
  14.     IF a%(0) AND a%(1) THEN
  15.         PRINT a%(0), a%(1), a%(2), x
  16.         IF a%(0) AND a%(1) AND x >= 1 AND x <= 3 THEN
  17.             PRINT "Arrow Left and Arrow Up and a Shift Key are all engaged!"
  18.         END IF
  19.     END IF
  20.  

Now if you read the 4 columns of values, you will notice the API cannot detect more than 2 keys down, which means the way I set up the code, it fails to detect the Shift key when the arrow up and left keys are depressed. Well, fortunately, the PEEK statement can detect a Shift key press, even when the arrow up and left keys are depressed; hence, a triple key routine is possible with Shift, and maybe with spacebar, if anyone can remember the PEEK DEF/SEG routine necessary to detect a space bar press.

Pete
Want to learn how to write code on cave walls? https://www.tapatalk.com/groups/qbasic/qbasic-f1/

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Odd multiple input problem
« Reply #12 on: July 12, 2019, 08:52:13 am »
Hi
this is the results on another notebook
  [ You are not allowed to view this attachment ]  
yes on this program catch all _keydown in the same time!

and on the same TOSHIBA if I use an USB external Keyboard I have some other strange results!!


yes I must admit that it is an Hardware issue, no issue of language.
(@Fellippe Thanks for tips)
So both if I write something in C++ both in QB64 both in Python or whatdoyouwanttouse the results are the same depending on the hardware!!!
Programming isn't difficult, only it's  consuming time and coffee

Offline johannhowitzer

  • Forum Regular
  • Posts: 118
    • View Profile
Re: Odd multiple input problem
« Reply #13 on: July 12, 2019, 01:14:45 pm »
You've reminded me that I need to be careful of left+right or up+down inputs, thanks.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Odd multiple input problem
« Reply #14 on: July 13, 2019, 11:16:16 am »
Mhmmmm... _KEYDOWN is hardware sensible,
Steve and Fellippe suggest to use _KEYHIT knowing that if key is released _KEYHIT returns a negative value...

Mumble Mumble.... it let me imagine...

this is a first result of a my attempt to write a workaround with _keyhit at the place of _keydown

for now as you can see from image I can get to see 5 key pressed together and holding them...
  [ You are not allowed to view this attachment ]  
but I'm fighting with _KEYCLEAR, it is the first time that I use it.

Stay  cartooned / tuned
Programming isn't difficult, only it's  consuming time and coffee