ugBASIC User Manual

Keyboard

The ugBASIC provides you with many useful keyboard commands. These can be used in anything from an arcade game to an adventure.

Introduction Theory Basic Key State Input Other

Introduction

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.

Some theorical aspects

Please note that the explanation given here is valid in case of asynchronous use of the keyboard. For more information please click here.

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:


Now, it is clear that, depending on the moment in which we check whether the key is pressed or not, we have a more or less correct representation of what is happening.


To better handle this situation, ugBASIC provides two different sets of instructions.


There is a set of instructions that let you know, at the moment you check, whether a key is pressed or not, and which key that key is (or, even, if a certain key is pressed). This type of instruction is very convenient for real-time video games, and are:
  • WAIT KEY - wait for a key press
  • WAIT KEY RELEASE - wait for a key press (and release)
  • KEY STATE(...) - check if a specific key is pressed
  • SCANCODE - retrieve the scan code of key pressed
  • ASCIICODE - retrieve the ascii code of key pressed
On the other hand, there are also instructions that let you retrieve the pressed key or the sequence of pressed keys, even if you are not constantly checking the keyboard. This can be useful for those games where the user has to type something.
  • KEY PRESSED(...) - check if a specific has been pressed
  • KEYPRESS - retrieve the scan code of key pressed
  • INKEY$ - retrieve the character of key pressed
  • INPUT - retrieve one or more data from keyboard
Note that KEY 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:


This repetition occurs whenever a keyboard key is held down: in this case, after a certain time (defined as "latency"), a repetition of the keys begins as if the user were continuously pressing the key. The repetition will occur by pressing the key for a time equal to "delay", while the key will be released for a time equal to "release".

Basic commands

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.

State of keys

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:

bitmeanning
0Left SHIFT
1Right SHIFT
2CAPS LOCK
3CONTROL
4Left ALT
5Right ALT


If a bit is set to a one, then the associated button has been held down by the user. Example:

CENTRE "Press some control keys"
DO
   LOCATE 14, 4
   PRINT BIN$(KEY SHIFT, 8)
LOOP

Note that not all computers support control keys, nor is it possible to have individual pressure detection. Depending on the target, some of the bits may not be available, or only under certain conditions. In particular:
targetlimitations 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.

More input

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

Other settings

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.

Any problem?

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!