Scancodes: Difference between revisions
No edit summary |
No edit summary |
||
(10 intermediate revisions by the same user not shown) | |||
Line 14: | Line 14: | ||
* The keyboard input is stored at decimal register 96 or &H60 hexadecimal. | * The keyboard input is stored at decimal register 96 or &H60 hexadecimal. | ||
* Returns values from 0 to 127 for keypresses. 129 to 255 for key releases. '''Codes 91 to 93 are available in QB64 only'''. | * Returns values from 0 to 127 for keypresses. 129 to 255 for key releases. '''Codes 91 to 93 are available in QB64 only'''. | ||
* Every key (except Prt Scr/Sys Rq) has an identifying code that will not change with Caps Lock or Shift. | * Every key (except Prt Scr/Sys Rq) has an identifying code that will not change with Caps Lock or Shift. | ||
* Release codes are the original key press code {{InlineCode}}+ 128{{InlineCodeEnd}}. Example: [Esc] key press = 1 and release = 129. | * Release codes are the original key press code {{InlineCode}}+ 128{{InlineCodeEnd}}. Example: [Esc] key press = 1 and release = 129. | ||
* Extended (added) keys on modern keyboards may alternate codes with Left Shift codes 42 and 170 because of Num Lock mode. | * Extended (added) keys on modern keyboards may alternate codes with Left Shift codes 42 and 170 because of Num Lock mode. | ||
* '''Keyboards with Alt Gr key:''' [[_KEYHIT]] may return both Alt (100307) and Ctrl (100306) codes when key is pressed or released. | * '''Keyboards with Alt Gr key:''' [[_KEYHIT]] may return both Alt (100307) and Ctrl (100306) codes when key is pressed or released. | ||
* '''Linux with foreign keyboards: {{InlineCode}} | * '''Linux with foreign keyboards: {{InlineCode}}{{Cl|SHELL}} {{Cl|_HIDE}} "setxkbmap us"{{InlineCodeEnd}} can be used to setup a keyboard to read '''US scan codes'''. | ||
* To clear the keyboard buffer, use the [[INKEY$]] function before or after the [[INP]] read to avoid buffer overflows and beeps. | * To clear the keyboard buffer, use the [[INKEY$]] function before or after the [[INP]] read to avoid buffer overflows and beeps. | ||
{{ | {{FixedStart}}' '''Extended Keyboard Press Scancodes''' | ||
' | ' | ||
'''' | ' '''Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SysReq ScrL Pause''' | ||
' | ' 1 59 60 61 62 63 64 65 66 67 68 87 88 0 70 29 | ||
' | ' '''`~ 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ BkSpc Insert Home PgUp NumL / * -''' | ||
' | ' 41 2 3 4 5 6 7 8 9 10 11 12 13 14 82 71 73 69 53 55 74 | ||
' | ' '''Tab Q W E R T Y U I O P [{ ]} \| Delete End PgDn 7/Home 8/▲ 9/PU + ''' | ||
' | ' 15 16 17 18 19 20 21 22 23 24 25 26 27 43 83 79 81 71 72 73 78 | ||
' | ' '''CapL A S D F G H J K L ;: '" Enter 4/◄- 5 6/-► E''' | ||
' | ' 58 30 31 32 33 34 35 36 37 38 39 40 28 75 76 77 '''n''' | ||
' | ' '''Shift Z X C V B N M ,< .> /? Shift ▲ 1/End 2/▼ 3/PD t''' | ||
' | ' 42 44 45 46 47 48 49 50 51 52 53 54 72 79 80 81 '''e''' | ||
' | ' '''Ctrl Win Alt Spacebar Alt Win Menu Ctrl ◄- ▼ -► 0/Insert ./Del r''' | ||
' | ' 29 {{Text|91|purple}} 56 57 56 {{Text|92 93|purple}} 29 75 80 77 82 83 28 | ||
' | ' | ||
' | ' {{Text|QB64 codes only!|purple}} '''Release codes = Press code + 128. Pause/Break may lock code returns.''' | ||
{{ | {{FixedEnd}} | ||
{{Small|NOTE: The above commented table can be copied and pasted directly into the QB64 IDE}} | |||
=== QBasic/QuickBASIC === | |||
===QBasic/QuickBASIC=== | |||
* In QBasic, extended keys would have the Left Shift release code 224 alternate with the actual release code. Extended keys are the Arrow keypad, Home keypad, Right Alt, and Right Ctrl keys on 101 + extended keyboards with the arrow pad, home pad and number pad. | * In QBasic, extended keys would have the Left Shift release code 224 alternate with the actual release code. Extended keys are the Arrow keypad, Home keypad, Right Alt, and Right Ctrl keys on 101 + extended keyboards with the arrow pad, home pad and number pad. | ||
Line 46: | Line 46: | ||
''Example 1:'' Displays the scan codes for most any keyboard press or release by the user. | ''Example 1:'' Displays the scan codes for most any keyboard press or release by the user. | ||
{{CodeStart}} | {{CodeStart}} | ||
{{Cl|DO}} | {{Cl|DO}} | ||
scancode% = {{Cl|INP}}(&H60) | scancode% = {{Cl|INP}}(&H60) | ||
Line 61: | Line 61: | ||
''Example 2:'' Unlike QBasic, INP(&H60) in '''QB64''' reads from a queue so you never miss a key press. | ''Example 2:'' Unlike QBasic, INP(&H60) in '''QB64''' reads from a queue so you never miss a key press. | ||
{{CodeStart}} | {{CodeStart}} | ||
{{Cl|DEFINT}} A-Z | {{Cl|DEFINT}} A-Z | ||
{{Cl|DIM}} {{Cl|SHARED}} KeyPress(127) | {{Cl|DIM}} {{Cl|SHARED}} KeyPress(127) | ||
CLS | CLS | ||
tmp$ = " ## \\ " | tmp$ = " ## \\ " | ||
{{Cl|DEF SEG}} = 0 | {{Cl|DEF SEG}} = 0 | ||
Line 76: | Line 76: | ||
{{Cl|POKE}} 1050, {{Cl|PEEK}}(1052) 'clear keyboard buffer | {{Cl|POKE}} 1050, {{Cl|PEEK}}(1052) 'clear keyboard buffer | ||
{{Cl|LOOP}} {{Cl|UNTIL}} i = i2 | {{Cl|LOOP}} {{Cl|UNTIL}} i = i2 | ||
row = 2 'display the key down states to show you how it works! | row = 2 'display the key down states to show you how it works! | ||
{{Cl|FOR}} x% = 1 {{Cl|TO}} 88 'read each key scancode from KeyDown array | {{Cl|FOR}} x% = 1 {{Cl|TO}} 88 'read each key scancode from KeyDown array | ||
Line 86: | Line 86: | ||
{{Cl|LOOP}} {{Cl|UNTIL}} i = 1 | {{Cl|LOOP}} {{Cl|UNTIL}} i = 1 | ||
{{Cl|DEF SEG}} | {{Cl|DEF SEG}} | ||
{{Cl|END}} | {{Cl|END}} | ||
{{CodeEnd}} | {{CodeEnd}} | ||
{{ | {{Small|Code by Galleon}} | ||
''Explanation:'' INP does not clear the keyboard buffer so it may beep. To eliminate the problem use INKEY$ before or after reading with INP(96). INP will still return the press code. The array can hold more than one code return. QBasic users may note that the arrow pad and Home pad keypresses also alternate codes 42 and 170 due to Number Lock setting. That will not happen in '''QB64'''. | ''Explanation:'' INP does not clear the keyboard buffer so it may beep. To eliminate the problem use INKEY$ before or after reading with INP(96). INP will still return the press code. The array can hold more than one code return. QBasic users may note that the arrow pad and Home pad keypresses also alternate codes 42 and 170 due to Number Lock setting. That will not happen in '''QB64'''. | ||
Line 94: | Line 94: | ||
''Example 3:'' A simple MULTIKEY demo using the SC Array to hold multiple key presses for diagonal arrow key moves. | ''Example 3:'' A simple MULTIKEY demo using the SC Array to hold multiple key presses for diagonal arrow key moves. | ||
{{CodeStart}} | {{CodeStart}} | ||
{{Cl|DEFINT}} A-Z | {{Cl|DEFINT}} A-Z | ||
{{Cl|DIM}} BG(300), Box(300), SC(127) ' BG holds background images. Box holds the Box image. | {{Cl|DIM}} BG(300), Box(300), SC(127) ' BG holds background images. Box holds the Box image. | ||
{{Cl | {{Cl|SCREEN}} 13 ' graphic coordinate minimums are 0 to 319 column or 199 row maximums. | ||
' set up screen background | ' set up screen background | ||
{{Cl|COLOR}} 4: {{Cl|LOCATE}} 10, 5: {{Cl|PRINT}} "Multikey Keyboard input routine" | {{Cl|COLOR}} 4: {{Cl|LOCATE}} 10, 5: {{Cl|PRINT}} "Multikey Keyboard input routine" | ||
Line 111: | Line 111: | ||
{{Cl|LINE}} (x, y)-(x + 15, y + 15), 9, BF ' the plain blue box to move | {{Cl|LINE}} (x, y)-(x + 15, y + 15), 9, BF ' the plain blue box to move | ||
{{Cl|GET (graphics statement)|GET}} (x, y)-(x + 15, y + 15), Box ' GET to Box Array | {{Cl|GET (graphics statement)|GET}} (x, y)-(x + 15, y + 15), Box ' GET to Box Array | ||
{{Cl|DO}} 'main loop | {{Cl|DO}} 'main loop | ||
t! = {{Cl|TIMER}} + .05 | t! = {{Cl|TIMER (function)|TIMER}} + .05 | ||
{{Cl|DO}} ' 1 Tick (1/18th second) keypress scancode read loop | {{Cl|DO}} ' 1 Tick (1/18th second) keypress scancode read loop | ||
a$ = {{Cl|INKEY$}} ' So the keyboard buffer won't get full | |||
code% = {{Cl|INP}}(&H60) ' Get keyboard scan code from port 96 | |||
{{Cl|IF...THEN|IF}} code% < 128 {{Cl|THEN}} SC(code%) = 1 {{Cl|ELSE}} SC(code% - 128) = 0 ' true/false values to array | |||
{{Cl|LOOP}} {{Cl|UNTIL}} {{Cl|TIMER}} > t!' loop until one tick has passed | {{Cl|LOOP}} {{Cl|UNTIL}} {{Cl|TIMER (function)|TIMER}} > t!' loop until one tick has passed | ||
PX = x: PY = y ' previous coordinates | PX = x: PY = y ' previous coordinates | ||
Line 126: | Line 126: | ||
{{Cl|IF}} SC(80) = 1 {{Cl|THEN}} y = y + 5: {{Cl|IF}} y > 184 {{Cl|THEN}} y = 184 | {{Cl|IF}} SC(80) = 1 {{Cl|THEN}} y = y + 5: {{Cl|IF}} y > 184 {{Cl|THEN}} y = 184 | ||
{{Cl|IF}} x <> PX {{Cl|OR}} y <> PY {{Cl|THEN}} ' look for a changed coordinate value | {{Cl|IF}} x <> PX {{Cl|OR}} y <> PY {{Cl|THEN}} ' look for a changed coordinate value | ||
{{Cl|WAIT}} 936, 8: {{Cl|PUT (graphics statement)|PUT}} (PX, PY), BG, PSET ' replace previous BG first | |||
{{Cl|GET (graphics statement)|GET}} (x, y)-(x + 15, y + 15), BG ' GET BG at new position before box is set | |||
{{Cl|PUT (graphics statement)|PUT}} (x, y), Box, PSET ' PUT box image at new position | |||
{{Cl|END IF}} | {{Cl|END IF}} | ||
{{Cl|LOOP}} {{Cl|UNTIL}} SC(1) = 1 ' main loop until [Esc] key (scan code 1) is pressed | {{Cl|LOOP}} {{Cl|UNTIL}} SC(1) = 1 ' main loop until [Esc] key (scan code 1) is pressed | ||
{{CodeEnd}} | {{CodeEnd}} | ||
{{ | {{Small|Code by Ted Weissgerber}} | ||
''Explanation:'' The SC array is used to hold all of the scancode status index values as 1 when pressed and 0 if released(see the ELSE statement). If arrow key(s) are pressed then each is moved to new positions on the screen. The coordinates are also checked to keep the box area's [[GET (graphics statement)|GET]] and [[PUT (graphics statement)|PUT]] statements on the screen to avoid an error. The previous background is PUT using the previous coordinates PX and PY. Then new position background box area is saved with GET before the box is placed with PUT. The box image is 16 X 16 and could use another image. | ''Explanation:'' The SC array is used to hold all of the scancode status index values as 1 when pressed and 0 if released(see the ELSE statement). If arrow key(s) are pressed then each is moved to new positions on the screen. The coordinates are also checked to keep the box area's [[GET (graphics statement)|GET]] and [[PUT (graphics statement)|PUT]] statements on the screen to avoid an error. The previous background is PUT using the previous coordinates PX and PY. Then new position background box area is saved with GET before the box is placed with PUT. The box image is 16 X 16 and could use another image. | ||
{{PageSeeAlso}} | {{PageSeeAlso}} | ||
*[[_KEYHIT]], [[_KEYDOWN]] | * [[_KEYHIT]], [[_KEYDOWN]] | ||
*[[ASC]], [[ASCII]] | * [[ASC (function)]], [[ASCII]] | ||
*[[Keyboard scancodes]] | * [[Keyboard scancodes]] | ||
*[[Creating Sprite Masks]] | * [[Creating Sprite Masks]] | ||
* [[ | * [[Windows Libraries#Hot_Keys_(maximize)|Windows hot keys]] | ||
* [http://www.quadibloc.com/comp/scan.htm Keyboard Scan Codes] | |||
* [http://www.win.tue.nl/~aeb/linux/kbd/scancodes.html Other Keyboards] | |||
{{PageNavigation}} | {{PageNavigation}} |
Latest revision as of 00:45, 26 February 2023
This page is maintained for historic purposes. The functionality of the code below can now be achieved through the _KEYDOWN function.
Scancodes are the return values of keyboard input that can be read using INP to find key presses and releases, unlike the ASCII codes returned using INKEY$.
Syntax
- scanCode% = INP(&H60)
Description
- Used to find [Ctrl], [Alt], [Shift], [Caps Lock], [Scroll Lock], [Num Lock] and [F]unction key controls.
- The keyboard input is stored at decimal register 96 or &H60 hexadecimal.
- Returns values from 0 to 127 for keypresses. 129 to 255 for key releases. Codes 91 to 93 are available in QB64 only.
- Every key (except Prt Scr/Sys Rq) has an identifying code that will not change with Caps Lock or Shift.
- Release codes are the original key press code + 128. Example: [Esc] key press = 1 and release = 129.
- Extended (added) keys on modern keyboards may alternate codes with Left Shift codes 42 and 170 because of Num Lock mode.
- Keyboards with Alt Gr key: _KEYHIT may return both Alt (100307) and Ctrl (100306) codes when key is pressed or released.
- Linux with foreign keyboards: SHELL _HIDE "setxkbmap us" can be used to setup a keyboard to read US scan codes.
- To clear the keyboard buffer, use the INKEY$ function before or after the INP read to avoid buffer overflows and beeps.
' Extended Keyboard Press Scancodes ' ' Esc F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SysReq ScrL Pause ' 1 59 60 61 62 63 64 65 66 67 68 87 88 0 70 29 ' `~ 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ BkSpc Insert Home PgUp NumL / * - ' 41 2 3 4 5 6 7 8 9 10 11 12 13 14 82 71 73 69 53 55 74 ' Tab Q W E R T Y U I O P [{ ]} \| Delete End PgDn 7/Home 8/▲ 9/PU + ' 15 16 17 18 19 20 21 22 23 24 25 26 27 43 83 79 81 71 72 73 78 ' CapL A S D F G H J K L ;: '" Enter 4/◄- 5 6/-► E ' 58 30 31 32 33 34 35 36 37 38 39 40 28 75 76 77 n ' Shift Z X C V B N M ,< .> /? Shift ▲ 1/End 2/▼ 3/PD t ' 42 44 45 46 47 48 49 50 51 52 53 54 72 79 80 81 e ' Ctrl Win Alt Spacebar Alt Win Menu Ctrl ◄- ▼ -► 0/Insert ./Del r ' 29 91 56 57 56 92 93 29 75 80 77 82 83 28 ' ' QB64 codes only! Release codes = Press code + 128. Pause/Break may lock code returns. |
QBasic/QuickBASIC
- In QBasic, extended keys would have the Left Shift release code 224 alternate with the actual release code. Extended keys are the Arrow keypad, Home keypad, Right Alt, and Right Ctrl keys on 101 + extended keyboards with the arrow pad, home pad and number pad.
Examples
Example 1: Displays the scan codes for most any keyboard press or release by the user.
DO scancode% = INP(&H60) LOCATE 15, 30 IF scancode% < 128 THEN COLOR 10: PRINT "Pressed Code ="; scancode%; SPACE$(1) IF scancode% > 127 THEN COLOR 12: PRINT "Release Code ="; scancode%; SPACE$(1) a$ = INKEY$ ' prevent keyboard beeps LOOP UNTIL scancode% = 1 ' [Esc] key exit |
Explanation: Green is a press code and red is the release code. Num Lock mode may display the Left Shift key press(42) and release(170) codes, plus code 224, but the designated codes are returned also. QB64 does not return those extra codes.
Example 2: Unlike QBasic, INP(&H60) in QB64 reads from a queue so you never miss a key press.
DEFINT A-Z DIM SHARED KeyPress(127) CLS tmp$ = " ## \\ " DEF SEG = 0 DO i = INP(&H60) 'update keydown states DO 'key read loop IF (i AND 128) THEN KeyPress(i XOR 128) = 0 IF (i AND 128) = 0 THEN KeyPress(i) = -1 i2 = i i = INP(&H60) POKE 1050, PEEK(1052) 'clear keyboard buffer LOOP UNTIL i = i2 row = 2 'display the key down states to show you how it works! FOR x% = 1 TO 88 'read each key scancode from KeyDown array L = x% MOD 10: column = (7 * L) + 5 IF L = 0 THEN row = row + 2 LOCATE row, column IF KeyPress(x%) THEN PRINT USING tmp$; x%; STRING$(2, 219) ELSE PRINT USING tmp$; x%; "UP" NEXT LOOP UNTIL i = 1 DEF SEG END |
Explanation: INP does not clear the keyboard buffer so it may beep. To eliminate the problem use INKEY$ before or after reading with INP(96). INP will still return the press code. The array can hold more than one code return. QBasic users may note that the arrow pad and Home pad keypresses also alternate codes 42 and 170 due to Number Lock setting. That will not happen in QB64.
Example 3: A simple MULTIKEY demo using the SC Array to hold multiple key presses for diagonal arrow key moves.
DEFINT A-Z DIM BG(300), Box(300), SC(127) ' BG holds background images. Box holds the Box image. SCREEN 13 ' graphic coordinate minimums are 0 to 319 column or 199 row maximums. ' set up screen background COLOR 4: LOCATE 10, 5: PRINT "Multikey Keyboard input routine" COLOR 10: LOCATE 12, 4: PRINT "Use the arrow keys to move the box." LOCATE 13, 4: PRINT "Note that you can press two or more" LOCATE 14, 4: PRINT "keys at once for diagonal movement!" COLOR 14: LOCATE 16, 4: PRINT " Also demonstrates how GET and PUT " LOCATE 17, 4: PRINT "are used to preserve the background." COLOR 11: LOCATE 20, 11: PRINT "Press [Esc] to quit" x = 150: y = 50: PX = x: PY = y ' actual box starting position GET (x, y)-(x + 15, y + 15), BG ' GET original BG at start box position LINE (x, y)-(x + 15, y + 15), 9, BF ' the plain blue box to move GET (x, y)-(x + 15, y + 15), Box ' GET to Box Array DO 'main loop t! = TIMER + .05 DO ' 1 Tick (1/18th second) keypress scancode read loop a$ = INKEY$ ' So the keyboard buffer won't get full code% = INP(&H60) ' Get keyboard scan code from port 96 IF code% < 128 THEN SC(code%) = 1 ELSE SC(code% - 128) = 0 ' true/false values to array LOOP UNTIL TIMER > t!' loop until one tick has passed PX = x: PY = y ' previous coordinates IF SC(75) = 1 THEN x = x - 5: IF x < 0 THEN x = 0 IF SC(77) = 1 THEN x = x + 5: IF x > 304 THEN x = 304 IF SC(72) = 1 THEN y = y - 5: IF y < 0 THEN y = 0 IF SC(80) = 1 THEN y = y + 5: IF y > 184 THEN y = 184 IF x <> PX OR y <> PY THEN ' look for a changed coordinate value WAIT 936, 8: PUT (PX, PY), BG, PSET ' replace previous BG first GET (x, y)-(x + 15, y + 15), BG ' GET BG at new position before box is set PUT (x, y), Box, PSET ' PUT box image at new position END IF LOOP UNTIL SC(1) = 1 ' main loop until [Esc] key (scan code 1) is pressed |
Explanation: The SC array is used to hold all of the scancode status index values as 1 when pressed and 0 if released(see the ELSE statement). If arrow key(s) are pressed then each is moved to new positions on the screen. The coordinates are also checked to keep the box area's GET and PUT statements on the screen to avoid an error. The previous background is PUT using the previous coordinates PX and PY. Then new position background box area is saved with GET before the box is placed with PUT. The box image is 16 X 16 and could use another image.
See also
- _KEYHIT, _KEYDOWN
- ASC (function), ASCII
- Keyboard scancodes
- Creating Sprite Masks
- Windows hot keys
- Keyboard Scan Codes
- Other Keyboards