Author Topic: detecting keypresses question - _KEYDOWN and _BUTTON both miss certain keys  (Read 5887 times)

0 Members and 1 Guest are viewing this topic.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
I'm playing with _KEYDOWN and _DEVICEINPUT(1) _BUTTON, to see how they work for detecting multiple keypresses for games, and have some questions.

Both methods work but they both don't detect certain keys (test code below).

_KEYDOWN
Using _KEYDOWN I am seeing values that match the "KEYHIT and KEYDOWN Codes" listed at
https://www.qb64.org/wiki/Keyboard_scancodes#KEYHIT_and_KEYDOWN_Codes

However it not seem to detect:
  • F11
  • F12
  • SysReq (Print Screen)
  • ScrL (Scroll Lock)
  • Pause / Break
  • NumLock
  • KEYPAD 5
  • Caps Lock
  • Left Shift
  • Shift
  • Right Shift
  • Left Ctrl
  • Ctrl
  • Left Win
  • Left Alt
  • Alt
  • Right Alt
  • Right Win
  • Menu
  • Right Ctrl
  • Mouse Left
  • Mouse Middle
  • Mouse Right
  • KEYPAD ENTER returns same code as regular ENTER key (13)
  • KEYPAD "-"   returns same code as regular "-" key (45)
  • KEYPAD "/"   returns same code as regular enter key (47)
_DEVICES(1) _BUTTON
Using _DEVICES(1) _BUTTON detects most of the above keys, however it doesn't seem to detect the following:
  • F10
  • Alt
  • Left Alt
  • Right Alt
  • Print Screen
  • Pause/Break
Also, I don't see where the keyboard codes are documented for _BUTTON.

Why are certain keys not detected?
Any advice on using these methods?

I'd appreciate any help I can get...

