The Allegro keyboard handler provides both buffered input and a set of flags
storing the current state of each key. Note that it is not possible to
correctly detect every combination of keys, due to the design of the PC
keyboard. Up to two or three keys at a time will work fine, but if you press
more than that the extras are likely to be ignored (exactly which
combinations are possible seems to vary from one keyboard to another).
int install_keyboard();
Installs the Allegro keyboard interrupt handler. You must call this
before using any of the keyboard input routines. Once you have set up the
Allegro handler, you can no longer use operating system calls or C
library functions to access the keyboard. Returns zero on success, or a
negative number on failure (but you may decide not to check the return
value as this function is very unlikely to fail). Note that on some
platforms the keyboard won't work unless you have set a graphic mode,
even if this function returns zero before calling set_gfx_mode.
void remove_keyboard();
Removes the keyboard handler, returning control to the operating system.
You don't normally need to bother calling this, because allegro_exit()
will do it for you.
void install_keyboard_hooks(int (*keypressed)(), int (*readkey)());
You should only use this function if you *aren't* using the rest of the
keyboard handler. It should be called in the place of install_keyboard(),
and lets you provide callback routines to detect and read keypresses,
which will be used by the main keypressed() and readkey() functions. This
can be useful if you want to use Allegro's GUI code with a custom
keyboard handler, as it provides a way for the GUI to get keyboard input
from your own code, bypassing the normal Allegro input system.
int poll_keyboard();
Wherever possible, Allegro will read the keyboard input asynchronously
(ie. from inside an interrupt handler), but on some platforms that may
not be possible, in which case you must call this routine at regular
intervals to update the keyboard state variables. To help you test your
keyboard polling code even if you are programming on a platform that
doesn't require it, after the first time that you call this function
Allegro will switch into polling mode, so from that point onwards you
will have to call this routine in order to get any keyboard input at all,
regardless of whether the current driver actually needs to be polled or
not. The keypressed(), readkey(), and ureadkey() functions call
poll_keyboard() automatically, so you only need to use this function when
accessing the key[] array and key_shifts variable. Returns zero on
success, or a negative number on failure (ie. no keyboard driver
installed).
int keyboard_needs_poll();
Returns TRUE if the current keyboard driver is operating in polling mode.
extern volatile char key[KEY_MAX];
Array of flags indicating the state of each key, ordered by scancode.
Wherever possible these values will be updated asynchronously, but if
keyboard_needs_poll() returns TRUE, you must manually call
poll_keyboard() to update them with the current input state. The
scancodes are defined in allegro/keyboard.h as a series of KEY_*
constants (and are also listed below). For example, you could write:
if (key[KEY_SPACE])
printf("Space is pressed\n");
Note that the array is supposed to represent which keys are physically
held down and which keys are not, so it is semantically read-only.
These are the keyboard scancodes:
KEY_A ... KEY_Z,
KEY_0 ... KEY_9,
KEY_0_PAD ... KEY_9_PAD,
KEY_F1 ... KEY_F12,
KEY_ESC, KEY_TILDE, KEY_MINUS, KEY_EQUALS,
KEY_BACKSPACE, KEY_TAB, KEY_OPENBRACE, KEY_CLOSEBRACE,
KEY_ENTER, KEY_COLON, KEY_QUOTE, KEY_BACKSLASH,
KEY_BACKSLASH2, KEY_COMMA, KEY_STOP, KEY_SLASH,
KEY_SPACE,
KEY_INSERT, KEY_DEL, KEY_HOME, KEY_END, KEY_PGUP,
KEY_PGDN, KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN,
KEY_SLASH_PAD, KEY_ASTERISK, KEY_MINUS_PAD,
KEY_PLUS_PAD, KEY_DEL_PAD, KEY_ENTER_PAD,
KEY_PRTSCR, KEY_PAUSE,
KEY_ABNT_C1, KEY_YEN, KEY_KANA, KEY_CONVERT, KEY_NOCONVERT,
KEY_AT, KEY_CIRCUMFLEX, KEY_COLON2, KEY_KANJI,
KEY_LSHIFT, KEY_RSHIFT,
KEY_LCONTROL, KEY_RCONTROL,
KEY_ALT, KEY_ALTGR,
KEY_LWIN, KEY_RWIN, KEY_MENU,
KEY_SCRLOCK, KEY_NUMLOCK, KEY_CAPSLOCK
extern volatile int key_shifts;
Bitmask containing the current state of shift/ctrl/alt, the special
Windows keys, and the accent escape characters. Wherever possible this
value will be updated asynchronously, but if keyboard_needs_poll()
returns TRUE, you must manually call poll_keyboard() to update it with
the current input state. This can contain any of the flags:
KB_SHIFT_FLAG
KB_CTRL_FLAG
KB_ALT_FLAG
KB_LWIN_FLAG
KB_RWIN_FLAG
KB_MENU_FLAG
KB_SCROLOCK_FLAG
KB_NUMLOCK_FLAG
KB_CAPSLOCK_FLAG
KB_INALTSEQ_FLAG
KB_ACCENT1_FLAG
KB_ACCENT2_FLAG
KB_ACCENT3_FLAG
KB_ACCENT4_FLAG
int keypressed();
Returns TRUE if there are keypresses waiting in the input buffer. This is
equivalent to the libc kbhit() function.
int readkey();
Returns the next character from the keyboard buffer, in ASCII format. If
the buffer is empty, it waits until a key is pressed. The low byte of the
return value contains the ASCII code of the key, and the high byte the
scancode. The scancode remains the same whatever the state of the shift,
ctrl and alt keys, while the ASCII code is affected by shift and ctrl in
the normal way (shift changes case, ctrl+letter gives the position of
that letter in the alphabet, eg. ctrl+A = 1, ctrl+B = 2, etc). Pressing
alt+key returns only the scancode, with a zero ASCII code in the low
byte. For example:
if ((readkey() & 0xff) == 'd') // by ASCII code
printf("You pressed 'd'\n");
if ((readkey() >> 8) == KEY_SPACE) // by scancode
printf("You pressed Space\n");
if ((readkey() & 0xff) == 3) // ctrl+letter
printf("You pressed Control+C\n");
if (readkey() == (KEY_X << 8)) // alt+letter
printf("You pressed Alt+X\n");
This function cannot return character values greater than 255. If you
need to read Unicode input, use ureadkey() instead.
int ureadkey(int *scancode);
Returns the next character from the keyboard buffer, in Unicode format.
If the buffer is empty, it waits until a key is pressed. The return value
contains the Unicode value of the key, and if not NULL, the pointer
argument will be set to the scancode. Unlike readkey(), this function is
able to return character values greater than 255.
int scancode_to_ascii(int scancode);
Converts the given scancode to an ASCII character for that key, returning
the unshifted uncapslocked result of pressing the key, or zero if the key
isn't a character-generating key or the lookup can't be done.
void simulate_keypress(int key);
Stuffs a key into the keyboard buffer, just as if the user had pressed
it. The parameter is in the same format returned by readkey().
void simulate_ukeypress(int key, int scancode);
Stuffs a key into the keyboard buffer, just as if the user had pressed
it. The parameter is in the same format returned by ureadkey().
extern int (*keyboard_callback)(int key);
If set, this function is called by the keyboard handler in response to
every keypress. It is passed a copy of the value that is about to be
added into the input buffer, and can either return this value unchanged,
return zero to cause the key to be ignored, or return a modified value to
change what readkey() will later return. This routine executes in an
interrupt context, so it must be in locked memory.
extern int (*keyboard_ucallback)(int key, int *scancode);
Unicode-aware version of keyboard_callback(). If set, this function is
called by the keyboard handler in response to every keypress. It is
passed the character value and scancode that are about to be added into
the input buffer, can modify the scancode value, and returns a new or
modified key code. If it both sets the scancode to zero and returns zero,
the keypress will be ignored. This routine executes in an interrupt
context, so it must be in locked memory.
extern void (*keyboard_lowlevel_callback)(int scancode);
If set, this function is called by the keyboard handler in response to
every keyboard event, both presses and releases. It will be passed a raw
keyboard scancode byte, with the top bit clear if the key has been
pressed or set if it was released. This routine executes in an interrupt
context, so it must be in locked memory.
void set_leds(int leds);
Overrides the state of the keyboard LED indicators. The parameter is a
bitmask containing any of the values KB_SCROLOCK_FLAG, KB_NUMLOCK_FLAG,
and KB_CAPSLOCK_FLAG, or -1 to restore the default behavior.
void set_keyboard_rate(int delay, int repeat);
Sets the keyboard repeat rate. Times are given in milliseconds. Passing
zero times will disable the key repeat.
void clear_keybuf();
Empties the keyboard buffer.
extern int three_finger_flag;
The djgpp keyboard handler provides an 'emergency exit' sequence which
you can use to kill off your program. If you are running under DOS this
is the three finger salute, ctrl+alt+del. Most multitasking OS's will
trap this combination before it reaches the Allegro handler, in which
case you can use the alternative ctrl+alt+end. If you want to disable
this behaviour in release versions of your program, set this flag to
FALSE.
extern int key_led_flag;
By default, the capslock, numlock, and scroll-lock keys toggle the
keyboard LED indicators when they are pressed. If you are using these
keys for input in your game (eg. capslock to fire) this may not be
desirable, so you can clear this flag to prevent the LED's being updated.
|