vin.ingine.nl
a blog by Vincent van Ingen
24 Aug 2009
 

When you're writing a program in C, C++, Objective C, maybe D?. You come to a point, how do I load my data? If you're making a game it would be nice to save your level data in some sort of file. And you should! You could use XML. It is widely used so why not? Well...did you ever opened the libXML library from xmlsoft.org? The 'parser.c' alone is already 395Kb! Sure, they need to make the code to follow the W3C standard, but come on! 395Kb for a parser?

That's one of the many reasons I wrote Lasanja. The other one is that I like to write my own code. Another is that XML has it flaws like '<a><b></a></b>' is not a valid structure, which in Lasanja you can't. The last and importent reason. I like things to be simple, don't overdo things you will never use.

So, what's Lasanja? Lasanja is a markup language, just like XML. Let say we want to load a level file. We could define a Lasanja file like so:

 
version{ 1 }
 
level{
	width{ 30 }
	height{ 5 }
 
	1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
	1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
	1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
	1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
	1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
 
	enemy{
		x{ 12.12 }
		y{ 24.24 }
	}
 
	enemy{
		x{ 56.34 }
		y{ 23.95 }
	}
}
in XML we would could do it like so:
 
<data>
	<version>
	    1
	</version>
 
	<level>
		<width>30</width>
		<height>5</height>
 
		1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
		1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
		1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
		1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
		1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
 
		<enemy>
			<x>12.12</x>
			<y>24.24</y>
		</enemy>
 
		<enemy>
			<x>56.34</x>
			<y>23.95</y>
		</enemy>
	</level>
</data>

You can see that's almost the same. In Lasanja there are two things, nodes and data. In XML you got, nodes, data and attributes. I removed the attributes because for some that's confusing and I don't like people confused. Also note the extra '<data>' tag in the xml file. That is not needed in a Lasanja file.

In short. With tagname{ you create a new node named 'tagname'. With } you close the node. Everyting between { and } is data. That's it! You find more info in the project file.

You may use the code anyway you like. If you vind some bugs, please e-mail me. I would appreciate it.
The project file and sources are here: http://vin.ingine.nl/posts/13/lasanja.v0.4.zip

Lasanja v0.4 does not mean it's not finished or buggy code. It does what it does and it does well. I don't consider this as a beta release. Because this is it's first release I don't want to release it as v1.0 yet.

Did I mentioned that the project executable for reading an example level las file, is only 9Kb! You can store that 163 times on a 1.44 Mb floppy disk :P

 
Tags: C, Development, Other. No comments yet.
 
 
 
 
 
10 Aug 2009
 

UPDATE: Today I use Cairo. Which is not only a font renderer but a full blown vector graphics library. They are now building support for OpenGL. Sweet!

Made me some nice wrapper functions. It's much more readable now. You can use it as a basis for your own font drawing routines.

TODO: Some better error handling.

 
FT_Face g_ftFace;
FT_Library g_ftLib;
FT_Matrix g_ftMatrix;
FT_Vector g_ftPen;
int g_ftBoxWidth;
int g_ftBoxHeight;
 
 
void ftBox( int width, int height )
{
    g_ftBoxWidth = width;
    g_ftBoxHeight = height;
}
 
void ftInit()
{
    g_ftMatrix.xx = 0x10000;
    g_ftMatrix.xy = 0;
    g_ftMatrix.yx = 0;
    g_ftMatrix.yy = 0x10000;
 
    g_ftBoxWidth = 0;
    g_ftBoxHeight = 0;
 
    if( FT_Init_FreeType( &g_ftLib ) ) {
        printf( "Error: could not initialize FreeType library\n" );
    }
}
 
void ftFace( char *face )
{
    FT_Error error = FT_New_Face( g_ftLib, face, 0, &g_ftFace );
 
    if( error == FT_Err_Unknown_File_Format ) {
        printf( "Error: Unknown font file format\n" );
    }
    else if( error ) {
        printf( "Error: Unknown error loading font\n" );
    }
}
 
void ftMatrix( int xx, int xy, int yx, int yy )
{
    g_ftMatrix.xx = xx;
    g_ftMatrix.xy = xy;
    g_ftMatrix.yx = yx;
    g_ftMatrix.yy = yy;
}
 
void ftSize( int width, int height )
{
    if( FT_Set_Pixel_Sizes( g_ftFace, 80, 80 ) ) {
        printf( "Error: Could not set font pixel size\n" );
    }
}
 
