Planet Nebula: The Personal Website of Jeff Weiner

Pages:


Portfolio: Advanced Console Library

This library makes it very easy to utilize some of the advanced features of C++ console windows. You can easily add color to your application, and you can move the cursor around the screen without changing what's already been output. Additionally, the screen can be partially or wholly erased. The library is cross-platform (both Unix/Linux and Microsoft Visual Studio libraries are provided), so you won't lock yourself into to one platform by using it.

I originally set out to write this library for a class I taught (Intermediate C++) in the summer of 2008 for Camp CAEN, a summer camp at the University of Michigan's engineering school. Having previously taken the course before as a student, I tried to think of ways I could enable the kids to make more interesting final projects without too much extra hassle. Final projects for the course had typically involved boring text-based RPGs, and I felt like it was time for something new. This library was easy enough for middle-/high-school aged children to use, and the kids really seemed to appreciate it. On a completely unrelated note, the final projects for 2008's Intermediate C++ class were far more interesting than any of the previous year's projects, if I do say so myself.

To use the library, you first need to ensure advconsole.cpp and advconsole.h are in your C++ project's build path. Second, you need to add the platform-specific version of the library to the build path as well (only one!):

The library provides three interfaces (technically four, but I've never had a chance to figure out if the last one really worked well...or at all). The four interfaces are the Color(), Cursor(), and Erase() objects (as well as the Scroll() object; more on this later). Once one of the above objects has been created, simply send it to your output stream (cout) like you would any other data you wanted to display.

The Color Interface

The Color interface allows for eight colors: red, green, blue, yellow, cyan, magenta, black, and white. You can specify the color to apply to the foreground or the background. Additionally, for foreground text, you can specify if you want the text to be bolded (though the effect isn't as pronounced as you might hope for). Color names are named AC_X, where X is the name of the color (in all caps). Similarly, the layer selection is either AC_FOREGROUND or AC_BACKGROUND, and font weight provided through either AC_NORMAL or AC_BOLD. Two Color object constructors are provided:

Example Usage

Cursor Example Output
Example Output
#include <iostream>
#include "advconsole.h"
using std::cout; using std::endl;
using namespace AdvancedConsole;

int main()
{
    cout << "Normal text" << endl;
    cout << Color(AC_RED) << "Red" << Color() << " text" << endl;
    cout << Color(AC_YELLOW) << Color(AC_BLUE, AC_BACKGROUND) << "Yellow on Blue text" <<
        Color(AC_DEFAULT, AC_BACKGROUND) << endl;    // Needed to reset bg color
    cout << Color(AC_GREEN, AC_BOLD) << "Bold" << Color() << " text" << endl;
    return EXIT_SUCCESS;
}

The Cursor Interface

The Cursor interface is a bit more straightforward. You can move the cursor to an absolute position (AC_ABSOLUTE) on the screen, or you can move the cursor relative to its current position (AC_RELATIVE). The screen's upper left coordinate is (1, 1), not (0, 0). Only one Cursor constructor is provided:

Example Usage

Cursor Example Output
Example Output
#include <iostream>
#include "advconsole.h"
using std::cout; using std::endl;
using namespace AdvancedConsole;

int main()
{
    cout << "This library sucks!" << Cursor(0, -6, AC_RELATIVE) << "ro" << endl;
    cout << Cursor(3, 10) << "Look ma', no spaces!" << endl;
    return EXIT_SUCCESS;
}

The Erase Interface

The Erase interface is also rather straightforward. You can choose to erase everything before (AC_BEFORE) or after (AC_AFTER) the cursor, as well as the entire (AC_ALL) screen all at once. Additionally, you can also specify to only operate on the current line (AC_LINE), instead of the whole screen (AC_SCREEN). Again, only one Erase constructor is provided:

IMPORTANT: The Visual Studio library implementation will unconditionally erase the entire screen. I got tired of surfing Microsoft's Console API specifications, and didn't bother to finish, since it seems people never want to do more than erase the whole screen.

The Scroll "Interface"

I must admit, I'm not entirely sure how the scroll interface is supposed to work. I assume the Unix version works, since I think I implemented it correctly according to the ANSI technical documents I read over. However, it was more of an "oh, this looks interesting" type of thing that I never ended up trying to use. As a result, I make no guarantee as to how it actually works. Consider it experimental.

The Scroll interface allows you to specify both a number of lines to scroll, as well as which direction to scroll in, either up (AC_UP) or down (AC_DOWN). As such, there's (again) only one constructor provided:

IMPORTANT: Given my shakiness with this interface that I mentioned earlier, I didn't even bother trying to port it to the Visual Studio implementation. Sigh.

Implementation Details

The Unix/Linux port is programmed using standard ANSI escape code sequences, and should work without a problem using any terminal emulator that supports the given control sequences. My guess is that you'll need to try to look pretty hard to find a terminal that doesn't support them, so I wouldn't worry about that. If you're really interested, there's an extremely detailed page that has more information than you ever wanted on various escape code sequences used throughout computing history.

The Microsoft Visual Studio port is written to use the Windows Console API, since it doesn't support the escape sequences used in the Unix/Linux version (ignoring ANSI.SYS, which was a MS-DOS thing). As mentioned earlier, there's full support for the Color and Cursor interface, but I didn't have time to finish the Erase interface, or to begin the Scroll interface. If this is a problem, then please let me know, and I'll see what I can do about finishing up the Windows port (since I probably should anyways).

Screenshots

Windows Vista
Mac OS X