Code: QB64: [Select]
  1. ' #############################################################################
  2. ' Keyboard detection test
  3. ' #############################################################################
  4.  
  5. ' =============================================================================
  6. ' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
  7.  
  8. ' boolean constants
  9. CONST FALSE = 0
  10. CONST TRUE = NOT FALSE
  11.  
  12. ' =============================================================================
  13. ' GLOBAL VARIABLES
  14. DIM ProgramPath$
  15. DIM ProgramName$
  16.  
  17. ' =============================================================================
  18. ' INITIALIZE
  19. ProgramName$ = MID$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\") + 1)
  20. ProgramPath$ = LEFT$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\"))
  21.  
  22. ' =============================================================================
  23. ' RUN TEST
  24. main ProgramName$
  25.  
  26. ' =============================================================================
  27. ' FINISH
  28. SYSTEM ' return control to the operating system
  29. PRINT ProgramName$ + " finished."
  30.  
  31.  
  32. ' /////////////////////////////////////////////////////////////////////////////
  33.  
  34. SUB main (ProgName$)
  35.     DIM in$: in$ = ""
  36.     DO
  37.         CLS
  38.         PRINT ProgName$
  39.         PRINT
  40.         PRINT "Test of different methods of detecting keypresses"
  41.         PRINT
  42.         PRINT "1. Test using _KEYDOWN"
  43.         PRINT
  44.         PRINT "2. Test using _DEVICE commands"
  45.         PRINT
  46.         PRINT "3. Enumerate _DEVICES"
  47.         PRINT
  48.         PRINT "What to do ('q' to exit)"
  49.  
  50.         INPUT in$: in$ = LCASE$(LEFT$(in$, 1))
  51.         IF in$ = "1" THEN
  52.             KeyboardKeydownTest
  53.         ELSEIF in$ = "2" THEN
  54.             KeyboardDeviceTest
  55.         ELSEIF in$ = "3" THEN
  56.             EnumerateDevices
  57.         END IF
  58.     LOOP UNTIL in$ = "q"
  59. END SUB ' main
  60.  
  61. ' /////////////////////////////////////////////////////////////////////////////
  62. ' MOSTLY WORKS TO RETURN KEYHIT and KEYDOWN Codes listed at
  63. ' https://www.qb64.org/wiki/Keyboard_scancodes#KEYHIT_and_KEYDOWN_Codes
  64.  
  65. ' However does not seem to detect:
  66. ' F11
  67. ' F12
  68. ' SysReq (Print Screen)
  69. ' ScrL (Scroll Lock)
  70. ' Pause / Break
  71. ' NumLock
  72. ' KEYPAD 5
  73. ' Caps Lock
  74. ' Left Shift
  75. ' Shift
  76. ' Right Shift
  77. ' Left Ctrl
  78. ' Ctrl
  79. ' Left Win
  80. ' Left Alt
  81. ' Alt
  82. ' Right Alt
  83. ' Right Win
  84. ' Menu
  85. ' Right Ctrl
  86. ' Mouse Left
  87. ' Mouse Middle
  88. ' Mouse Right
  89. ' KEYPAD ENTER returns same code as regular ENTER key (13)
  90. ' KEYPAD "-"   returns same code as regular "-" key (45)
  91. ' KEYPAD "/"   returns same code as regular enter key (47)
  92.  
  93. SUB KeyboardKeydownTest
  94.     DIM iLoop AS INTEGER
  95.     DIM iLastPressed AS INTEGER
  96.  
  97.     CLS
  98.     PRINT "Press a key to see what _KEYDOWN code is detetected."
  99.     PRINT
  100.     PRINT
  101.     PRINT
  102.     PRINT "(Press <ESC> to exit)."
  103.  
  104.     _KEYCLEAR: _DELAY 1
  105.     iLastPressed = -1
  106.     DO
  107.         FOR iLoop = 1 TO 32767
  108.             iCode = _KEYDOWN(iLoop)
  109.  
  110.             ' If the last key pressed is still held down, don't keep printing the code
  111.             IF (iLoop <> iLastPressed) THEN
  112.                 'IF _KEYDOWN(iLoop) THEN
  113.                 IF iCode = TRUE THEN
  114.                     CLS
  115.                     PRINT "Press a key to see what _KEYDOWN code is detetected."
  116.                     PRINT
  117.                     PRINT "Detected key press with _KEYDOWN(" + STR$(iLoop) + ") = " + STR$(iCode)
  118.                     PRINT
  119.                     PRINT "(Press <ESC> to exit)."
  120.                     iLastPressed = iLoop
  121.                 END IF
  122.             ELSE
  123.                 ' If last key is released, clear the code so it can be pressed again:
  124.                 IF iCode = FALSE THEN
  125.                     iLastPressed = -1
  126.                 END IF
  127.             END IF
  128.         NEXT iLoop
  129.  
  130.         '_LIMIT 100
  131.     LOOP UNTIL _KEYDOWN(27)
  132.     _KEYCLEAR
  133. END SUB ' KeyboardKeydownTest
  134.  
  135. ' /////////////////////////////////////////////////////////////////////////////
  136. 'DEVICES Button
  137. '_LASTBUTTON(1) keyboards will normally return 512 buttons. One button is read per loop through all numbers.
  138. '_BUTTONCHANGE(number) returns -1 when pressed, 1 when released and 0 when there is no event since the last read.
  139. '_BUTTON(number) returns -1 when a button is pressed and 0 when released
  140.  
  141. ' Detects most keys (where the codes are documented?)
  142. ' However, does not seem to detect:
  143. ' F10
  144. ' Alt
  145. ' Left Alt
  146. ' Right Alt
  147. ' Print Screen
  148. ' Pause/Break
  149.  
  150. SUB KeyboardDeviceTest
  151.     DIM iLoop AS INTEGER
  152.     DIM iCode AS INTEGER
  153.     DIM iLastPressed AS INTEGER
  154.  
  155.     CLS
  156.     PRINT "Press a key to see what _BUTTON code is detetected."
  157.     PRINT
  158.     PRINT
  159.     PRINT
  160.     PRINT "(Press <ESC> to exit)."
  161.  
  162.     _KEYCLEAR: _DELAY 1
  163.     iLastPressed = -1
  164.     DO
  165.         WHILE _DEVICEINPUT(1): WEND ' clear and update the keyboard buffer
  166.  
  167.         ' Detect changed key state
  168.         FOR iLoop = 1 TO 512
  169.             iCode = _BUTTON(iLoop)
  170.  
  171.             ' If the last key pressed is still held down, don't keep printing the code
  172.             IF (iLoop <> iLastPressed) THEN
  173.                 IF iCode <> 0 THEN
  174.                     CLS
  175.                     PRINT "Press a key to see what _BUTTON code is detetected."
  176.                     PRINT
  177.                     PRINT "Detected key press with _BUTTON(" + STR$(iLoop) + ") = " + STR$(iCode)
  178.                     PRINT
  179.                     PRINT "(Press <ESC> to exit)."
  180.                     iLastPressed = iLoop
  181.                 END IF
  182.             ELSE
  183.                 ' If last key is released, clear the code so it can be pressed again:
  184.                 IF iCode = 0 THEN
  185.                     iLastPressed = -1
  186.                 END IF
  187.             END IF
  188.         NEXT iLoop
  189.  
  190.         '_LIMIT 100
  191.     LOOP UNTIL _KEYDOWN(27)
  192.     _KEYCLEAR
  193. END SUB ' KeyboardDeviceTest
  194.  
  195. ' /////////////////////////////////////////////////////////////////////////////
  196.  
  197. SUB WaitForKey (prompt$, KeyCode&, DelaySeconds%)
  198.     ' SHOW PROMPT (IF SPECIFIED)
  199.     IF LEN(prompt$) > 0 THEN
  200.         IF RIGHT$(prompt$, 1) <> ";" THEN
  201.             PRINT prompt$
  202.         ELSE
  203.             PRINT RIGHT$(prompt$, LEN(prompt$) - 1);
  204.         END IF
  205.     END IF
  206.  
  207.     ' WAIT FOR KEY
  208.     DO: LOOP UNTIL _KEYDOWN(KeyCode&) ' leave loop when specified key pressed
  209.  
  210.     ' PAUSE AFTER (IF SPECIFIED)
  211.     IF DelaySeconds% < 1 THEN
  212.         _KEYCLEAR: '_DELAY 1
  213.     ELSE
  214.         _KEYCLEAR: _DELAY DelaySeconds%
  215.     END IF
  216. END SUB ' WaitForKey
  217.  
  218.  
  219. ' /////////////////////////////////////////////////////////////////////////////
  220. ' Example: Checking for the system's input devices.
  221.  
  222. ' _DEVICES FUNCTION (QB64 REFERENCE)
  223. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/wiki/index_title_DEVICES/
  224. '
  225. ' The _DEVICES function returns the number of INPUT devices on your computer
  226. ' including keyboard, mouse and game devices.
  227. '
  228. ' Syntax:
  229. '
  230. ' device_count% = _DEVICES
  231. '
  232. ' Returns the number of devices that can be listed separately with the _DEVICE$
  233. ' function by the device number.
  234. ' Devices include keyboard, mouse, joysticks, game pads and multiple stick game
  235. ' controllers.
  236. ' Note: This function MUST be read before trying to use the _DEVICE$,
  237. ' _DEVICEINPUT or _LAST control functions!
  238.  
  239. ' Note: The STRIG/STICK commands won't read from the keyboard
  240. '       or mouse device the above example lists.
  241.  
  242. SUB EnumerateDevices
  243.     DIM devices%
  244.     DIM iLoop%
  245.     DIM sCount$
  246.     DIM iLen AS INTEGER
  247.  
  248.     devices% = _DEVICES ' MUST be read in order for other 2 device functions to work!
  249.  
  250.     CLS
  251.     PRINT "Total devices found: "; STR$(devices%)
  252.     FOR iLoop% = 1 TO devices%
  253.         iLen = 4
  254.         sCount$ = LEFT$(LTRIM$(RTRIM$(STR$(iLoop%))) + STRING$(iLen, " "), iLen)
  255.         PRINT sCount$ + _DEVICE$(iLoop%) + " (" + LTRIM$(RTRIM$(STR$(_LASTBUTTON(iLoop%)))) + " buttons)"
  256.     NEXT iLoop%
  257.     PRINT
  258.     PRINT "PRESS <ESC> TO CONTINUE"
  259.     DO: LOOP UNTIL _KEYDOWN(27) ' leave loop when ESC key pressed
  260.     _KEYCLEAR: '_DELAY 1
  261.  
  262. END SUB ' EnumerateDevices
  263.  


Results:
Code: [Select]

