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 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 . 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 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 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