This trainer is on the scaling of an arbitrary sized bitmap to screen in two dimensions. The sample program seems to work quite quickly, and the code is documented. The scaling procedure is however totally in assembler… hopefully this won’t cause too many problems.

DENTHOR, coder for ...
_____   _____   ____   __   __  ___  ___ ___  ___  __   _____
/  _  \ /  ___> |  _ \ |  |_|  | \  \/  / \  \/  / |  | /  _  \
|  _  | \___  \ |  __/ |   _   |  \    /   >    <  |  | |  _  |
\_/ \_/ <_____/ |__|   |__| |__|   |__|   /__/\__\ |__| \_/ \_/
smith9@batis.bis.und.ac.za
The great South African Demo Team! Contact us for info/code exchange!  

Grant Smith, alias Denthor of Asphyxia, wrote up several articles on the creation of demo effects in the 90s. I reproduce them here, as they offer so much insight into the demo scene of the time.

These articles apply some formatting to Denthor's original ASCII files, plus a few typo fixes.

What is scaling?

I think that most of you know this one already, but here goes. Let us say you have a picture (10x10 pixels) and you want to draw it to a different size (say 5x7 pixel), the process of altering the picture to fit into the new size is called scaling. Scaling only works on rectangular areas.

With scaling to can easily stretch and shrink your bitmaps.

Okay, so how do we code it?

Right. The way I am going to do scaling is as follows:

For the horizontal area, I am going to calculate a certain step value. I will then trace along the bitmap, adding this step to my position, and place the nearest pixel on to the screen. Let me explain this simpler…

Let us say I have a 10 pixel wide bitmap. I want to squish it into 5 pixels. Along the bitmap, I would draw every second pixel to screen. In ASCII:

  1234567890   13579
  +--------+   +---+
  |        |   |   |
  | bitmap |   |   |dest
  |        |   |   |
  +--------+   +---+

As you can see, by stepping through every second pixel, I have shrunk the bitmap to a width of 5 pixels.

The equation is as follows:

step = origionalwidth / wantedwidth;

Let us say we have a 100 pixel wide bitmap, which we want to get to 20 pixels.

step = 100 / 20
step = 5

If we draw every fifth pixel from the original bitmap, we have scaled it down correctly! This also works for all values, if step is of type real.

We also find the step for the height in the same way.

Our horizontal loop is as follows:

       For loop1:=1 to wantedwidth do BEGIN
         putpixel (loop1,height,bitmap[round (curpos)],vga);
         curpos:=curpos+xstep;
       END;

And the vertical loop is much the same. Easy huh? So east in fact, I wrote the procedure in pure assembler for you ;-) … don’t worry, it’s commented.

In the sample program, instead of using reals I have used fixed point math. Refer to Part 14 if you have any hassles with fixed point, it is fairly straightforward.

I also use psuedo 3-d perspective transforms to get the positions smooth… after Part 8, this should be a breeze.

There are no new commands in the assembler for you, so you should get by with what you learned in tut7/8 … whew! A lot of back referencing there ;) We really are building on our knowledge :)

In closing

Well, that is about it. As you can see the concept is easy, and in fact fairly obvious, but that didn’t stop me from having to sit down with a pencil and a piece of paper a few months ago and puzzle it out ;-)