Key                     _BUTTON       _KEYDOWN   
---------------------   -----------   --------
Esc                     2             27         
F1                      60            15104       
F2                      61            15360       
F3                      62            15616       
F4                      63            15872       
F5                      64            16128       
F6                      65            16384       
F7                      66            16640       
F8                      67            16896       
F9                      68            17152       
F10                     ?             17408       
F11                     88            ?           
F12                     89            ?           
SysReq (Print Screen)   ?             ?           
ScrL (Scroll Lock)      71            ?           
Pause / Break           ?             ?           
~                       42            96         
1!                      3             49         
2@                      4             50         
3#                      5             51         
4$                      6             52         
0.05                    7             53         
6^                      8             54         
7&                      9             55         
8*                      10            56         
9(                      11            57         
0)                      12            48         
-_                      13            45         
=+                      14            61         
BkSp                    15            8           
Ins                     339           20992       
Home                    328           18176       
PgUp                    330           18688       
Del                     340           21248       
End                     336           20224       
PgDn                    338           20736       
NumLock                 326           ?           
KEYPAD /                310           (47)       
KEYPAD *                56            (42)       
KEYPAD -                75            (45)       
KEYPAD 7/Home           72            18176       
KEYPAD 8 Up             73            18432       
KEYPAD 9 PgUp           74            18688       
KEYPAD +                79            (43)       
KEYPAD 4 Left           76            19200       
KEYPAD 5                77            ?           
KEYPAD 6 Right          78            19712       
KEYPAD 1 End            80            20224       
KEYPAD 2 Down           81            20480       
KEYPAD 3 PgDn           82            20736       
KEYPAD ENTER            285           (13)       
KEYPAD 0 Ins            83            20992       
KEYPAD . Del            84            21248       
Tab                     16            9           
Q                       17            113         
W                       18            119         
E                       19            101         
R                       20            114         
T                       21            116         
Y                       22            121         
U                       23            117         
I                       24            105         
O                       25            111         
P                       26            112         
[{                      27            91         
]}                      28            93         
\|                      44            92         
Caps Lock               59            ?           
A                       31            97         
S                       32            115         
D                       33            100         
F                       34            102         
G                       35            103         
H                       36            104         
J                       37            106         
K                       38            107         
L                       39            108         
;:                      40            59         
'"                      41            39         
Enter                   29            13         
Left Shift              43            ?           
Shift                   (44 or 55)    ?           
Z                       45            22         
X                       46            120         
C                       47            99         
V                       48            118         
B                       49            98         
N                       50            110         
M                       51            109         
,<                      52            44         
.>                      53            46         
/?                      54            47         
Right Shift             55            ?           
Up                      329           18432       
Left                    332           19200       
Down                    337           20480       
Right                   334           19712       
Left Ctrl               30            ?           
Ctrl                    (30 or 286)   ?           
Left Win                348           ?           
Left Alt                ?             ?           
Alt                     ?             ?           
Spacebar                58            32         
Right Alt               ?             ?           
Right Win               349           ?           
Menu                    350           ?           
Right Ctrl              286           ?           

« Last Edit: December 15, 2020, 03:41:25 pm by madscijr »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
I’ll let Fellippe answer this one for you.  If I say anything, I’ll get fussed at for “degrading QB64’s reputation” by telling the truth.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Ha! I WAS going to suggest checking in with Steve on this, he's made a study of keys and how to fix them up.

@madscijr If you have vital keys you need to get working, Steve probably already has answer in code he's worked.
If he doesn't have links at the ready you can try searches of this forum. You would have to accept a reassignment of key number codes to get it all, or more of them anyway.

If you are just playing around, I'd say stick with what's available with normal QB64 functions.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
@madscijr If you have vital keys you need to get working, Steve probably already has answer in code he's worked.
If he doesn't have links at the ready you can try searches of this forum. You would have to accept a reassignment of key number codes to get it all, or more of them anyway.

If you are just playing around, I'd say stick with what's available with normal QB64 functions.

As long as you’re a windows user, my stuff will work for you: https://www.qb64.org/forum/index.php?topic=3290.msg125740#msg125740

https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Thanks for your replies...

@madscijr If you have vital keys you need to get working, Steve probably already has answer in code he's worked.
If he doesn't have links at the ready you can try searches of this forum. You would have to accept a reassignment of key number codes to get it all, or more of them anyway.
If you are just playing around, I'd say stick with what's available with normal QB64 functions.

I'm relatively new to QB64, I just want to make some games, some of which might utilize almost every key on the keyboard.
I can get by without EVERY key, and the _BUTTON method seems to detect almost everything.
It is just so strange that it doesn't work with F10 and right/left ALT, yet it picks up stuff like right/left Windows, caps lock, and the menu key! (I don't think I've ever used that key in my life, but I might now!)

My only question would be, is there any reason NOT to read the keyboard with _DEVICES _BUTTON?

As long as you’re a windows user, my stuff will work for you: https://www.qb64.org/forum/index.php?topic=3290.msg125740#msg125740

Thanks... I'll give that a look! From your first answer it sounds like I've touched on an old pain point! lol

FellippeHeitor

  • Guest
Try _KEYHIT too.

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Try _KEYHIT too.

I just gave it a try - it can sort of detect some of the keys that _KEYDOWN can't detect, although there is weirdness like you guys were discussing, where the key press code is negative, and the key release code is a totally different number. In some cases the release code is not distinguishable (left & right shift both -16, left & right ctrl both -17, etc.) and it seems to really get confused with keys like caps lock & num lock. For instance while caps lock is held down, the code alternates between 30771 and -30771, then after caps lock is released & turned off -20. Strange.

Also the numeric keypad's values (when num lock is off) are indistinguishable from the regular keys - ie the arrow keys are the same codes as the regular arrow keys. Not helpful if you want to detect the keypad's arrows as separate input.

The only thing _KEYHIT looks like it buys you is if you don't know what key you're looking for, or you don't want to loop through codes, it pushes the value to you.

But with _BUTTON you only have to cycle through 512 codes to see everything.
I think with _KEYDOWN the biggest code value I saw was 21248 (my test prog loops upto 32767) which could be more taxing if you had to loop through those values every time.
But with both of _BUTTON and _KEYDOWN, as long as you know what keys to test for, you don't have to loop at all, just look for those specific values.

Anyhow below is the updated keyboard test code with _KEYHIT added, and below that are the resulting keycodes I detected with _KEYDOWN, _BUTTON, _KEYHIT methods.

