QBasic/Advanced Input

INKEY$

edit

Getting real time information from the user is a little more difficult. To do so, we will use the INKEY$ command, which checks to see whether a user typed a key and provides the keypress to the program.

Look at this code and then we will look at it in depth:

DO
	LET k$ = INKEY$
LOOP UNTIL k$ <> ""
SELECT CASE k$
	CASE "q"
		QuitProgram
	CASE "c"
		MakeCircle
	CASE "s"
		MakeSquare
END SELECT

The first part is the DO-LOOP which constantly polls INKEY$ for a return value. In the basic use, INKEY$ returns an empty string if no keys are being pressed and continues with the program. Once a key is pressed, INKEY$ will return that key immediately.

The keyboard buffer

edit

What is INKEY$ doing and how does it work?

While the INKEY$ command looks like it returns the key currently being pressed, this is not the case. It is used by the program to answer the question, "What is IN the KEYboard buffer?" To understand this you will need to understand what a basic buffer is and why it is used.

In older systems (not necessarily the IBM PC) a single chip processed keyboard input, and controlled the LED lights for caps lock and number lock. Because a computer does many things at once (e.g., take input from the mouse, crunch numbers, call subroutines, display new information on the screen), it needs to be able to remember what was pressed on the keyboard while it is busy. This chip contained some memory (called a buffer) that allow keeping track of a limited number of keypresses.

Within the Dos platform under IBM PCs, the hardware has changed slightly. Instead of a hardware buffer, pressing or releasing a key will interrupt the running program to add a keystroke to a software buffer located in the BIOS. This procedure is usually unnoticed by the user and has minimal impact on system performance. However, this buffer allows for 15 characters: attempting to overflow it when the computer is busy will cause a short beep and drop any further characters.

The INKEY$ command uses this buffer as a FIFO (First In First Out) buffer. As an example let's say you have a game that has a bouncing ball on the screen and a paddle at the bottom. The computer program constantly has to update the screen to show the movement of the ball. While it does this the program passes by an INKEY$ command to see what value is returned. If the user has pressed a key since the last time the command was invoked it will return that key. Let's say the ball is moving over to the right and the user needs to press the "R" key to tell the program to move the paddle right. Since the program is busy moving the ball and updating the screen, it does not instantaneously notice that the user has pressed the key. Instead, the key press is stored in the keyboard buffer, and retrieved a few milliseconds (or microseconds) later when the INKEY$ command is used.

In many programs (as above), INKEY$ will appear nested in a loop. It is requested over and over again. This allows the program to get user input one character at a time. Using our example above, the user may need to press R over and over again until the paddle is under the ball. On the other hand, the user may press R too many times and need to press L to move it left. Because the INKEY$ command is using a FIFO buffer it will always retrieve the keys pressed in the same order as they were typed.

In summary, the INKEY$ command will always return and remove the first character in the keyboard buffer. Generally speaking, it is used over and over to retrieve every key that has been pressed, and to allow a user to interact with a program in a close approximation to "real time." If there is no key in the keyboard buffer, INKEY$ returns an empty string (no character).

Scancodes

edit

Some keypresses are not associated with an ASCII character. When one of these keys is pressed, INKEY$ returns a string with two characters: the first character is a null (ASCII code 0), and the second is the raw scan code for the keyboard. A full listing of the scancodes can be found within the QBASIC help file. You can also determine the scan codes by examining the results of INKEY$ as you press those keys in question.

Note:
Some keys cannot be directly detected by INKEY$.

  Ctrl+            Extended; prefixed with CHR$(0)
 1  A               3   Ctrl+2
 2  B              15   Shift+Tab
 3  C              
 4  D                Alt+    Alt+    Alt+     Alt+
 5  E              16  Q   30  A   44  Z   120  1
 6  F              17  W   31  S   45  X   121  2
 7  G              18  E   32  D   46  C   122  3
 8  H  Backspace   19  R   33  F   47  V   123  4
 9  I  Tab         20  T   34  G   48  B   124  5
10  J  Ctrl+Enter  21  Y   35  H   49  N   125  6
11  K              22  U   36  J   50  M   126  7
12  L              23  I   37  K           127  8
13  M  Enter       24  O   38  L           128  9
14  N              25  P                   129  0
15  O                                      130  -
16  P                 Shift Ctrl Alt       131  =
17  Q              59   84   94  104  F1
18  R              60   85   95  105  F2
19  S              61   86   96  106  F3
20  T              62   87   97  107  F4
21  U              63   88   98  108  F5
22  V              64   89   99  109  F6
23  W              65   90  100  110  F7
24  X              66   91  101  111  F8
25  Y              67   92  102  112  F9
26  Z              68   93  103  113  F10
27  [  Escape     133  135  137  139  F11
28  \             134  136  138  140  F12
29  ]
30  6              71  Home   72  Up    73  PgUp
31  -              75  Left             77  Right
                   79  End    80  Down  81  PgDn
   Ctrl+           82  Insert           83  Del
127 Backspace
                  119  Ctrl+Home   132  Ctrl+PgUp
                  115  Ctrl+Left   116  Ctrl+Right
                  117  Ctrl+End    118  Ctrl+PgDn