Annex Solutions Foundation Classes Documentation Vs. 1.01 (10/27/2002) Written By: Andy Stone
ASFC By: Andy Stone (astone42@attbi.com), Eoin Coffey (eoin@angrystickman.com) Visit: http://loreandlutes.sourceforge.net for more information. See copying.txt or copying for licensing information.


Changes (Document Versions):

1.0: Initial document.
1.01: Fixed some dumb spelling mistakes, re-worded a few things so they

sound better.

What ASFC is:

ASFC is the module L&L uses for drawing graphics. AFC handles more than just Graphics though. It includes several nice features such as container objects (Linked lists), string conversion functions, fonts, and several classes that C++ programmers trying to make cross-platform games might find handy. ASFC is built on SDL, so it will compile and run on any platform SDL runs on. ASFC is independent of Lore And Lutes, so if you're a game programmer you might find it useful. Currently ASFC can not\will not compile under MS Visual C++, without modifying the include files for MSVC++ to work with ANSI C++, I don't know how to do this so don't ask. But it works fine under G++, cygwin running G++, mingwin if you're programming in Windows, and several other compilers. There are no plans to make it support MSVC++ since that compiler can't compile ANSI C++ code that uses STL. If you'd like to take a look at ASFC download the L&L source code and look in the src/asfc directory, it's all in there.

Current State Of ASFC:

Currently ASFC is in its very late Alpha stages meaning that 99% of the information in this document will still apply when ASFC gets to its release version. Nothing is planned to be changed or removed but new features will be added. Also ASFC is rather buggy but it does work and in my development I've found ASFC to be a very useful lib. ASFC will probably be in to its beta development in a few months (but don't take my word for it).

Headers for objects:

Whenever you want to create an instance of an ASFC object make sure that you include the appropriate header or else you'll get errors. The following are the headers you'll need:
Header             For
------             ---
animation.h        ASFC_Animation
console.h          ASFC_Console
font.h             ASFC_Font
fontpalette.h      ASFC_FontPalette
input.h            ASFC_Input
linkedlist.h       ASFC_LinkedList
matrix.h           ASFC_Matrix
mousepointer.h     ASFC_MousePointer
multiimage.h       ASFC_MultiImage
screen.h           ASFC_Screen
surface.h          ASFC_Surface
timer.h            ASFC_Timer
utils.h            ASFC_Utils

In this documentation I'll assume that all ASFC headers are in a subfolder called ASFC in your include path. So, for example, to include the header animation.h you'd do this:

#include <asfc/animation.h>

If you're programming in Windows whenever including headers please be careful to not capitalize any letters! Although it may compile and work under windows it might now compile and work fine in other operating systems. This is because most posix OSs have case sensitive files and windows does not.

ASFC and SDL

Since ASFC uses SDL most, if not all, SDL functions will work in a project that uses ASFC. For example you may want to use the SDL_WM_SetCaption() function to set the caption on your windows. ASFC wraps a lot of SDL into C++ functions but it doesn't wrap all of 'em. For more information about SDL visit <http://www.libsdl.org>.

The ASFC classes

ASFC is object oriented so it includes several classes for a game programmer (you) to use. These classes are explained in detail within this document. I suggest that whenever you use an ASFC class you open its header (.h) file and take a look at all the public members. This is a good way to learn all about ASFC. The ASFC classes are:
ASFC_Animation:     Used for creating raster (non vector) animations.
ASFC_Console        Used for displaying graphical text in a console like
                    interface. It works simliarish to cout.
ASFC_Font           A graphical font object.
ASFC_FontPalette    Aggregates (holds) several font objects. Console objects
                    realize (point to) font palette objects.
ASFC_Input          Handles keyboard and mouse input.
ASFC_LinkedList     A templated linked list container class.
ASFC_Matrix         A 2d Linked List.
ASFC_MousePointer   Loads a mouse pointer from a text (.cursor) document.
ASFC_MultiImage     An image object that parses itself into periodic smaller
                    images. A multiimage file (.png, .bmp, etc.). Looks like
                    a strip of images.
ASFC_Screen         An ASFC_Surface that will draw its contents to the screen
                    whenever the Update() member is called.