I probably don't need a custom library (though I might for reading separate input from multiple mice with the raw input API, if I can figure that out!) - I would like to keep things as "vanilla" as possible, and more easily ported to Linux & Mac. But we'll see how that goes down the road...
Code: QB64: [Select]
  1. ' ################################################################################################################################################################
  2. ' qb64_keypress_detection_test_v7.bas
  3. ' ################################################################################################################################################################
  4.  
  5. ' A little script to show which keycodes are detected for the different keys
  6. ' on the keyboard using 3 different methods (_KEYDOWN, _KEYHIT, _BUTTON).
  7. ' While none of them seems to be able to detect every key, _BUTTON catches
  8. ' most of them (except for F10 and right/left ALT). So I will use _BUTTON
  9. ' to catch most of the codes, and _KEYDOWN to detect F10, and _KEYHIT for ALT.
  10.  
  11. ' Here are the results for each method, compiled here in a handy table for you:
  12.  
  13. ' Key                     _BUTTON       _KEYDOWN       _KEYHIT                                              
  14. ' ---------------------   -----------   --------       -----------------------------------------------------
  15. ' Esc                     2             27             27                                                  
  16. ' F1                      60            15104          15104                                                
  17. ' F2                      61            15360          15360                                                
  18. ' F3                      62            15616          15616                                                
  19. ' F4                      63            15872          15872                                                
  20. ' F5                      64            16128          16128                                                
  21. ' F6                      65            16384          16384                                                
  22. ' F7                      66            16640          16640                                                
  23. ' F8                      67            16896          16896                                                
  24. ' F9                      68            17152          17152                                                
  25. ' F10                     ?             17408          17408                                                
  26. ' F11                     88            ?              -31488                                              
  27. ' F12                     89            ?              -31232                                              
  28. ' SysReq (Print Screen)   ?             ?              (-44 on press/release, seems to slow down PC)        
  29. ' ScrL (Scroll Lock)      71            ?              (-145 on press/release, seems to slow down PC)      
  30. ' Pause / Break           ?             ?              (31053 momentarily on pressing another key)          
  31. ' ~                       42            96             96                                                  
  32. ' 1!                      3             49             49                                                  
  33. ' 2@                      4             50             50                                                  
  34. ' 3#                      5             51             51                                                  
  35. ' 4$                      6             52             52                                                  
  36. ' 0.05                    7             53             53                                                  
  37. ' 6^                      8             54             54                                                  
  38. ' 7&                      9             55             55                                                  
  39. ' 8*                      10            56             56                                                  
  40. ' 9(                      11            57             57                                                  
  41. ' 0)                      12            48             48                                                  
  42. ' -_                      13            45             45                                                  
  43. ' =+                      14            61             61                                                  
  44. ' BkSp                    15            8              8                                                    
  45. ' Ins                     339           20992          20992                                                
  46. ' Home                    328           18176          18176                                                
  47. ' PgUp                    330           18688          18688                                                
  48. ' Del                     340           21248          21248                                                
  49. ' End                     336           20224          20224                                                
  50. ' PgDn                    338           20736          20736                                                
  51. ' NumLock                 326           ?              30772 (flip flops with -30772 on release, -144 after)
  52. ' KEYPAD /                310           (47)           47                                                  
  53. ' KEYPAD *                56            (42)           42                                                  
  54. ' KEYPAD -                75            (45)           45                                                  
  55. ' KEYPAD 7/Home           72            18176          18176                                                
  56. ' KEYPAD 8 Up             73            18432          18432                                                
  57. ' KEYPAD 9 PgUp           74            18688          18688                                                
  58. ' KEYPAD +                79            (43)           43                                                  
  59. ' KEYPAD 4 Left           76            19200          19200                                                
  60. ' KEYPAD 5                77            ?              ? (-12 after release)                                
  61. ' KEYPAD 6 Right          78            19712          19712                                                
  62. ' KEYPAD 1 End            80            20224          20224                                                
  63. ' KEYPAD 2 Down           81            20480          20480                                                
  64. ' KEYPAD 3 PgDn           82            20736          20736                                                
  65. ' KEYPAD ENTER            285           (13)           13                                                  
  66. ' KEYPAD 0 Ins            83            20992          20992                                                
  67. ' KEYPAD . Del            84            21248          21248                                                
  68. ' Tab                     16            9              9                                                    
  69. ' Q                       17            113            113                                                  
  70. ' W                       18            119            119                                                  
  71. ' E                       19            101            101                                                  
  72. ' R                       20            114            114                                                  
  73. ' T                       21            116            116                                                  
  74. ' Y                       22            121            121                                                  
  75. ' U                       23            117            117                                                  
  76. ' I                       24            105            105                                                  
  77. ' O                       25            111            111                                                  
  78. ' P                       26            112            112                                                  
  79. ' [{                      27            91             91                                                  
  80. ' ]}                      28            93             93                                                  
  81. ' \|                      44            92             92                                                  
  82. ' Caps Lock               59            ?              30771 (flip flops with -30771 on release, -20 after)
  83. ' A                       31            97             97                                                  
  84. ' S                       32            115            115                                                  
  85. ' D                       33            100            100                                                  
  86. ' F                       34            102            102                                                  
  87. ' G                       35            103            103                                                  
  88. ' H                       36            104            104                                                  
  89. ' J                       37            106            106                                                  
  90. ' K                       38            107            107                                                  
  91. ' L                       39            108            108                                                  
  92. ' ;:                      40            59             59                                                  
  93. ' '"                      41            39             39                                                  
  94. ' Enter                   29            13             13                                                  
  95. ' Left Shift              43            ?              -30768 (-16 on release)                              
  96. ' Shift                   (44 or 55)    ?              (-30768 or -30769)                                  
  97. ' Z                       45            22             22                                                  
  98. ' X                       46            120            120                                                  
  99. ' C                       47            99             99                                                  
  100. ' V                       48            118            118                                                  
  101. ' B                       49            98             98                                                  
  102. ' N                       50            110            110                                                  
  103. ' M                       51            109            109                                                  
  104. ' ,<                      52            44             44                                                  
  105. ' .>                      53            46             46                                                  
  106. ' /?                      54            47             47                                                  
  107. ' Right Shift             55            ?              -30769 (-16 on release)                              
  108. ' Up                      329           18432          18432                                                
  109. ' Left                    332           19200          19200                                                
  110. ' Down                    337           20480          20480                                                
  111. ' Right                   334           19712          19712                                                
  112. ' Left Ctrl               30            ?              -30766 (-17 on release)                              
  113. ' Ctrl                    (30 or 286)   ?              (-30766 or -30767)                                  
  114. ' Left Win                348           ?              ? (-91 after release)                                
  115. ' Left Alt                ?             ?              -30764 (-18 on release)                              
  116. ' Alt                     ?             ?              (-30764 or -30765)                                  
  117. ' Spacebar                58            32             32                                                  
  118. ' Right Alt               ?             ?              -30765 (-18 on release)                              
  119. ' Right Win               349           ?              ? (-92 after release)                                
  120. ' Menu                    350           ?              ? (-93 after release)                                
  121. ' Right Ctrl              286           ?              -30767 (-17 on release)                              
  122.  
  123. ' =============================================================================
  124. ' GLOBAL DECLARATIONS a$=string, i%=integer, L&=long, s!=single, d#=double
  125.  
  126. ' boolean constants
  127. CONST FALSE = 0
  128. CONST TRUE = NOT FALSE
  129.  
  130. ' =============================================================================
  131. ' GLOBAL VARIABLES
  132. DIM ProgramPath$
  133. DIM ProgramName$
  134.  
  135. ' =============================================================================
  136. ' INITIALIZE
  137. ProgramName$ = MID$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\") + 1)
  138. ProgramPath$ = LEFT$(COMMAND$(0), _INSTRREV(COMMAND$(0), "\"))
  139.  
  140. ' =============================================================================
  141. ' RUN TEST
  142. main ProgramName$
  143.  
  144. ' =============================================================================
  145. ' FINISH
  146. SYSTEM ' return control to the operating system
  147. PRINT ProgramName$ + " finished."
  148.  
  149. ' /////////////////////////////////////////////////////////////////////////////
  150.  
  151. SUB main (ProgName$)
  152.     DIM in$: in$ = ""
  153.     DO
  154.         CLS
  155.         PRINT ProgName$
  156.         PRINT
  157.         PRINT "Test of different methods of detecting keypresses"
  158.         PRINT
  159.         PRINT "1. Test using _KEYDOWN"
  160.         PRINT
  161.         PRINT "2. Test using _KEYHIT"
  162.         PRINT
  163.         PRINT "3. Test using _DEVICE commands"
  164.         PRINT
  165.         PRINT "4. Enumerate _DEVICES"
  166.         PRINT
  167.         PRINT "What to do ('q' to exit)"
  168.  
  169.         INPUT in$: in$ = LCASE$(LEFT$(in$, 1))
  170.         IF in$ = "1" THEN
  171.             KeyboardKeydownTest
  172.         ELSEIF in$ = "2" THEN
  173.             KeyboardKeyhitTest
  174.         ELSEIF in$ = "3" THEN
  175.             KeyboardDeviceTest
  176.         ELSEIF in$ = "4" THEN
  177.             EnumerateDevices
  178.         END IF
  179.     LOOP UNTIL in$ = "q"
  180. END SUB ' main
  181.  
  182. ' /////////////////////////////////////////////////////////////////////////////
  183. ' MOSTLY WORKS TO RETURN KEYHIT and KEYDOWN Codes listed at
  184. ' https://www.qb64.org/wiki/Keyboard_scancodes#KEYHIT_and_KEYDOWN_Codes
  185.  
  186. ' However does not seem to detect:
  187. ' F11
  188. ' F12
  189. ' SysReq (Print Screen)
  190. ' ScrL (Scroll Lock)
  191. ' Pause / Break
  192. ' NumLock
  193. ' KEYPAD 5
  194. ' Caps Lock
  195. ' Left Shift
  196. ' Shift
  197. ' Right Shift
  198. ' Left Ctrl
  199. ' Ctrl
  200. ' Left Win
  201. ' Left Alt
  202. ' Alt
  203. ' Right Alt
  204. ' Right Win
  205. ' Menu
  206. ' Right Ctrl
  207. ' Mouse Left
  208. ' Mouse Middle
  209. ' Mouse Right
  210. ' KEYPAD ENTER returns same code as regular ENTER key (13)
  211. ' KEYPAD "-"   returns same code as regular "-" key (45)
  212. ' KEYPAD "/"   returns same code as regular enter key (47)
  213.  
  214. SUB KeyboardKeydownTest
  215.     DIM iLoop AS INTEGER
  216.     DIM iCode AS INTEGER
  217.     DIM iLastPressed AS INTEGER
  218.  
  219.     CLS
  220.     PRINT "Press a key to see what _KEYDOWN code is detetected."
  221.     PRINT
  222.     PRINT
  223.     PRINT
  224.     PRINT "(Press <ESC> to exit)."
  225.  
  226.     _KEYCLEAR: _DELAY 1
  227.     iLastPressed = -1
  228.     DO
  229.         FOR iLoop = 1 TO 32767
  230.             iCode = _KEYDOWN(iLoop)
  231.  
  232.             ' If the last key pressed is still held down, don't keep printing the code
  233.             IF (iLoop <> iLastPressed) THEN
  234.                 'IF _KEYDOWN(iLoop) THEN
  235.                 IF iCode = TRUE THEN
  236.                     CLS
  237.                     PRINT "Press a key to see what _KEYDOWN code is detetected."
  238.                     PRINT
  239.                     PRINT "Detected key press with _KEYDOWN(" + STR$(iLoop) + ") = " + STR$(iCode)
  240.                     PRINT
  241.                     PRINT "(Press <ESC> to exit)."
  242.                     iLastPressed = iLoop
  243.                 END IF
  244.             ELSE
  245.                 ' If last key is released, clear the code so it can be pressed again:
  246.                 IF iCode = FALSE THEN
  247.                     iLastPressed = -1
  248.                 END IF
  249.             END IF
  250.         NEXT iLoop
  251.  
  252.         '_LIMIT 100
  253.     LOOP UNTIL _KEYDOWN(27)
  254.     _KEYCLEAR
  255. END SUB ' KeyboardKeydownTest
  256.  
  257. ' /////////////////////////////////////////////////////////////////////////////
  258.  
  259. SUB KeyboardKeyhitTest
  260.     DIM iLoop AS INTEGER
  261.     DIM iCode AS INTEGER
  262.     DIM iLastPressed AS INTEGER
  263.     DIM iKey AS INTEGER
  264.     DIM sMessage AS STRING
  265.     DIM z$
  266.  
  267.     CLS
  268.     PRINT "Press a key to see what _KEYHIT code is detetected."
  269.     PRINT
  270.     PRINT
  271.     PRINT
  272.     PRINT "(Press <ESC> to exit)."
  273.  
  274.     _KEYCLEAR: _DELAY 1
  275.     iLastPressed = 0
  276.     DO
  277.         iCode = _KEYHIT
  278.         IF iCode <> 0 THEN
  279.             IF iLastPressed <> iCode THEN
  280.                 iLastPressed = iCode
  281.  
  282.                 IF iCode > 0 THEN
  283.                     ' positive value means key pressed
  284.                     sMessage = "Detected key  pressed with _KEYHIT = " + cstr$(iCode)
  285.                 ELSE
  286.                     ' negative value means key released
  287.                     sMessage = "Detected key released with _KEYHIT = " + cstr$(iCode)
  288.                     iCode = -iCode ' get code of key released
  289.                 END IF
  290.  
  291.                 IF iCode < 256 THEN ' ASCII code values
  292.                     sMessage = sMessage + ", ASCII"
  293.                     IF iCode > 31 THEN
  294.                         sMessage = sMessage + " " + CHR$(34) + CHR$(iCode) + CHR$(34)
  295.                     ELSE
  296.                         sMessage = sMessage + " (UNPRINTABLE)"
  297.                     END IF
  298.                 ELSEIF iCode > 255 AND iCode < 65536 THEN ' 2 byte key codes
  299.                     sMessage = sMessage + ", 2-BYTE-COMBO (" + cstr$(iCode AND 255) + "," + cstr$(iCode \ 256) + ")"
  300.                     iKey = iCode \ 256
  301.                     IF iKey > 31 AND iKey < 256 THEN
  302.                         sMessage = sMessage + " " + CHR$(34) + CHR$(iKey) + CHR$(34)
  303.                     END IF
  304.                 ELSEIF iCode > 99999 AND iCode < 200000 THEN ' QB64 Virtual Key codes
  305.                     sMessage = sMessage + ", QB64 SDL Virtual Key code (" + cstr$(iCode - 100000) + ")"
  306.  
  307.                 ELSEIF iCode > 199999 AND iCode < &H40000000 THEN
  308.                     sMessage = sMessage + ", QB64 VK code (" + cstr$(iCode - 200000) + ")"
  309.  
  310.                 ELSEIF iCode >= &H40000000 THEN ' Unicode values (IME Input mode)
  311.                     PRINT "IME input mode, UNICODE (" + cstr$(iCode - &H40000000) + "0x" + HEX$(iCode - &H40000000) + ")"
  312.                     ' The MKL$ function encodes a LONG numerical value into a 4-byte ASCII STRING value.
  313.                     z$ = MKL$(iCode - &H40000000) + MKL$(0)
  314.                     sMessage = sMessage + " " + z$ + z$ + z$
  315.                 END IF
  316.  
  317.                 CLS
  318.                 PRINT "Press a key to see what _KEYHIT code is detetected."
  319.                 PRINT
  320.                 PRINT sMessage
  321.                 PRINT
  322.                 PRINT "(Press <ESC> to exit)."
  323.             END IF
  324.         END IF ' iCode <> 0
  325.         '_LIMIT 100
  326.     LOOP UNTIL _KEYDOWN(27)
  327.     _KEYCLEAR
  328.  
  329. END SUB ' KeyboardKeyhitTest
  330.  
  331. ' /////////////////////////////////////////////////////////////////////////////
  332. 'DEVICES Button
  333. '_LASTBUTTON(1) keyboards will normally return 512 buttons. One button is read per loop through all numbers.
  334. '_BUTTONCHANGE(number) returns -1 when pressed, 1 when released and 0 when there is no event since the last read.
  335. '_BUTTON(number) returns -1 when a button is pressed and 0 when released
  336.  
  337. ' Detects most keys (where the codes are documented?)
  338. ' However, does not seem to detect:
  339. ' F10
  340. ' Alt
  341. ' Left Alt
  342. ' Right Alt
  343. ' Print Screen
  344. ' Pause/Break
  345.  
  346. SUB KeyboardDeviceTest
  347.     DIM iLoop AS INTEGER
  348.     DIM iCode AS INTEGER
  349.     DIM iLastPressed AS INTEGER
  350.  
  351.     CLS
  352.     PRINT "Press a key to see what _BUTTON code is detetected."
  353.     PRINT
  354.     PRINT
  355.     PRINT
  356.     PRINT "(Press <ESC> to exit)."
  357.  
  358.     _KEYCLEAR: _DELAY 1
  359.     iLastPressed = -1
  360.     DO
  361.         WHILE _DEVICEINPUT(1): WEND ' clear and update the keyboard buffer
  362.  
  363.         ' Detect changed key state
  364.         FOR iLoop = 1 TO 512
  365.             iCode = _BUTTON(iLoop)
  366.  
  367.             ' If the last key pressed is still held down, don't keep printing the code
  368.             IF (iLoop <> iLastPressed) THEN
  369.                 IF iCode <> 0 THEN
  370.                     CLS
  371.                     PRINT "Press a key to see what _BUTTON code is detetected."
  372.                     PRINT
  373.                     PRINT "Detected key press with _BUTTON(" + STR$(iLoop) + ") = " + STR$(iCode)
  374.                     PRINT
  375.                     PRINT "(Press <ESC> to exit)."
  376.                     iLastPressed = iLoop
  377.                 END IF
  378.             ELSE
  379.                 ' If last key is released, clear the code so it can be pressed again:
  380.                 IF iCode = 0 THEN
  381.                     iLastPressed = -1
  382.                 END IF
  383.             END IF
  384.         NEXT iLoop
  385.  
  386.         '_LIMIT 100
  387.     LOOP UNTIL _KEYDOWN(27)
  388.     _KEYCLEAR
  389. END SUB ' KeyboardDeviceTest
  390.  
  391. ' /////////////////////////////////////////////////////////////////////////////
  392. ' Same as QB64's str$ function, except removes the annoying space that
  393. ' str$ prepends to the result.
  394. ' For example:
  395. '     PRINT CHR$(34) + STR$(5) + CHR$(34)
  396. ' outputs
  397. '     " 5"
  398. ' If you do a lot of str$, you find yourself having to use ltrim$ a lot,
  399. ' which can make your code harder to read.
  400. ' With this function, something that would look like
  401. '     sRightCount = LEFT$(LTRIM$(RTRIM$(STR$(arrInfo(iIndex).RightCount))) + STRING$(iLen, " "), iLen)
  402. ' becomes easier to read:
  403. '     sRightCount = LEFT$(cstr$(arrInfo(iIndex).RightCount) + STRING$(iLen, " "), iLen)
  404. ' And cstr is easy to remember for those familiar with vbscript/VBA/VB6/ASP.
  405.  
  406. FUNCTION cstr$ (myValue)
  407.     cstr$ = LTRIM$(RTRIM$(STR$(myValue)))
  408. END FUNCTION ' cstr$
  409.  
  410. ' /////////////////////////////////////////////////////////////////////////////
  411.  
  412. SUB WaitForKey (prompt$, KeyCode&, DelaySeconds%)
  413.     ' SHOW PROMPT (IF SPECIFIED)
  414.     IF LEN(prompt$) > 0 THEN
  415.         IF RIGHT$(prompt$, 1) <> ";" THEN
  416.             PRINT prompt$
  417.         ELSE
  418.             PRINT RIGHT$(prompt$, LEN(prompt$) - 1);
  419.         END IF
  420.     END IF
  421.  
  422.     ' WAIT FOR KEY
  423.     DO: LOOP UNTIL _KEYDOWN(KeyCode&) ' leave loop when specified key pressed
  424.  
  425.     ' PAUSE AFTER (IF SPECIFIED)
  426.     IF DelaySeconds% < 1 THEN
  427.         _KEYCLEAR: '_DELAY 1
  428.     ELSE
  429.         _KEYCLEAR: _DELAY DelaySeconds%
  430.     END IF
  431. END SUB ' WaitForKey
  432.  
  433. ' /////////////////////////////////////////////////////////////////////////////
  434. ' Example: Checking for the system's input devices.
  435.  
  436. ' _DEVICES FUNCTION (QB64 REFERENCE)
  437. ' http://www.[abandoned, outdated and now likely malicious qb64 dot net website - don’t go there]/wiki/index_title_DEVICES/
  438. '
  439. ' The _DEVICES function returns the number of INPUT devices on your computer
  440. ' including keyboard, mouse and game devices.
  441. '
  442. ' Syntax:
  443. '
  444. ' device_count% = _DEVICES
  445. '
  446. ' Returns the number of devices that can be listed separately with the _DEVICE$
  447. ' function by the device number.
  448. ' Devices include keyboard, mouse, joysticks, game pads and multiple stick game
  449. ' controllers.
  450. ' Note: This function MUST be read before trying to use the _DEVICE$,
  451. ' _DEVICEINPUT or _LAST control functions!
  452.  
  453. ' Note: The STRIG/STICK commands won't read from the keyboard
  454. '       or mouse device the above example lists.
  455.  
  456. SUB EnumerateDevices
  457.     DIM devices%
  458.     DIM iLoop%
  459.     DIM sCount$
  460.     DIM iLen AS INTEGER
  461.  
  462.     devices% = _DEVICES ' MUST be read in order for other 2 device functions to work!
  463.  
  464.     CLS
  465.     PRINT "Total devices found: "; STR$(devices%)
  466.     FOR iLoop% = 1 TO devices%
  467.         iLen = 4
  468.         sCount$ = LEFT$(LTRIM$(RTRIM$(STR$(iLoop%))) + STRING$(iLen, " "), iLen)
  469.         PRINT sCount$ + _DEVICE$(iLoop%) + " (" + LTRIM$(RTRIM$(STR$(_LASTBUTTON(iLoop%)))) + " buttons)"
  470.     NEXT iLoop%
  471.     PRINT
  472.     PRINT "PRESS <ESC> TO CONTINUE"
  473.     DO: LOOP UNTIL _KEYDOWN(27) ' leave loop when ESC key pressed
  474.     _KEYCLEAR: '_DELAY 1
  475.  
  476. END SUB ' EnumerateDevices
  477.  

Results:
Code: [Select]
Key                     _BUTTON       _KEYDOWN       _KEYHIT                                             
Esc                     2             27             27                                                   
F1                      60            15104          15104                                               
F2                      61            15360          15360                                               
F3                      62            15616          15616                                               
F4                      63            15872          15872                                               
F5                      64            16128          16128                                               
F6                      65            16384          16384                                               
F7                      66            16640          16640                                               
F8                      67            16896          16896                                               
F9                      68            17152          17152                                               
F10                     ?             17408          17408                                               
F11                     88            ?              -31488                                               
F12                     89            ?              -31232                                               
SysReq (Print Screen)   ?             ?              (-44 on press/release, seems to slow down PC)       
ScrL (Scroll Lock)      71            ?              (-145 on press/release, seems to slow down PC)       
Pause / Break           ?             ?              (31053 momentarily on pressing another key)         
~                       42            96             96                                                   
1!                      3             49             49                                                   
2@                      4             50             50                                                   
3#                      5             51             51                                                   
4$                      6             52             52                                                   
0.05                    7             53             53                                                   
6^                      8             54             54                                                   
7&                      9             55             55                                                   
8*                      10            56             56                                                   
9(                      11            57             57                                                   
0)                      12            48             48                                                   
-_                      13            45             45                                                   
=+                      14            61             61                                                   
BkSp                    15            8              8                                                   
Ins                     339           20992          20992                                               
Home                    328           18176          18176                                               
PgUp                    330           18688          18688                                               
Del                     340           21248          21248                                               
End                     336           20224          20224                                               
PgDn                    338           20736          20736                                               
NumLock                 326           ?              30772 (flip flops with -30772 on release, -144 after)
KEYPAD /                310           (47)           47                                                   
KEYPAD *                56            (42)           42                                                   
KEYPAD -                75            (45)           45                                                   
KEYPAD 7/Home           72            18176          18176                                               
KEYPAD 8 Up             73            18432          18432                                               
KEYPAD 9 PgUp           74            18688          18688                                               
KEYPAD +                79            (43)           43                                                   
KEYPAD 4 Left           76            19200          19200                                               
KEYPAD 5                77            ?              ? (-12 after release)                               
KEYPAD 6 Right          78            19712          19712                                               
KEYPAD 1 End            80            20224          20224                                               
KEYPAD 2 Down           81            20480          20480                                               
KEYPAD 3 PgDn           82            20736          20736                                               
KEYPAD ENTER            285           (13)           13                                                   
KEYPAD 0 Ins            83            20992          20992                                               
KEYPAD . Del            84            21248          21248                                               
Tab                     16            9              9                                                   
Q                       17            113            113                                                 
W                       18            119            119                                                 
E                       19            101            101                                                 
R                       20            114            114                                                 
T                       21            116            116                                                 
Y                       22            121            121                                                 
U                       23            117            117                                                 
I                       24            105            105                                                 
O                       25            111            111                                                 
P                       26            112            112                                                 
[{                      27            91             91                                                   
]}                      28            93             93                                                   
\|                      44            92             92                                                   
Caps Lock               59            ?              30771 (flip flops with -30771 on release, -20 after)
A                       31            97             97                                                   
S                       32            115            115                                                 
D                       33            100            100                                                 
F                       34            102            102                                                 
G                       35            103            103                                                 
H                       36            104            104                                                 
J                       37            106            106                                                 
K                       38            107            107                                                 
L                       39            108            108                                                 
;:                      40            59             59                                                   
'"                      41            39             39                                                   
Enter                   29            13             13                                                   
Left Shift              43            ?              -30768 (-16 on release)                             
Shift                   (44 or 55)    ?              (-30768 or -30769)                                   
Z                       45            22             22                                                   
X                       46            120            120                                                 
C                       47            99             99                                                   
V                       48            118            118                                                 
B                       49            98             98                                                   
N                       50            110            110                                                 
M                       51            109            109                                                 
,<                      52            44             44                                                   
.>                      53            46             46                                                   
/?                      54            47             47                                                   
Right Shift             55            ?              -30769 (-16 on release)                             
Up                      329           18432          18432                                               
Left                    332           19200          19200                                               
Down                    337           20480          20480                                               
Right                   334           19712          19712                                               
Left Ctrl               30            ?              -30766 (-17 on release)                             
Ctrl                    (30 or 286)   ?              (-30766 or -30767)                                   
Left Win                348           ?              ? (-91 after release)                               
Left Alt                ?             ?              -30764 (-18 on release)                             
Alt                     ?             ?              (-30764 or -30765)                                   
Spacebar                58            32             32                                                   
Right Alt               ?             ?              -30765 (-18 on release)                             
Right Win               349           ?              ? (-92 after release)                               
Menu                    350           ?              ? (-93 after release)                               
Right Ctrl              286           ?              -30767 (-17 on release)                             
« Last Edit: December 16, 2020, 02:55:24 pm by madscijr »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
One thing to remember: Those negative values are key up events, not key down.  It's impossible to read them as repetitive event keys, as you only get when they're released and not pressed or held.

Hold "A" down, you'll get 65, 65, 65, 65, 65, 65, 65, 65....  Release it, you get -65.

Hold F12 down, you get (nothing)...  Release it, you get -31232.

Your game can't track a key down state for those buttons; only a key up event.  You might map them to something like opening a status menu, but they'd be completely worthless to hold and automatically fire a machine gun, or such.

The library I posted above gives direct access to window's keyboard commands, and then wraps them into the same standard code set that _KEYHIT  uses.  $INCLUDE the BI file at the top of your code, the BM at the bottom, and then use KeyHit instead of _KEYHIT in your code.

The only problem is, as you mentioned, it won't port to Linux or Mac.



A second side note:  From what I remember with past experiences, _KEYHIT and _KEYDOWN have different issues in them in Linux and Mac.  F12 might read only key up in windows, but might give proper results in Linux.  On the other hand, the menu key might not work at all on Linux.  You'll want to do extensive testing with any workarounds you come up with, to make certain performance is the same on all OSES.

« Last Edit: December 16, 2020, 12:16:31 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
One thing to remember: Those negative values are key up events, not key down.
...
The library I posted above gives direct access to window's keyboard commands,
...

I get it, it sounds like a great tool if you need it.
I think I'm fine for now with using _BUTTON.
If I need keyup, it's easy to track the state of each key using an array.

The only problem is, as you mentioned, it won't port to Linux or Mac.
...
A second side note:  From what I remember with past experiences, _KEYHIT and _KEYDOWN have different issues in them in Linux and Mac.  F12 might read only key up in windows, but might give proper results in Linux.  On the other hand, the menu key might not work at all on Linux.  You'll want to do extensive testing with any workarounds you come up with, to make certain performance is the same on all OSES.

Yikes, what a pain. I wonder if there any Mac or Linux programmers on here who might be interested in porting your library to those OSes, to make porting QB64 to those other systems seamless?


PS So you are familiar with writing libraries that can be used from QB64?
Might I ask, what did you use to develop it? C or C++?

I ask because I might need to do something like that, to make Microsoft's RawInput API accessible to QB64 programs,
to read multiple mouse input like explained here:
https://asawicki.info/news_1533_handling_multiple_mice_with_raw_input

If it is possible to get Windows to detect separate input from multiple mice,
and I have to dirty my hands and write some library in C, to use that input in QB64,
I might be crazy enough to attempt it.

How does one "plug in" a library for QB64?
In Office VBA, you just goto references and add the registered COM DLL.
For QB64 does it have to be a COM DLL? Or a .NET assembly?
Would managed IL code be "low level" and fast enough to return multiple mice input?
I've never written an actual working C or C++ program for Windows.
We used C back in school many moons ago (just simple console programs using GCC in Solaris for comp sci classes),
and a few times at various jobs I had to read through horrid old VC++ 6 code to understand business logic.
I used VB6 to make desktop GUI apps back in the day, but I don't think I every made an library - maybe I did, it's been so long.
And my .NET experience is limited to some VB.NET and C# desktop GUI apps in the early/mid 00s,
of which I remember there was that GAC for shared .NET libraries. But yuck.

Anyway, any and all help / info / advice toward that would be most welcome and appreciated.

Thanks again everyone for your help!
« Last Edit: December 16, 2020, 03:25:51 pm by madscijr »

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
PS So you are familiar with writing libraries that can be used from QB64?
Might I ask, what did you use to develop it? C or C++?

Everything in the Custom Input library which I wrote is written in QB64.  At the heart of the program is basically this little snippet of code:

Code: QB64: [Select]
  1. DECLARE LIBRARY 'function is already used by QB64 so "User32" is not required
  2.     FUNCTION GetAsyncKeyState% (BYVAL vkey AS LONG)
  3.  
  4.  
  5.     FOR i = 1 TO 10000
  6.         IF GetAsyncKeyState(i) THEN LOCATE 1, 1: PRINT i; " pressed  "
  7.     NEXT
  8.     _LIMIT 30

We use DECLARE LIBBRARY to call the windows keyboard commands, and then the results we get correspond to the windows keycodes here: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

Now, all windows does is basically tell us "Is this key up or down?", so the rest of the library is used to determine states for us and to return custom codes in various combinations.  For example: 0x32 (it's a hex value, if you're not used to seeing the results like this) tells us the "2" key is pressed.  It doesn't tell the difference between "2" and "@", which are both related to the same physical key (one is a shift modifier), so the rest of my library allows us to sort the difference out between whether that's a "2" or a "@". 

It also allows us to set custom codes for foreign keyboard layouts, which might have a character, and then 2 or 3 accented characters all associated with the same key on the keyboard.  (A is just "A", Alt-A might be "A, accent forward", CTRL-A might be "A, accent backwards", Shift-A might be "a", SHIFT-ALT-A might be "a, accent forward", ect...)

So most of the library is simply sorting out the proper return codes and allowing us to map keys to custom codes as we want, while the heart of the input routine is basically as simple as the code showcased above. 
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline madscijr

  • Seasoned Forum Regular
  • Posts: 295
    • View Profile
Re: detecting keypresses question - _KEYDOWN and _BUTTON both miss certain keys
« Reply #10 on: December 22, 2020, 06:50:43 pm »
Everything in the Custom Input library which I wrote is written in QB64.
...
We use DECLARE LIBBRARY to call the windows keyboard commands,
...
So most of the library is simply sorting out the proper return codes and allowing us to map keys to custom codes as we want

Thanks for your explanation...
I am not sure how I would use that method to tie into something like the Microsoft Raw Input API though.
Where in DECLARE LIBRARY do you specify a DLL or a .NET assembly name?
TempodiBasic suggested searching for "including external library, using C code" and checking out
http://www.qb64.org/wiki/C_Libraries
which I will do when I have a little more time.

Thanks again for your reply.

Offline Pete

  • Forum Resident
  • Posts: 2361
  • Cuz I sez so, varmint!
    • View Profile
Re: detecting keypresses question - _KEYDOWN and _BUTTON both miss certain keys
« Reply #11 on: December 22, 2020, 07:21:55 pm »
INKEY$ with PEEK for SHIFT/CTRL/ALT is all anyone would ever need.

The neat thing about QB64 is there's always workarounds, including Windows API calls for key detection, for Windows systems.

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

Offline Cobalt

  • QB64 Developer
  • Forum Resident
  • Posts: 878
  • At 60 I become highly radioactive!
    • View Profile
Re: detecting keypresses question - _KEYDOWN and _BUTTON both miss certain keys
« Reply #12 on: December 23, 2020, 12:15:45 am »
I’ll let Fellippe answer this one for you.  If I say anything, I’ll get fussed at for “degrading QB64’s reputation” by telling the truth.

Thats never stopped you before!

You people and your funky keyboards! :P
Granted after becoming radioactive I only have a half-life!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: detecting keypresses question - _KEYDOWN and _BUTTON both miss certain keys
« Reply #13 on: December 23, 2020, 12:54:54 am »
INKEY$ with PEEK for SHIFT/CTRL/ALT is all anyone would ever need.

Unless you need to know the difference in compound keypresses....


Show me an example where you detect CTRL-TAB with INKEY$, which is a common "cycle backwards" key-combo.

Show me how INKEY$ can detect the difference in CTRL-M, ENTER, and CTRL-ENTER.

QB64's built-in key commands handle common input tolerably enough, but they're not where you can point to an user and say, "Here, assign whatever key combo you want for this command, in this program." 

Experiment with them some, and you'll be amazed at how many combinations are mismapped, double mapped, or completely unmapped.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: detecting keypresses question - _KEYDOWN and _BUTTON both miss certain keys
« Reply #14 on: December 23, 2020, 10:03:16 am »
Does the library being discussed execute this entire loop every time it tries to detect a single keypress? Scans all 10000?

Code: QB64: [Select]
  1.     FOR i = 1 TO 10000
  2.         IF GetAsyncKeyState(i) THEN LOCATE 1, 1: PRINT i; " pressed  "
  3.     NEXT

EDIT: I guess this isnt that bad a thing, so long as it happens once per physical, leather-to-plastic keypress. A loop screaming to 10000 to find just one value begs for hashing, but maybe it doesn't actually *need* to be fast.
« Last Edit: December 23, 2020, 10:06:40 am by STxAxTIC »
You're not done when it works, you're done when it's right.