C Programming Lessons

TIGCC Programming Lessons

The following is part of a series of lessons designed to help teach
people to program in C for the TI-89, 92+, and V200 calculators
using the TIGCC development environment.

If you wish, you can download the program source code, project
files, and binaries
here.

Lesson 2 - Basic Keyboard Input

Step 1 - The Basics of Keyboard Input

Keyboard input is probably the most basic need of any program, and it is
especially so it for calculator programs.

There are several ways to read keyboard input using TIGCC, but we will
start with the simple ones, and cover others in future lessons. The ones
we will cover today are the ngetchx() function (for reading key
presses), the kbhit() function (for testing whether or not keys have
been hit), and the faster, but more advanced OSdequeue() function for
reading key presses directly from the keyboard buffer.

Step 2 - The ngetchx() function

Start TIGCC and create a new project. The project should be created just
like the project we made in lesson one. Create a new C Source File named
waitkey and replace the contents with the following.

Build the program by using the Project, Make menu item and send it to
TiEmu. It will look similar to following screenshots, though they are
from an older slightly modified version of this example.

Step 2b - Analyze the Program

This program is fairly straightforward, except for the while loop in the
middle. If you have programmed before, it should be easy enough to
understand, but we will go over each line in detail.

// keypress variable
int key;

This is a variable declaration. As the name implies, variables are used
in programs to store values which can change. In this case, we need to
store an integer value. In C, we use an int variable for this. Variable
declarations come in the form type name;. Multiple variables can be
declared by separating the names by commas. We can also assign initial
values by using an = [some value] after the name. We will see examples
like this later.

The clrscr function is similar to the ClrScr function we used in the
first lesson (note the change in capitalization). However, they are not
the same. clrscr is a special function in the TIGCC library which is
used in conjunction with certain screen I/O functions.

The next function is one of those special I/O functions that is helped
by clrscr. printf is similar to the DrawStr function, but is a bit
more versatile. Notice we did not need to tell it where to print our
string. This is because the TIGCC library keeps track of screen position
so that printf can handle screen wrapping and scrolling. The clrscr
function actually resets this screen position to 0,0, which is why the
string is printed at the top left.

The end of the string has a funny little part, the '\n' character. This
is a special character, called an escape sequence. It represents a
newline. When printf sees a '\n' character, it will adjust the screen
position to the next line. You probably noticed this behavior in the
screenshots.

Remember to use clrscr to clear the screen if you want to use printf.

// wait for the ESC key to be pressed
while ((key = ngetchx()) != KEY_ESC) {
printf("That's not the ESC key.\n");
}

This is the core of the program, and obviously the most complex part.
The first statement is the beginning of a while loop, one of the control
instructions in C. while performs looping, so we can do certain commands
more than once until we get the result we want. The format of a while
loop is while (condition) { do something }, which means while
this test is true, do everything within the braces.

Our condition has a lot of things going on simultaneously. It helps to
have an understanding of operator precedence. Just as you probably
learned in algebra, do the things inside parentheses first, and if you
have nested parentheses, do the inner-most and work your way out.
Finally, we work left to right (in most cases). We will discuss operator
precedence in more detail when it comes into play.

Using our basic understanding, we can gather that we will be doing the
(key = ngetchx()) first. Whatever the result of that is, we will take
that and see if it is != KEY_ESC, whatever that means.

The first part is simple, the key variable will get the value of
ngetchx(). ngetchx() is a function that waits for a key to be pressed,
and then returns the value of that key press. All the keys on the
keyboard (other than the ON button) have a unique key code.

Now we come to the != part. != is C syntax for "not equal". So, the long
while condition is testing whether the value of the key press that we
got from ngetchx() and put into the key variable is not equal to
KEY_ESC. KEY_ESC is a TIGCC defined constant for the key code of the ESC
key. It was included in our tigcclib.h include line.

So, what does our conditional statement say? Call the ngetchx() function
and assign the returned value to the variable key. If the value we just
stored in key is not equal to the key code value of the ESC key, then
do all the code inside the while loop. So, until the user presses the
ESC key, the program will keep executing the body of the loop contained
within the braces.

The body of the while loop is just another printf function call.

// display the final string
printf("You pressed ESC.\n");
// wait for user input before exiting the program
ngetchx();

After we have pressed the ESC key and the while loop stops, we print
another string and wait for a key press before exiting the program.

Step 2c - Programmatic Conclusions

ngetchx() is quite useful, but it has definite drawbacks. First, and
probably foremost for most programmers is that it waits until a key has
been pressed before returning. This is a big problem for game
programming where you need to do other things besides check for keys.
To handle these situations, ngetchx() will not work. So let's explore
some alternatives.