ASFC_Surface        Holds graphical data.
ASFC_Timer          Handles timing, counts milliseconds.
ASFC_Utils          Not a class, but includes several handy macros and
                    functions.

Intro to ASFC_Screen:

ASFC_Screen is an ASFC_Surface object that will display its contents on to the computer screen, usually within a window. To create a new screen simply pass the constructor the width and height of the window you want to create and the # of bits per pixel (8, 16, or 32). You should always create a screen object before performing any other graphical function. The ASFC_Screen is doubled buffered, meaning whenever you want to update the screen (transfer everything in ASFC_Screen to the screen) call the Update() member.

//Create a new ASFC screen object that's 640x480x32

ASFC_Screen screen(640, 480, 32);

If you want your game to appear in full screen then add the parameter 'true' after the bits per pixel (bpp) parameter in the constructor. For example:

//Create a new ASFC screen object that's 640x480x32 and in full screen mode.

ASFC_Screen screen(640, 480, 32, true);

ASFC_Surface:

An ASFC surface is simply an object that contains graphical data. The screen is an ASFC_Surface object that is mapped so when its Update() member is called it will be displayed on the screen.

Primitive Surface Functions:

The ASFC_Surface class includes several graphics primitives functions. For most primitive functions you pass a location on the surface and a color. The 'r' 'g' and 'b' variables represent the red, green, and blue values of the color. The 'a' variable is the alpha byte and represents how translucent to draw this primitive. If you want a pure opaque primitive set a to 255 (hex 0xFF).

//Primitives
int DrawPixel(int x, int y, int r, int g, int b, int a); int DrawLine (int x1, int y1, int x2, int y2, int r, int g, int b, int a); int DrawRectangle(int x, int y, int width, int height, int r, int g, int b, int a); int DrawFillRectangle(int x, int y, int width, int height, int r, int g, int b, int a); int DrawCircle(int x, int y, int radius, int r, int g, int b, int a); int DrawFillCircle(int x, int y, int radius, int r, int g, int b, int a);

Example: Drawing Random Rectangles:

The following example will draw several (6000 actually) random rectangles across the screen.

int main(int argc, char *argv[])
{

//First we have to initialize ASFC screen, we'll set it to be 640x480x32 ASFC_Screen screen(640, 480, 32);

//Loop 6000 times

        for(int i = 0; i < 6000; i++)
        {
            screen.DrawFillRectangle
            (
                 rand() % 640, rand() % 480,
                 rand() % 150, rand() % 150, rand() % 255, rand() % 255,
                 rand() % 255, rand() % 255
            );

          if(i % 50 == 0)
               screen.Update();

}
//You haven't learned ASFC_Input yet but it will just pause until space is depressed

        ASFC_Input input;
        while(input.KeyUp(SDLK_SPACE)) input.Update();

}

Taking advantage of images

In most games you'll probably want to load some sort of image. ASFC can load and draw .PNG, .JPEG, .BMP, and several other common image formats. To load an image onto an ASFC surface use the LoadImage member. All data in the image file will be transferred to the surface.

LoadImage(string file, int transred = -1, int transgrn = -1, int transblu = -1);

Example (load image "test.png" into a surface called surface and make all blue pixels transparent)

ASFC_Surface surface;
surface.LoadImage("test.png", COLOR_BLUE);

If you don't want your image to have any transparent pixels pass -1 to the transparency parameters.

Transferring data from one surface to another

Once you load an image into a surface you may want to copy it into another surface, namely the screen. To do this either use the Blit() or BlitTo() members. The Blit() member takes an ASFC_Surface and copies that surface onto itself. The BlitTo() member takes an ASFC_Surface and copies itself onto the surface passed. The sx, sy, w, and h parameters specify which part of the image to blit. You can change them to crop an image. By default sx, sy, w, and h

Example: (Take surface and blit it to the screen at 50, 50): surface.BlitTo(screen, 50, 50);

Other Surface functions:

SDL_Surface *GetSurface() Returns the ASFC_Surface as an SDL_Surface
int GetWidth()             Gets the width of this surface
int GetHeight()            Gets the height of this surface
int GetBpp()               Gets the BPP of this surface

MultiImage Objects:

