A85: Scaling Sprites


[Prev][Next][Index][Thread]

A85: Scaling Sprites




Hopefully some people are still subscribing to this list ;)

I'm trying to code a sprite scaling routine, and I'm kinda afraid the 
algorithm I'm using will be too slow.  The algorithm is closely related to 
Brensenham's Line algorithm, in that it keeps track of an error term, and 
when it exceeds a certain value, it skips out of the loop.  Basically, the 
routine will take each individual bit in each individual row and assign it a 
value:  if set, 1; if reset, -1.  It uses this to find an "average" for a 
block of bits within a particular row.  Then it will add the corresponding 
averages of groups of rows to give the final pixel value if the scaled 
sprite: if >=0, set; if <0, reset.  Something like at illustration might help 
;)

Say you had the following 16x10 sprite:

1111111101000000
0000000101000000
0000000101000000
0000000101000000
0000000101000000
1000000101000000
1000000101000000
1000000101000000
1000000101000000
1111111101111111

...and you wanted to shrink this sprite into something like...10x6.  Using a 
similar approach to Brensenham's line algorithm, the sprite would be split up 
into "blocks", that will eventually be converted into individual pixels:

11 | 1 | 11 | 1 | 11 | 01 | 0 | 00 | 0 | 00
00 | 0 | 00 | 0 | 01 | 01 | 0 | 00 | 0 | 00
-----------------------------------------------------
00 | 0 | 00 | 0 | 01 | 01 | 0 | 00 | 0 | 00
-----------------------------------------------------
00 | 0 | 00 | 0 | 01 | 01 | 0 | 00 | 0 | 00
00 | 0 | 00 | 0 | 01 | 01 | 0 | 00 | 0 | 00
-----------------------------------------------------
10 | 0 | 00 | 0 | 01 | 01 | 0 | 00 | 0 | 00
10 | 0 | 00 | 0 | 01 | 01 | 0 | 00 | 0 | 00
-----------------------------------------------------
10 | 0 | 00 | 0 | 01 | 01 | 0 | 00 | 0 | 00
10 | 0 | 00 | 0 | 01 | 01 | 0 | 00 | 0 | 00
-----------------------------------------------------
11 | 1 | 11 | 1 | 11 | 01 | 1 | 11 | 1 | 11

This is split into 10 sections horizontally, and 6 sections vertically.  
Anyway, each "block" is evaluated based on the pixels in that block.  For 
each 1, add 1; for each 0, subtract 1.  So, for example, the first block in 
the top-left corner would be evaluated to 1 + 1 - 1 - 1 = 0.  The rest would 
be like:

  0 |  0 |  0 |  0 |  2 |  0 | -2 | -4 | -2 | -4
-----------------------------------------------------
 -2 | -1 | -2 | -1 |  0 |  0 | -1 | -2 | -1 | -2
-----------------------------------------------------
 -4 | -2 | -4 | -2 |  0 |  0 | -2 | -4 | -2 | -4
-----------------------------------------------------
  0 | -2 | -4 | -2 |  0 |  0 | -2 | -4 | -2 | -4
-----------------------------------------------------
  0 | -2 | -4 | -2 |  0 |  0 | -2 | -4 | -2 | -4
-----------------------------------------------------
  2 |  1 |  2 |  1 |  2 |  0 |  1 |  2 |  1 |  2

You'd then take each value of each block, and if it's 0 or positive, you put 
a pixel to the screen, else it corresponds to no pixel.  So the resulting 
scaled sprite would look like:

1111110000
0000110000
0000110000
1000110000
1000110000
1111111111

This example actually turned out pretty good... ;)

So why write to this list?  I basically wanna know if anyone else has a 
better idea for a scaling algorithm (shrinking only for now...stretching is 
somewhat easier).  If you have any idea at all, don't hesitate to let me know!

JayEll