This sample program demonstrates the use of the BIOS functions from the CONIO.H library and how they can be use to create fast action programs.
/* FastKey.C -- Demo on how CONIO.H functions can permit * fast action programming. * * by Gary Neal Jr. */ #include <conio.h> /* Console I/O functions */ #include "vmode.h" /* Video functions */ int main(void) { int X, Y, C, OldPixel, done = 0; int xdir = 0, ydir = 0; direct_video = 0; /* CONIO functions uses BIOS for output */ if (!SetVideoMode(VGA256)) { cprintf("Could not initialize VGA.\r\nAborting..."); return 1; } X = 160; Y = 100; C = 15; gotoxy(5, 0); cputs("Press [SPACE] to change color."); gotoxy(10, 20); cputs("Press [ESC] to quit."); while (kbhit()) getch(); while (!done) { if (kbhit()) { switch (getch()) { case 27: done = 1; break; case ' ': C = (++C) % ScreenColors; break; case '\0': { switch (getch()) { case 72: ydir = -1; xdir = 0; break; case 80: ydir = 1; xdir = 0; break; case 75: xdir = -1; ydir = 0; break; case 77: xdir = 1; ydir = 0; break; } } } } SetPixel(X, Y, OldPixel); X += xdir; Y += ydir; if (X >= ScreenWidth) X = ScreenWidth - 1; else if (X < 0) X = 0; if (Y >= ScreenHeight) Y = ScreenHeight - 1; else if (Y < 0) Y = 0; OldPixel = GetPixel(X, Y); if (!C) SetPixel(X, Y, 15); SetPixel(X, Y, C); } SetVideoMode(TEXT_MODE); return 0; }
This is a nice little way to use the keyboard to control the action in your programs. After a while though, you'll encounter some subtle problems with this type of interface.
The program relies on the keyboard buffer, so if you were to hold down one of the direction keys the keyboard buffer will likely fill up. This will cause your computer to make those annoying little blips of sound indicating that the buffer is full. Also, this program can only process a single key at a time. This may not be a problem since it would pick off each key from the buffer at every cycle of the loop. However, what if you desired to have the program process both the up and left arrow keys at once to indicate a northwest diagonal move? In addition to that, the 'kbhit' and 'getch' functions only interpret key presses and returns the ASCII or control codes, key releases are not processed by these functions. If you ran the sample program you would've noticed that once you pressed and released a directional key, the dot follows Newton's law of motion. That is once set in motion, it stayed in motion until either another key was pressed or the pixel reached the edge of the screen. One possible solution to this is to set up another key to act as a stop key, such as the spacebar. A player would press the directional key to move and the spacebar to stop. However, game players aren't accustomed to using another key press to stop their game character. Think about it, when you are playing a game, you would normally press and hold a directional key to move and release it to stop, not press another key to stop.
Clearly what is needed is a more direct approach to processing the key strokes. More direct access to the keyboard is required and is not available with any of the CONIO functions as well as the BIOS functions that they call. A better approach is to somehow store the state of all the keys on the keyboard and to read them on demand. A flag indicating whether or not a key is being pressed or released would be ideal. None of the BIOS functions will give you this so we have to create our own and in order to do this, we need to investigate how the keyboard actually works.
Send your questions, comments, or ideas here.