An ASFC_MultiImage object loads a single image file and parses it out into several smaller images. To load a multi image use the load member, pass it the X block and Y block size which specify the size of each periodic smaller image. When you want to blit a multiimage to another surface use the BlitTo member just like you would for a regular surface but pass it an extra parameter specifying which smaller image (sub image) you wish to blit. To find the # of smaller images in a multiimmage use the NumImages() member.

Animation Objects:

An ASFC_Animation object is like a multiimage but you don't pass which smaller image you want to blit when using the BlitTo() member. Rather the animation object will blit which ever frame the animation is on. When you want to update your animation, setting it so on the next blit it'll blit the next frame, call the Reset() member.

Handy Dandy Utils:

MEMVAR_

ASFC includes a header called utils.h that contains several macros. It's important that you understand at least a few of these since they appear over and over in the ASFC source code. The most important macros are the MEMVAR_ macros. The MEMVAR_ macros automatically create a member (for a class) that maps to a variable. Generally the name of the member function to me created, the variable type, and the variable are passed to MEMVAR_ macros. The MEMVAR_SETGET macro gets passed to values for the member functions to be created. One for the Set member and the other for the get.

MEMVAR_SET: Creates a member that sets a variable. MEMVAR_GET: Returns a member that returns a variable MEMVAR_SETGET: Combines both of the above macros into one creating two members. MEMVAR_LINK: Creates two members that overload eachother one for setting

another for getting.
MEMVAR_GETREF: Creates a function that returns a variable by reference.

Example:

#include <asfc/utils.h>

class ASFC_TestClass
{
private:
int iValue;

public:
MEMVAR_SETGET(SetVal, Val, int, iValue); }

int main()
{
ASFC_TestClass test;

for(int i = 0; i < 10; i++)
{
test.SetVal(i);
cout << test.Val() << " ";
}

return 0;
}

Output:
0 1 2 3 4 5 6 7 8 9

Color Constants

There are several nice macros that are used to enter color values into ASFC functions such as the primitive members for ASFC_Suface. These macro constants are:
COLOR_RED                           0xff, 0x00, 0x00
COLOR_GREEN                         0x00, 0xff, 0x00
define COLOR_BLUE                   0x00, 0x00, 0xff
COLOR_YELLOW                        0xff, 0xff, 0x00
COLOR_PURPLE                        0xff, 0x00, 0xff
COLOR_CYAN                          0x00, 0xff, 0xff
COLOR_GRAY                          0x7f, 0x7f, 0x7f

#define COLOR_LIGHT_RED             0xff, 0x7f, 0x7f
#define COLOR_LIGHT_GREEN           0x7f, 0xff, 0x7f
#define COLOR_LIGHT_BLUE            0x7f, 0x7f, 0xff
#define COLOR_LIGHT_YELLOW          0xff, 0xff, 0x7f
#define COLOR_LIGHT_PURPLE          0xff, 0x7f, 0xff
#define COLOR_LIGHT_CYAN            0x7f, 0xff, 0xff
#define COLOR_LIGHT_GRAY            0xbf, 0xbf, 0xbf

#define COLOR_DARK_RED              0x7f, 0x00, 0x00
#define COLOR_DARK_GREEN            0x00, 0x7f, 0x00
#define COLOR_DARK_BLUE             0x00, 0x00, 0x7f
#define COLOR_DARK_YELLOW           0x7f, 0x7f, 0x00
#define COLOR_DARK_PURPLE           0x7f, 0x00, 0x7f
#define COLOR_DARK_CYAN             0x00, 0x7f, 0x7f
#define COLOR_DARK_GRAY             0x3f, 0x3f, 0x3f

#define COLOR_GRAY_0                0x00, 0x00, 0x00
#define COLOR_GRAY_1                0x10, 0x10, 0x10
#define COLOR_GRAY_2                0x20, 0x20, 0x20
#define COLOR_GRAY_3                0x30, 0x30, 0x30
#define COLOR_GRAY_4                0x40, 0x40, 0x40
#define COLOR_GRAY_5                0x50, 0x50, 0x50
#define COLOR_GRAY_6                0x60, 0x60, 0x60
#define COLOR_GRAY_7                0x70, 0x70, 0x70
#define COLOR_GRAY_8                0x80, 0x80, 0x80
#define COLOR_GRAY_9                0x90, 0x90, 0x90
#define COLOR_GRAY_A                0xa0, 0xa0, 0xa0
#define COLOR_GRAY_B                0xb0, 0xb0, 0xb0
#define COLOR_GRAY_C                0xc0, 0xc0, 0xc0
#define COLOR_GRAY_D                0xd0, 0xd0, 0xd0
#define COLOR_GRAY_E                0xe0, 0xe0, 0xe0
#define COLOR_GRAY_F                0xf0, 0xf0, 0xf0

