DungeonMaker
How I Rendered the Dungeons on SDL
- a tutorial -
by Peter Henningsen
What is the DungeonMaker again?
The DungeonMaker is a program that uses artificial life methods
to construct mazes. It will eventually do dungeons, but right now all it
does is mazes. The DungeonMaker starts out on an open map with a wall around
the perimeter, possible more pre-placed walls, and a number of Crawlers.
These Crawlers are entities that crawl around, interacting with each other,
and leaving wall tiles in their wake. Eventually, a maze is constructed - its
basic layout is determined by the design parameters (mostly pre-placed walls
and Crawlers read in from the ``rooms''-file), and its execution is steered
in detail by the parameters in the ``stats''-file, which determine likelihoods
of Crawler-behaviors for the different generations of Crawlers. There is much
more information on all this available in the
manual. Run the
program a few times and you will see....
Version 1.0 of the DungeonMaker creates output in the form of a text file,
where different letters and numbers are printed for the different square-types,
such as open, wall, column, etc. The aim with version 1.1 was to create
graphical output using the SDL-library.
Calling SDL
This is the code I use to open and close my SDL-section of code:
#include<SDL/SDL.h>
SDL_Surface* screen;
SDL_Surface* image;
SDL_Rect src , dest;
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("Unable to init SDL: %s\n" , SDL_GetError());
return(1);
}
atexit(SDL_Quit);
//x and y are the dimensions of our map, and we render each map-square
as an image of 4x4 white pixels - (scale == 4)
//we want a 16 bit color model, so we don't have to mess with a palette
//the last parameter 0 gives us a rendering surface in a window
screen = SDL_SetVideoMode(scale * x , scale * y , 16 , 0);
if(screen == NULL)
{
printf("Unable to set video mode: %s\n" , SDL_GetError());
return(1);
}
//do something here
//...and here
//now wait for the user to close the window
SDL_Event event;
while(SDL_WaitEvent(&event) != 0)
{
switch(event.type)
{
case (SDL_QUIT):
SDL_FreeSurface(image);
goto jump;
}
//we handle only the one event
}
jump: SDL_Quit();
There's also a small change in the Makefile. Two types of cleanup have
to be done: That done by SDL automatically, which
is triggered by the call atexit(SDL_Quit());,
and the cleanup we have to do ourselves, e.g. for surfaces we allocated. In our case this
is done in response to the SDL_QUIT-event by
calling SDL_FreeSurface(). I crashed when
calling SDL-Quit() from the event loop, so I
tried the jump and it worked, but it doesn't look very elegant;-)
Putting the map on the screen
This now is the "something" I do to put out the DungeonMaker-generated map
on the screen:
image = SDL_LoadBMP("white4x4.bmp");
if(image == NULL)
{
printf("Unable to load white4x4.bmp\n");
return(1);
}
src.x = 0;
src.y = 0;
src.w = image->w; //we know this is 4
src.h = image->h;
dest.w = image->w;
dest.h = image->h;
unsigned int wallCode;
//we iterate through the DungeonMaker-generated map:
for(int xIndex = 0; xIndex < x; xIndex++)
for(int yIndex = 0; yIndex < y; yIndex++)
{
wallCode = pDM -> GetMap(xIndex , yIndex);
if ( ( wallCode != 0 ) && ( wallCode != 3 ) && ( wallCode != 5 ) ) //we have a wall here
{
dest.x = 4*xIndex; //here we designate the starting point
dest.y = 4*yIndex; //of the rect where we want our white4x4-image blitted
SDL_BlitSurface(image , &src , screen , &dest);
}
}
//after all the little white squares for the walls have been blitted to the screen, we update
//and actually display the screen
SDL_UpdateRect(screen , 0 , 0 , 0 , 0 );
That's all. SDL is amazingly simple. In version 1.2 we will display the
dungeon-generation process as a movie, a rather more difficult task. Stay
tuned...