Author Topic: Direct vs Undirect _KEYHIT  (Read 2356 times)

0 Members and 1 Guest are viewing this topic.

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Direct vs Undirect _KEYHIT
« on: May 13, 2019, 07:36:19 pm »
Hi Guys
here another my boring experience...

for those that have the energy to follow me please
CPR the two following codes...

code 1
Code: QB64: [Select]
  1. CONST BN = 78, Ln = 110, Sp = 32 'BigN  LittleN
  2. _TITLE "Direct _Keyhit"
  3.     LOCATE 1, 1: PRINT _KEYHIT; "     ";
  4.     IF _KEYHIT = BN THEN PRINT "N"
  5.     IF _KEYHIT = Ln THEN PRINT "n"
  6.  

code 2
Code: QB64: [Select]
  1. CONST BN = 78, Ln = 110, Sp = 32 'BigN  LittleN
  2. _TITLE "Undirect _Keyhit"
  3.     k = _KEYHIT
  4.     LOCATE 1, 1: PRINT k; "     ";
  5.     IF k = BN THEN PRINT "N"
  6.     IF k = Ln THEN PRINT "n"
  7. LOOP UNTIL k = Sp

I have hade this experience...
1. direct use of _keyhit can loose some keystrokes...
please try to run code1 and on running please press N after capslock or with SHIFT modifier and then n without capslock or with capslock plus SHIFT... in the best experience I got some N and n but keycode is always 0, never 32 or 78 or 110 or other number!

2. undirect use of _keyhit (using a variable to store the result of _KEYHIT) is more accurate but always I got 0 as result of the statement PRINT k.

3. if I run together the two programs...for example I load before Undirect keyhit and then Direct Keyhit. After getting an N or n output on the screen of the two applications, if I have focus on Direct Keyhit  well hitting CapsLock it passes a Keyhit message to the other application Undirect Keyhit that works following its inner code. Moreover the second keystroke on CapsLock is passed to Direct Keyhit that has already the focus and it works following its inner code.

Thanks to read and for feedbacks
Programming isn't difficult, only it's  consuming time and coffee

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Direct vs Undirect _KEYHIT
« Reply #1 on: May 13, 2019, 08:27:15 pm »
_KEYHIT is a function that returns a LONG integer:
Code: QB64: [Select]
  1. CONST BN = 78, Ln = 110, Sp = 32 'BigN  LittleN
  2. _TITLE "Direct _Keyhit"
  3.     K& = _KEYHIT
  4.     IF K& = BN THEN PRINT "N";
  5.     IF K& = Ln THEN PRINT "n";
  6.     _DISPLAY
  7.     _LIMIT 100
  8. LOOP UNTIL K& = Sp
  9.  

1. You are polling _KEYHIT too many times in one loop in first code snippett
2. Most of the time _KEYHIT will be 0 because loops occur many many times per second.
« Last Edit: May 13, 2019, 08:37:44 pm by bplus »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Direct vs Undirect _KEYHIT
« Reply #2 on: May 13, 2019, 08:40:01 pm »
Just like INKEY$ has an input buffer, _KEYHIT does as well. 

DO
    LOCATE 1,1
    PRINT INKEY$
    PRINT INKEY$
    PRINT INKEY$
    PRINT INKEY$
    PRINT INKEY$
LOOP UNTIL INKEY$ <> “”

Run the above, press the ASDF keys in order.  Chances are, they’ll be read in the first INKEY$ statement and never in the 2nd to 5th.  Your loop is processing the keys as fast as you’re hitting them, keeping the buffer clear.

Now, add a _DELAY 5 after the DO and run it.   You’ll have time to put all 4 key presses into the buffer, and they’ll be cleared in a single pass with the multiple INKEY$ statements.

Press a key, it goes onto the buffer.  Try this:

_DELAY 5
FOR I = 1 TO 10
    PRINT INKEY$
NEXT

While the delay is active, press all sorts of keys — they all go onto the INKEY$ buffer.  Quit hitting the keys before the 5 second delay is finished, and watch the FOR loop print your first 10 key presses, as it clears them from the buffer.



So, how’s this relate to what’s going on in your code??

Let’s run the program and hit the ASDF keys in order, and put them into the KEYHIT buffer...

When you get to the PRINT _KEYHIT, it’ll take the “A” off the buffer and print 65.

The “IF _KEYHIT = BN” will then pull the “S” from the buffer...

The “IF _KEYHIT = Ln” then pulls the “D” from the buffer...

*EACH* time INKEY$ is called, it pulls from the INKEY$ buffer, and *EACH* time _KEYHIT is called, it pulls from the _KEYHIT buffer...

So, if you only hit one key every loop cycle, it’d enter the buffer and get cleared with the PRINT _KEYHIT statement, clearing the buffer so the 2 IF statements will *always* be false.  The only way you’d print “N” is if the 2nd character in the buffer = BN, and the only way you’ll print “n” is if the 3rd character in the buffer = 110...

To make it work correctly, read one character from the buffer at a time and process it a character at a time, as you are in your “code 2”.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline TempodiBasic

  • Forum Resident
  • Posts: 1792
    • View Profile
Re: Direct vs Undirect _KEYHIT
« Reply #3 on: May 14, 2019, 07:05:11 am »
Hi Bplus Hi Steve

Thanks for your answers
you together confirm to me that there is so much power under QB64 and I must prepare myself to pay attention to this feature when I'm coding.

I'm driving a Ferrari  https://auto.ferrari.com/it_IT/and not a 500 https://www.google.it/search?client=opera&hs=LdD&biw=1326&bih=627&tbm=isch&sa=1&ei=PKDaXM2iOtHCwQKYhZnoAQ&q=500+fiat+vecchia&oq=500+fiat&gs_l=img.1.1.0l10.18880.23067..25451...0.0..0.75.549.8......1....1..gws-wiz-img.......0i67.7XH4QPOc4Ks#imgrc=186cqf9DNruDnM:

:-) Well

I remark if can be useful the point 3. about focus and keystroke in my Toshiba with Windows 10.
It is ok for MacOs and Linux?
Programming isn't difficult, only it's  consuming time and coffee