#define COLOR_BLACK                 0x00, 0x00, 0x00
#define COLOR_WHITE                 0xff, 0xff, 0xff

//Oranges & Browns

#define COLOR_ORANGE                0xff, 0x80, 0x00
#define COLOR_LIGHT_ORANGE          0xff, 0xbf, 0x80
#define COLOR_DARK_ORANGE           0xbf, 0x5f, 0x00

#define COLOR_BROWN                 0xa5, 0x7b, 0x48
#define COLOR_LIGHT_BROWN           0xa5, 0x93, 0x7c
#define COLOR_DARK_BROWN            0x59, 0x45, 0x2c

Example (Create a red rectangle)
screen.DrawFillRectangle(0, 0, 50, 50, COLOR_RED, 0xFF)

Functions

Utils includes some nice helper functions that don't really fit anywhere else but are useful :-).
string UpperString(string s)          Returns s in all caps.
string Val(double d);                 Converts a value to a string.
double Val(string s);                 Converts a string to a value.
string Rot(int iChars, string s);     Rotates all the chars iChars down in a
                                      string. The most basic encryption
                                      algorithm that can be done.
void SToStr(string s, char* str);     Converts a C++ string to an C string
string Qoute(string s);               Returns string s surrounded with qoutes.
string ReadString(ifstream &oFile);   Reads in a string surrounded by double.
                                      qoutes, a la from the Qoute() member,
                                      from an ifstream.
bool FileExist(string sFile);         Returns true if sFile exists.

The utils.h header also includes several more constants and macros. I suggest you take a look at it it's really scary ;-).

ASFC_Timer

The ASFC_Timer class provides members for returning ellapsed time since the Reset() member was called.
void Reset()                           Reset the # of milliseconds ellapsed.
void Delay(long lMilliseconds);        Pauses until lMilliseconds of time have
                                       ellapsed since the last reset.
bool Ellapsed(long lMilliseconds);     True if lMilliseconds of time have
                                       ellapsed.
long Ellapsed();                       Returns the # of mills ellapsed since
                                       Reset() was last called.

Example (Wait 100 milliseconds):

ASFC_Timer oTime;
oTime.Reset();
oTime.Delay(100);

Make sure you use the reset member before calling Delay or else you may hang your system.

Linked List and Matrix

ASFC includes two templated container classed ASFC_LinkedList and ASFC_Matrix. To use the ASFC_LinkedList use the Push() member when you want to add a piece of data to the list, Pop() or Delete() when you want to remove data, and the [] operator when you want to read or change data. You can also use the Resize() member to resize the list.

void Resize(int iNewLength); Resize the list to iNewLength elements void Resize(int iNewLength, T &zDefault); Resize the list to iNewLength elements, fill them with zDefault

void Push(T zWhat);                         Push zWhat on to the end of the list
void PushFront(T zWhat);                    Push zWhat on to the front of the list
void AddElement(int iElement, T zWhat);     Add element zWhat after element # iElement
T    ReadLast();                            Read the last element
T    Pop();                                 Read and remove the last element
T&   operator[](int iElement);              Return element iElement
int  Length();                              Return the # of elements
void Delete(int iElement);                  Remove element # iElement

An ASFC_Matrix class works simliarly except when resizing you pass it a length and height and you use two [][]s to access data. For example:

ASFC_Matrix<string> matrix;
matrix.Resize(3, 3);
matrix[1][1] = "1, 1";

Fonts

A font object is a multi image mapped where each smaller image is mapped to a character. The multi image must follow a very strict pattern (e.g. the letters have to be in the right order). To learn this order simply open up a font image /font/normal_console_font.png for example and take a look. You can load a font with the ASFC_Font::Load() member and you can draw text with the WriteTo() member. The fonts that come with ASFC all have a block size of 8x14 and have a blue background.

