Graphics

When I decided I want to develop this engine, I didn't know which file format would be good for this projects graphic. It should be store simple ASCII art with the color information, and first time I thought I should make my own extension, but then I found something...ANSI art!

Research


Yeah, this is something similar to ASCII art, when you can use only text for make your picture. ANSI is an american standard institute and they created old character set with some really usable special characters (ANSI is an extended ASCII and has codepage to explain, which code means which character). Word "ANSI" refers often this character set.

Old times, BBS systems were really popular. Don't blame me but I didn't use them. These systems were text-based and they used ANSI art on welcome screens. Soon I found the .ans extension, which store old-school terminal commands (move, goto, set background color, set color etc.). That was the ANSI X3.64 standard.


I had an extension with terminal commands so I had to write a simple terminal emulator, which can load the commands from an .ans file and execute them (draw on the screen). But later if I want to make my own graphic, should I write an editor too, right? No.


PabloDraw, my holy grail. It is an ANSI / ASCII art editor, some kind of "mspaint" in ANSI art world. This is what I need. You can draw cool ANSI graphics with color and save it in .ans extension, hell yeah!




Coding


Because the PabloDraw isn't open source in this moment and I didn't find another .ans file loader, I had to write my own. I found the specification of the terminal standard so I implemented commands in C# on standard windows console, one after one.


Sure if something sounds too simple, it is never simple.


1. Commands
There is a lots of them. Not too much but enough to give me a nice job. They have default parameters too so I should take care about correct interpretation.


2. Different terminals
World would be simple with one type of car, computer or terminal. Sure, there are different types and terminal isn't an exception. Standard Windows-style console has 80x25 character resolution and 16 color. But .ans files sometimes used advanced terminals (80x50 resolution, 256 color instead of 16 etc.).
Problem? Windows console don't support more than 16 color. 80x50 character? I can change the resolution but this cause compatibility problems (check the next section).


3. Non-standard solutions
Because of different terminal standards, there is a lot of possible problem. For example: if my editor using 80x50 resolution in default and I will display my draw on 80x25 screen, this will break up. Or if I found some cool draw in 80x25 but it don't use "break line" in the last character of the line, just let skip to the next, this will cause problems again if I want to use it in my greater resolution game.


Moreover, artists frequently made simple "animations" in the draw. Because you can change the (display / draw) speed of the terminal, if you draw something and redraw some character, the result was an animation. It's cool, but if your emulation isn't correct or animation using some non-standard feature, this will be totally bad.


Current graphics features

  • graphics using standard console window
CL.init("Command Line Engine test");
CL.hideCursor();

//these are static methods, you don't need to create an object from CL


You can create with these commands your console window. This will be 80x25 in default with black background color and white font color. If you give a string, this will be the title of the window. Useful command the hideCursor if you don't want to see the flashing underline (with showCursor, you can enable again).
  • font- and cursor graphics style save / restore
CL.saveCursorStyle(CL.getCurrentCursorStyle);

CL.loadCursorStyle(false);

CL.saveTextStyle(CL.getCurrentTextStyle);

CL.loadTextStyle();


There are two struct for these options: cursorStyle and textStyle. Always you have an actual style what you are currently using and you can save an another in these struct. textStyle have fontColor and backColor variables (type: ConsoleColor), and cursorStyle have positionX, positionY, size (type: int) and visible (type: bool) variables. You can save and restore these styles (even without modify restored cursor style your current cursor position, check the bool argument).
  • write to the console
CL.write("Hello World!");
CL.breakLine(); //or instead of last 2 line: CL.write("Hello World!\n");
CL.write("Hello World!",10,10,ConsoleColor.DarkRed,ConsoleColor.White);


You can use a lots of variant of "write" command. Without parameter just write to the current position. With two numbers write to the given position, and if you type colors too you can change the back- and font color.
Because if you will use console as a graphics area, break line after write is not always good so you should use breakLine command if you want to begin new line (or use new line constant - \n -  in your string).
Good news: formatting text write don't change your default color style, it will be saved and loaded after executed the write command.

plain text ASCII art, color formatting in code
(Source: http://www.chris.com/ascii/index.php?art=anime%20and%20manga/dragon%20ball)
  • sprite import from file (.txt ASCII or .ans ANSI art)
Sprite s1 = new Sprite("ASCII_art_01.txt");

Sprite s2 = new Sprite("ANSI_art_01.ans");

s1.draw(); //s2.draw();
You don't need to bother about extensions, just give the name and engine will do others. Because that detect depends on file extension (.ans -> ANSI art, others -> ASCII art), don't forget to give the full path with file extension.

Part of the picture after load and draw
(Source: http://artscene.textfiles.com/ansi/scene/rmcrypt.ans)
  • sprite draw independent from extension
s1.draw(); //draw to the top left corner
s2.draw(10,10); //draw to the given character position



.ans file loader with small mistakes
(Source: http://artscene.textfiles.com/ansi/scene/acid-vn.ans)


  • high-level table generating (data input from DataTable object or manual enumeration)
Table t = new Table(dt.Columns.Count,dt.Rows.Count,7,2,dt);
t.draw(); //draw to the top left corner
t.draw(20,30); //draw to the given character position

("dt" is a DataTable object, "t" will get dimensions from data source, 7 and 2 are the size of one cell in the table, in this example I didn't initialized border or special colors)

  • table format options
t.setBorderStyle(CL.borderStyle.Double);
t.cellSizeX = 10;
t.cellSizeY = 2;

t.draw();


Generated table with formatting (data from SQLite database)




Supported simple / double / no border, custom font- and background color, flexible size and automatic field text shortening.


Tasks

  • simple animation (now you should make manually with draw and MoveBufferArea commands)
  • 100% accurate .ans file loading (correct display of complex animated files and which are using not so common commands will fail right now)
  • ignoreUserInput method
  • automatic line wrap in data cells
State: under development

Nincsenek megjegyzések:

Megjegyzés küldése