How to do Floormapping Without Really Trying

Everybody who has played Super Nintendo knows that some games like F-Zero used a funky graphics mode where a flat background would be rendered in a sorta 3D-looking way using a technique called "floormapping"

Now, you might be wondering how to do floormapping in your own games. Yeah, me too. I remember there was a tutorial online a couple years ago that explained all the floormapping mechanics in detail and reduced it to one simple formula to plug into your program. But that tutorial disappeared, leaving all of us clueless as how to actually do it.

Keep in mind, this is NOT meant as a replacement for that tutorial. I do not know how to floormap, but I have figured out a simple way to fake it. My example uses the Allegro library, but it could easily be ported to any number of different graphics libraries

Step 1: Stretching the X

Make a bitmap the size of your screen (my example uses a 320x240 screen). This is the buffer that you'll put your floormapped image into. So it's... a floor buffer! :)

The thing about this method is that you start by rendering the stuff on screen like normal, THEN you stretch the image to make it look 3-D. This is accomplished by grabbing horizontal lines of image data and stretching them more and more as you go towards the bottom of the screen. Here's some sample code:

for (x = 0; x < 240; x++) { 
 stretch_blit(buffer, floorbuffer,
              x / 4, x, 320 - (x / 2), 1,
              0, x, 320, 1);
}

Then you just blit it either to the screen or back to your buffer. Simple, eh? But this ends up looking a little strange, because even though things get stretchier as they get closer, it only stretches horizontally. The end result is it looks a bit like you're walking on the inside of a gigantic cylinder-shaped world. If your game takes place on a donut-shaped rotating space colony this would be fine but for flatter worlds, another step needs to be taken

Step 2: Stretching the Y

Step 1's method takes a horizontal line from the source bitmap and puts it in the same position on the floor buffer (hehehee... floor buffer). What we need to do is make it so that the horizontal line slows down on its way to the bottom, the end result being that it gets stretched vertically more and more toward the bottom. To do this we need to use floating points. They tend to be slow, so it's best to put their results in a lookup table like so (do this only once in your program or you won't get any speed benefit)

float y;
float changey;
y = 0;
for (x = 0; x < 240; x++) {
 changey = 1.5 - float(x / 240.0);
 y += changey;
 if (y > 239) y = 239;
 floorstretchyness[x] = int(y);
}

It is very important that you put the decimal point in 240.0 because otherwise it will do an integer division and the results will look really weird.

Now we simply take our first formula and replace the fourth value with floorstretchyness[x]

for (x = 0; x < 240; x++) { 
 stretch_blit(buffer, floorbuffer,
              x / 4, floorstretchyness[x], 320 - (x / 2), 1,
              0, x, 320, 1);
}

Tada! You're done. Note that any of the constant numbers in this can be changed to suit your needs and experiment with. Also note that you will have to render your player character to the screen AFTER doing this or he'll get stretched too. If you plan to have more than one character or object onscreen, or if your playing character doesn't stay centered then you'll have to do some advanced sprite positioning and resizing, and I don't know how to do that :)

Oh yeah, and if you use this in your game be nice and mention me somewhere.