Example: (Load font normal_console_font and write hello world on the screen:

ASFC_Font font;
font.Load("fonts/normal_console_font.png", 8, 14, COLOR_BLUE) font.WriteTo(screen, 50, 50, "Hello, World!");

Font Palette

A font palette is simply a linked list of fonts. To add a font either Push() a font object onto the list or call AddFont() and pass a string to the font's image. Font palettes are used for console classes.

Example: (Create a font palette with the fonts normal_console_font.png and runic_console_font.png)

ASFC_FontPalette palette;
palette.AddFont("./fonts/normal_console_font.png", 8, 14, COLOR_BLUE); palette.AddFont("./fonts/runic_console_font.png", 8, 14, COLOR_BLUE);

Console

A console class creates a graphical console that works similarly to the C++ iostream extern cout. To Draw the console call the Draw() member. To write data pass it with the << operator like you would with cout or call the Writeln() or Write() members. Consoles are linked to font palettes with the SetFontPalette() member and are linked to the screen with the SetSurface() member.

Example:
ASFC_FontPalette palette;
palette.AddFont("./fonts/normal_console_font.png", 8, 14, COLOR_BLUE); palette.AddFont("./fonts/runic_console_font.png", 8, 14, COLOR_BLUE);

ASFC_Console con;
con.SetFontPalette(&palette);
con.SetSurface(&screen);

con << "Testing Console\n";
con.Draw();

screen.Update();

You can also grab input for the string, double, and int data types by using the >> operator.

Example:
string s;
con >> s;
con << "\nYou just typed: " << s << "\n";

Other Console Notes:

The endl constant doesn't work the console class, however using a string containing an end line constant "\n" will work.

Input

The ASFC_Input class handles keyboard and mouse input for your game. It maps keyboard keys to SDLKey keyboard constants. A list of SDLKey constants is included in Appendix A, near the bottom of this document. See the SDL documentation for more information about key constants.

The KeyUp and KeyDown members are probably the most useful in games. The return true if the passed SDLKey is up or depressed. Before polling for keyboard input its generally a good idea to call the Update() member which rechecks the keyabord for its state. If you forget to do this you may get some errors. The GetMouseX(), GetMouseY(), and GetMouseButton() members handle mouse input.

Exampple (Draw info about mouse input while escape isn't depressed)

ASFC_Input input;
int loops = 0;
while(input.KeyUp(SDLK_ESCAPE))
{

//Display curret key info

      cout << loops << ": " << input.GetMouseX() << " "
           << input.GetMouseY() << endl;

input.Update();
}

The GetKey() members will poll the keyabord for any depressed key and will return the first depressed key found. There are two versions:

SDLKey GetKey();
int GetKey(bool fRefreshData, int iKeyDelay, int iRepeatRate);

The second version will return the SDLKey (as an int) based on certain timing information. For example:

GetKey(false, 200, 200);

will only return a key if 200 milliseconds have passed. This member is nice when you want to handle keyboard input like a text editor.

MousePointer

The mouse pointer class is pretty simple. It changes the image used for the cursor based on data it reads from a .cursor file. Simply call the Load() member to load a cursor and then call the Set() member when you want to set the current pointer to be this one. A .cursor file contains two ints at the top for the cursors hot spot (where clicks are registered) and a 32x32 image of what the cursor will look like. In the image any time a 'X' is encountered it represents a black pixel, '.' represents a blank (transperent) pixel, and '#' represents a white pixel.

Example cursor file (cursor.cursor):

0 0

X...............................
XX..............................
X#X.............................
X##X............................
X###X...........................
X####X..........................
X#####X.........................
X######X........................
X#######X.......................
X########X......................
X#####XXXXX.....................
X##X##X.........................
X#X.X##X........................
XX..X##X........................
X....X##X.......................
.....X##X.......................
......X##X......................
......X##X......................
.......XX.......................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................
................................

Example Code:

ASFC_Cursor cursor;
cursor.Load("cursor.cursor");
cursor.Set();

Effects

Effects is an up and coming class that will perform special effects on the screen.

Adding to this documentation

Currently there's a lot of information that could be added to this doc but hasn't been mostly because I'm busy coding :-). But if you have something that you think should be added, or if you use ASFC know just what this doc needs feel free to help me. E-Mail me, Andy Stone, at astone42@attbi.com. Also if you notice any dumb spelling or grammar mistakes that just stand out and bug you e-mail me where the are and I'll try to fix those too. Thanks.

Errors, Bugs, Questions, Comments?


E-Mail me (Andy) or Eoin:
Andy Stone (astone42@attbi.com)
Eoin Coffey (eoin@angrystickman.com)

Appendix A: SDLK Constants

SDLK_UNKNOWN
SDLK_FIRST
SDLK_BACKSPACE
SDLK_TAB
SDLK_CLEAR
SDLK_RETURN
SDLK_PAUSE
SDLK_ESCAPE
SDLK_SPACE
SDLK_EXCLAIM
SDLK_QUOTEDBL
SDLK_HASH
SDLK_DOLLAR
SDLK_AMPERSAND
SDLK_QUOTE
SDLK_LEFTPAREN
SDLK_RIGHTPAREN
SDLK_ASTERISK
SDLK_PLUS
SDLK_COMMA
SDLK_MINUS
SDLK_PERIOD
SDLK_SLASH
SDLK_0
SDLK_1
SDLK_2
SDLK_3
SDLK_4
SDLK_5
SDLK_6
SDLK_7
SDLK_8
SDLK_9
SDLK_COLON
SDLK_SEMICOLON
SDLK_LESS
SDLK_EQUALS
SDLK_GREATER
SDLK_QUESTION
SDLK_AT
SDLK_LEFTBRACKET
SDLK_BACKSLASH
SDLK_RIGHTBRACKET
SDLK_CARET
SDLK_UNDERSCORE
SDLK_BACKQUOTE
SDLK_a
SDLK_b
SDLK_c
SDLK_d
SDLK_e
SDLK_f
SDLK_g
SDLK_h
SDLK_i
SDLK_j
SDLK_k
SDLK_l
SDLK_m
SDLK_n
SDLK_o
SDLK_p
SDLK_q
SDLK_r
SDLK_s
SDLK_t
SDLK_u
SDLK_v
SDLK_w
SDLK_x
SDLK_y
SDLK_z
SDLK_DELETE

Numeric Keypad Keys:

SDLK_KP0
SDLK_KP1
SDLK_KP2
SDLK_KP3
SDLK_KP4
SDLK_KP5
SDLK_KP6
SDLK_KP7
SDLK_KP8
SDLK_KP9
SDLK_KP_PERIOD
SDLK_KP_DIVIDE
SDLK_KP_MULTIPLY
SDLK_KP_MINUS
SDLK_KP_PLUS
SDLK_KP_ENTER
SDLK_KP_EQUALS

Numeric keypad keys:

SDLK_UP= 273,
SDLK_DOWN= 274,
SDLK_RIGHT= 275,
SDLK_LEFT= 276,
SDLK_INSERT= 277,
SDLK_HOME= 278,
SDLK_END= 279,
SDLK_PAGEUP= 280,
SDLK_PAGEDOWN= 281,

Function keys:

SDLK_F1
SDLK_F2
SDLK_F3
SDLK_F4
SDLK_F5
SDLK_F6
SDLK_F7
SDLK_F8
SDLK_F9
SDLK_F10
SDLK_F11
SDLK_F12
SDLK_F13
SDLK_F14
SDLK_F15

Key state modifier keys:

SDLK_NUMLOCK
SDLK_CAPSLOCK
SDLK_SCROLLOCK
SDLK_RSHIFT
SDLK_LSHIFT
SDLK_RCTRL
SDLK_LCTRL
SDLK_RALT
SDLK_LALT
SDLK_RMETA
SDLK_LMETA
SDLK_LSUPER= 311     Left windows or penguin key
SDLK_RSUPER= 312     Right windows or penguin key
SDLK_MODE= 313       Alt Gr key on some international keyboards

SDLK_COMPOSE= 314

Misc. function keys

SDLK_HELP
SDLK_PRINT
SDLK_SYSREQ
SDLK_BREAK
SDLK_MENU
SDLK_POWER           Mac power key
SDLK_EURO= 321       On some european keyboards
SDLK_UNDO= 322       On Atari keyboards