Almost all targets that ugBASIC supports provide a keyboard, with the obvious
exception of consoles. For these targets, you can use the keyboard to receive typed commands,
or to use the keyboard as a very advanced and flexible joystick.
To make the code fast and optimized, the compiler provides direct access to the underlying
hardware format, which in jargon is called "scancode". In some targets it can coincide with the
ASCII code. However, in general, it is different from computer to computer. For this reason
it is necessary for the program to use the constants that the language provides, and they are all
prefixed by the term KEY
.
In general, pressing a key generates a "key pressed" event and a "key released"
event. The first is received when the finger presses the key all the way down,
while the second is received when the key is released.
To better represent this situation, you can draw rectangles where every time a key is
pressed, we have a rectangle:
WAIT KEY
- wait for a key pressWAIT KEY RELEASE
- wait for a key press (and release)KEY STATE(...)
- check if a specific key is pressedSCANCODE
- retrieve the scan code of key pressedASCIICODE
- retrieve the ascii code of key pressedKEY PRESSED(...)
- check if a specific has been pressedKEYPRESS
- retrieve the scan code of key pressedINKEY$
- retrieve the character of key pressedINPUT
- retrieve one or more data from keyboardKEY PRESSED
function will behave as an alias of KEY STATE
,
unless the DEFINE KEY PRESSED ASYNC
pragma option is enabled.
In order to better manage keyboard typing, ugBASIC automatically manages character repetition,
as described below:
The INKEY$
function checks whether the user has pressed
a key, and returns its value in a string. Note the INKEY$
command doesn't wait for your input in any way. If the user hasn't
entered a character, INKEY$
will simply return an empty
string ""
.
Example:
DO
x$=INKEY$: IF x$<>"" THEN PRINT x$;
LOOP
Regardless of hardware, INKEY$
is only capable of reading keys which return a
specific 7 bit ASCII character from the keyboard. ASCII is a standard code
used to represent all the characters which can be printed on the
screen. It's important to realise that some keys, like the function keys
o special keys, use a rather different format. If INKEY$
detects
such a key, it could return a zero character or a non-ASCII character (ASCII code
more than 128). You can now find the the internal scan code of this key using a
separate SCANCODE
function.
SCANCODE
returns the internal scancode of a key which
was previously entered using the INKEY$
function. This allows
you to check for keys which do not produce a character from the keyboard,
such as F1
or TAB
. Try typing in the following
small example:
DO
WHILE k$=""
k$=INKEY$
WEND
IF ASC(k$)=0 THEN PRINT "You Pressed A Key With No ASCII Code."
PRINT "The scancode is ";SCANCODE
k$=""
LOOP
To avoid having to write a loop to read a certain number of characters
with INKEY$
, you can use the INPUT$
function.
The function will wait for a certain number of characters from keyboard,
waiting for each one in turn. As with INKEY$
, these characters
are not echoed onto the screen. The return value is a string
which will be loaded with your new characters.
Example:
CLEAR KEY: PRINT "Type In Ten Characters"
c$=INPUT$(10) : PRINT "You entered ";c$
Note that this instruction is not that same as the standard
INPUT
command. The two instructions are completely different.
The ugBASIC language provides primitives that allow you to know the state of a
single key, or multiple keys, being pressed. This is particularly useful for
implementing keyboard-controlled video games, for example to make the character
jump while moving towards the finish line.
The KEY STATE
function checks
if a specific button has been pressed on the keyboard. Its parameter is the internal
scancode of the key you want to check. If this key is currently being depressed then
KEY STATE
will return a value of TRUE
(-1
),
otherwise the result will be FALSE
(O
).
Example:
DO
IF KEY STATE(KEY SPACE) = TRUE THEN PRINT "SPACE!"
IF KEY STATE(KEY A) = TRUE THEN PRINT "A!"
LOOP
The KEY SHIFT
function returns the current status of the various control
keys. These keys such as SHIFT
or ALT
cannot be detected
using the standard INKEY$
or SCANCODE
system. But you can
easily test for any combination of control keys with just a single call to the
KEY SHIFT
function. The result is a bit map in the following format:
bit | meanning |
---|---|
0 | Left SHIFT |
1 | Right SHIFT |
2 | CAPS LOCK |
3 | CONTROL |
4 | Left ALT |
5 | Right ALT |
CENTRE "Press some control keys"
DO
LOCATE 14, 4
PRINT BIN$(KEY SHIFT, 8)
LOOP
target | limitations and behaviours |
---|---|
atari atarixl | Only SHIFT keys are detected, and both (left and right). The CTRL key is detected only if a key is pressed. The CAPS LOCK detection is purely software. |
c128 c64 c64reu c128z | Both left and right SHIFT are detected, separately. The CTRL key is detected. The CAPS LOCK is equivalent to the left SHIFT. |
coco coco3 d32 d64 | Only SHIFT keys are detected, and both (left and right). |
cpc | SHIFT keys are detected, and both (left and right), but only on real hardware. Only the CAPS LOCK is detected. |
mo5 pc128op | Only right SHIFT key is detected, and it keep both (left and right) as pressed. The CTRL button is detected, as well. The CAPS LOCK is not detected. |
msx1 | Both left and right SHIFT are detected, as if both was presed. The CTRL key is detected. The CAPS LOCK is detected. |
zx | No control keys are detected, yet. |
The instruction INPUT
provides you with a standard
way of entering information into one or more variables. There are
two possible formals for this instruction:
INPUT vars[;]
Enters a list of variables directly from the keyboard.
The var
can contain any set of variables you like,
separated by commas. A question mark will be automatically displayed
at the current cursor position.
INPUT "Prompt";variable list[;]
INPUT "Prompt",variable list[;]
Prints out the prompt string before entering your information. Note that
you must place a semi-colon between your text and the variable list,
if you want to print out a question mark. If you use a comma, the
question mark will be not printed.
The optional semi-colon ";" at the end of your variable list specifies that
the text cursor will not be affected by the INPUT
instruction,
and will retain its original position after the data has been entered.
When you execute one of these commands, ugBASIC will wait
for you to enter the required information from the keyboard. Each variable
in your list must be matched by a single value from the user. These values
must be of the same type as your original variables, and should be separated
by commas. Here are some simple examples:
INPUT a: PRINT "Your number was ";a
INPUT "Enter a floating point number";n
PRINT "You entered ";n
INPUT "What's your name Human?",name$;
LOCATE 23, : PRINT "Hello ";name$
The LINE INPUT
is exactly the same as INPUT
,
except that it uses a RETURN
instead of a comma to separate
each value you enter from the keyboard.
Example:
LINE INPUT "Enter three numbers";a, b, c
PRINT a, b, c
You can wait for a key press by using the WAIT KEY
command. Moreover, you can also wait for releasing the keyboard,
by using the WAIT KEY RELEASE
.
WAIT KEY: PRINT "key pressed"
WAIT KEY RELEASE: PRINT "key pressed and released"
Other than pragmas,
you can change some parameters using the KEY SPEED
instruction.
It lets you tailor the speed of the keyboard to your own particular taste.
The new speed will be used on the compiler source. Latency is the time (in ticks
or milliseconds, if MS
suffix is used) between pressing a key,
and the start of the repeat sequence. Delay is the delay between each
successive character and, finally, release is the time between the automatic
release and the next press event (see above).
Example:
KEY SPEED 1000 MS, 1000 MS, 1000 MS: REM Hold down a key for SLOW repeat
KEY SPEED 1, 1, 1: REM FAST repeat!!
On some hardware, whenever you enter a character from the keyboard, its ASCII code
is placed in an area of memory known as the keyboard buffer (or "queue"). It is
this buffer that is sampled by the INKEY$
function to get your key
presses. CLEAR KEY
erases this buffer completely, and returns your
keyboard to its original state. It's especially helpful at the start of a program,
as the buffer may well be full of unwanted information. You can also call it
immediately before a WAIT KEY
command to ensure that the program
waits for a fresh keypress before preceding.
Example:
CLEAR KEY: REM remove current key presses
WAIT KEY: REM Wait for a new key
Finally, the PUT KEY
command loads a string of characters
directly into the keyboard buffer. Carriage returns can be included using a
CHR$(13)
(RETURN
) character. The most common use of
PUT KEY
is to set up defaults for your INPUT
routines.
Here's a demonstration:
DO
PUT KEY "NO"
INPUT "Another Game ";a$
IF a$="NO" THEN EXIT
LOOP
The program above assigns "No" to the default INPUT
string.
Hitting the RETURN
key will enter this value straight into
the variable a$. Alternatively, you can edit the line using the normal cursor
keys, and type in your own value for a$ as required.
If you have found a problem, if you think there is a bug or, more
simply, you would like something to be improved, write a topic on the official forum, or open an issue on GitHub.
Thank you!