Saturday, April 12, 2014

aclib - Getting Started

ACLib is a library that provides extra functionality to the Windows Console using C#.

It was written to meet a demand for writing unicode text to the output buffer of the console, but it expanded to allow access to the input buffer as well.

Because the library makes kernel32 calls directly (via pinvoke), it breaks the functionality of the original System.Console API.

Differences in functionality

This area is a little technical and isn't really required to understand how to use ACLib.

ACLib's functionality is written to mimic libraries like SDL or OpenGL, as it was written to primarily provide advanced drawing functionality. This means it works in a flipping-buffer manner; you write changes to a buffer, then 'swap' the buffer to write it to the console in one go.

I tried to mimic the functionality of the original System.Console API as much as possible, but there are inherit differences between them.

ACLib does not write to the console in a streamed manner; the library doesn't seek to a position before writing data. Instead, the backbuffer is basically an array of character structures that contain character and color data. This means that writing to the buffer is done by simply calculating the offsets for each character, and changing the data at the calculated index of the buffer. This should be faster than sequentially writing to a stream.

Unfortunately this means that the functionality of the System.Console API is broken and/or unpredictable after ACLib is initialized, as there will be two references to the console's IO buffers and their methods of handling the buffer's data are different.

Setting up our program

Enough of the details; Lets write some code!

Seeing as how ACLib only works with windows (as it uses kernel32 windows calls), we'll be using some version of Visual Studio. If your favorite IDE can handle creating a windows console project, feel free to try using that! I'm generally uneducated about alternative C# IDEs.

Lets start out by writing a little test application for ourselves. Create a new Console Application project, name it whatever you want.

Make sure to add a reference to aclib.dll.

You should end up with a standard Main entry point...


static void Main(string[] args)
{
}

Lets define a static bool to use with a while loop; If its set to true the program will continue to run, and similarly if its set to false the program will end.

static bool running = true;

Now, we'll need to define two methods, Update and Draw. Because we're writing them to be called directly from the Main entry point, everything will have to be static. Alternatively (and optimally), you can write this into a class to be instantiated and run from there, but i'll keep this as straight-forward as possible.

static void Update() { }

static void Draw() { }

Next, we'll return to the Main method and define a while loop to call Update and Draw respectively, which loops as long as "running" is true.

static void Main(string[] args)
{           
    while (running)
    {
        Update();
        Draw();
    }
}

What we've just done is defined the framework for how our ACLib application will function; Any logic that doesn't involve drawing will be called in the Update function (this includes input), and code that involves drawing will be called in the Draw function.

Note: There probably isn't a reason you couldn't collapse these down into a single function, but for cleanliness I like to separate the two into respective functions. It keeps you from drawing before processing logic, and its easier to debug.

Initializing ACLib

Next we'll initialize ACLib. This is done in one call to AdvConsole.Init().
There are a few overloads for Init(), the one we'll use will let us define the name of the window and its dimensions in characters.

AdvConsole will need to be initialized before any other calls are made! Because of this, we'll call it before our loop begins.

static void Main(string[] args)
{
    AdvConsole.Init("ACLib Test", 100, 40); 
  
    while (running)
    {
        Update();
        Draw();
    }
}

Now that we've initialized ACLib, we are able to use it to poll the input and write to the output buffer.

At this point, you can run the program and confirm that things are working. You should be presented with a black console window of the size specified in your Init() line, and the window should have the title specified as well!

We're not really done though; Lets show that its actually doing something worth while by making a ClearScreen() call in our Draw function.

ClearScreen() fills the screen with empty characters, with a background color specified in your call.

static void Draw()
{
    AdvConsole.ClearScreen(AdvConsoleColor.DarkBlue);
}

Running the application at this point will not reflect any changes. As stated in the Differences in functionality section, ACLib works in a swapping-buffer method. This means that writing to the buffer does not mean applying the buffer to the console.

All we have to do to apply the buffer is call SwapBuffers().

static void Draw()
{
    AdvConsole.ClearScreen(AdvConsoleColor.DarkBlue);

    AdvConsole.SwapBuffers();
}

Ta da! When running the program, you should now be presented with a console window, set to the specified size and title in the Init() line, and now filled with color specified on the ClearScreen() line.

So now we have the absolute bare minimum required to start using ACLib. Feel free to experiment with it until the next tutorial.

Next time we'll look at basic use of input.