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

previous page            contents            there's nothing after this, really