void ftText( char *image, char *text )
{
    int num_chars = strlen( text );
    int x, y, i, j, p, q, x_max, y_max, pixel;
    char color;
 
    FT_Bitmap *bitmap;
    FT_GlyphSlot slot = g_ftFace->glyph;
 
    int n = 0;
 
    for( ; n < num_chars; n++ )
    {
        FT_Set_Transform( g_ftFace, &g_ftMatrix, &g_ftPen );
 
        if( FT_Load_Char( g_ftFace, text[n], FT_LOAD_RENDER ) ) {
            continue;
        }
 
        bitmap = &slot->bitmap;
        x = slot->bitmap_left;
        y = g_ftBoxHeight - slot->bitmap_top;
        x_max = x + bitmap->width;
        y_max = y + bitmap->rows;
 
        for( i = x, p = 0; i < x_max; i++, p++ )
        {
            for( j = y, q = 0; j < y_max; j++, q++ )
            {
                if( i < 0 || j < 0 || i >= g_ftBoxWidth || j >= g_ftBoxHeight ) {
                    continue;
                }
 
                color = bitmap->buffer[q * bitmap->width + p];
                pixel = ( j * g_ftBoxHeight + i ) * 4;
                image[pixel++] = 0xff;   // R
                image[pixel++] = 0xff;   // G
                image[pixel++] = 0xff;   // B
                image[pixel] |= color;   // A
            }
        }
 
        g_ftPen.x += slot->advance.x;
        g_ftPen.y += slot->advance.y;
    }
}
 
void ftTranslate( int x, int y )
{
    g_ftPen.x = x << 6;
    g_ftPen.y = ( g_ftBoxHeight - y ) << 6;
}


This is how you use the new functions. Much nicer now!

 
#define IMG_WIDTH 512
#define IMG_HEIGHT 512
 
 
 
// create a bitmap
unsigned char *image = malloc( IMG_WIDTH * IMG_HEIGHT * 4 );
 
if( image == NULL ) {
    printf( "Error: malloc()\n" ); return 0;
}
 
memset( image, 0, IMG_WIDTH * IMG_HEIGHT * 4 );
 
 
 
// draw our text using our awesome functions!
ftInit();
ftFace( "c:/windows/fonts/verdana.ttf" );
ftSize( 80, 80 );
ftBox( IMG_WIDTH, IMG_HEIGHT );
 
double angle = ( -30.0 / 180.0 ) * 3.14159;
ftMatrix(
    (FT_Fixed)( cos( angle ) * 0x10000L ),
    (FT_Fixed)(-sin( angle ) * 0x10000L ),
    (FT_Fixed)( sin( angle ) * 0x10000L ),
    (FT_Fixed)( cos( angle ) * 0x10000L )
);
 
ftTranslate( 50, 100 );
ftText( image, "Hello, world!" );
ftTranslate( 50, 200 );
ftText( image, "Hello, world!" );
ftTranslate( 50, 300 );
ftText( image, "Hello, world!" );
 
 
 
// ...and create a OpenGL texture of it
GLint img;
 
glGenTextures( 1, &img );
glBindTexture( GL_TEXTURE_2D, img );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, IMG_WIDTH, IMG_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, image );
 
Tags: C, Development, OpenGL, Other. No comments yet.
 
 
 
 
 
4 Aug 2009
 

Why Vin Ingine?
My real name is Vincent van Ingen. But people call me just Vin or Vinnie for short. Ingine is my company name which I got from mixing "engine" and my last name "Ingen".

Are you available for work?
Yes I am. I've got a company Visionplay in The Netherlands where I do work for external companys.

How can I contact you?
Click on the e-mail at the right menu of this site under Contact.

For now not much faq. Need to know something more? Leave a comment below :)

 
Tags: Other. No comments yet.
 
 
 
 
 
3 Aug 2009
 

Hi! My name is Vincent van Ingen. And finally I have my own personal web blog! I've been around for some time now but never had a website where I could share my stuff with the rest of the world.

I like to develop in a very creative way. Nowdays I like todo that in just plain C with some OpenGL stuff. But also in Flash Actionscript, Processing or any other language that's good looking. Hence, I've started my own programming language!

Today I'm working on several things. I got my company Visionplay where I work on some websites and RIA applications. I got another company called Ingine which from now on I started developing games for multiple platforms. And last, Vii2Media which is a cross-media platform for broadcasting.

Well, that's about it for now. I could tell more, but let the blog do the talking for now.

Enjoy your stay :)

 
Tags: Other. Comments (4).