Masking and Sprites


As you may have noticed, the PUT function has those parameters:

PUT (x%, y%), array%(index%)[, mode]


where mode can be either PSET, AND, XOR among others. That final parameters especifies a logical operation between the pixel data in the array and the pixel data on screen.

What is a logical operation? Well, I guess you have heard of AND and OR, and that:

1 OR x = 1
0 OR 0 = 0
0 AND x = 0
1 AND 1 = 1


where x can be either 1 or 0. You also have XOR:

x XOR x = 0
x XOR y = 1 if x<>y


Those binary operations can be applied to byte numbers, for example, 127 AND 255 will compare each bit of 127 with its correspondent bit in 255, and will build a new byte with the results:

    127 = 0 1 1 1 1 1 1 1
AND
255 = 1 1 1 1 1 1 1 1
______________________
0 1 1 1 1 1 1 1 = 127


This is very useful when trying to avoid the ugly black bounding box around our GFX. With masking techniques, you can get rid of it.

First we need to create a mask. Imagine we want a ball. We think on which pixels will be transparent and draw it with colour #ZERO:

00 00 01 02 02 01 00 00
00 01 02 03 03 02 01 00
01 02 03 03 03 03 02 01
01 02 03 03 03 03 02 01
01 02 03 03 03 03 02 01
01 02 03 03 03 03 02 01
00 01 02 03 03 02 01 00
00 00 01 02 02 01 00 00


Now, we create the mask. We need a similar drawing, but the transparent zones have to be drawn with colour #FFh (255, the last colour, in binary 11111111b). The non-transparent zones have to be drawn with colour #00h, that is:

FF FF 00 00 00 00 FF FF
FF 00 00 00 00 00 00 FF
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
FF 00 00 00 00 00 00 FF
FF FF 00 00 00 00 FF FF


what for? well, let me explain:

To do masking, we first need to prepare screen. If we PUT the mask using "AND", the blitter will AND each pixel in our mask with its correspondent on screen. That will make that every pixel on screen that corresponds with a FF in our mask (transparent zone) will remain as it is, 'cause x AND FF = x. It will also make that every pixel on screen that corresponds with a 00 in our mask (solid zones) will be cleared to ZERO, 'cause x AND 0 = 0.

Note that this will create a black zone with the shape of our sprite on screen.

Now we PUT the sprite using "XOR". Note that x XOR 0 = x and 0 XOR x = x, so the pixels in your sprite that equal 0 (transparent zones) won't have no effect on screen (and those pixels on screen will still have the background, after the AND operation), and the pixels in your sprite different from 0 will be XORed with pixels on screen that equal zero (after the AND operation, if your mask was correctly done).

' Transparent blit using masks:
PUT (x%, y%), myMask%(0), AND
PUT (x%, y%), mySprite%(0), XOR


I can't post examples 'cause my webspace can not be accessed tonight, so I can't upload pics to show you :(.

LATER:

I've written this piece of code as an example:

' Masking demo by Na Than Assh Antti 2003

'$DYNAMIC
DIM mySprite%(33)
DIM myMask%(33)

SCREEN 13

' Colour #255 is by default BLACK. Let's turn it into WHITE so we can
' see the mask (for educational purposes):

OUT &H3C8, 255: OUT &H3C9, 63: OUT &H3C9, 63: OUT &H3C9, 63

' Get the sprites: [I am using ugly and stupid DATA sprites :P]

RESTORE
FOR i% = 0 TO 1

FOR y% = 0 TO 7
FOR x% = 0 TO 7
READ a$
PSET (i% * 8 + x%, y%), VAL("&H" + a$)
NEXT x%
NEXT y%

NEXT i%
GET (0, 0)-(7, 7), mySprite%(0)
GET (8, 0)-(15, 7), myMask%(0)

CLS
PAINT (0, 0), 34

LOCATE 3, 5: PRINT "THIS IS THE SPRITE:"
PUT (220, 16), mySprite%(0), PSET
LOCATE 5, 5: PRINT "THIS IS THE MASK:"
PUT (220, 32), myMask%(0), PSET
LOCATE 7, 5: PRINT "Let's see what happens if we PUT"
LOCATE 8, 5: PRINT "our mask using AND:"
PUT (156, 72), myMask%(0), AND
LOCATE 12, 5: PRINT "Now we PUT the mask with AND and "
LOCATE 13, 5: PRINT "then the sprite with XOR:"

' Transparency:
PUT (156, 112), myMask%(0), AND
PUT (156, 112), mySprite%(0), XOR

' DONE :D

END

' Sprite:
DATA 00,00,01,01,01,01,00,00
DATA 00,01,02,02,02,02,01,00
DATA 01,02,02,03,03,02,02,01
DATA 01,02,02,03,03,02,02,01
DATA 01,02,02,03,03,02,02,01
DATA 01,02,02,03,03,02,02,01
DATA 00,01,02,02,02,02,01,00
DATA 00,00,01,01,01,01,00,00

' Mask:
DATA FF,FF,00,00,00,00,FF,FF
DATA FF,00,00,00,00,00,00,FF
DATA 00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00
DATA 00,00,00,00,00,00,00,00
DATA FF,00,00,00,00,00,00,FF
DATA FF,FF,00,00,00,00,FF,FF


Replace FF (255) by F (15) for SCREEN 7, 8, 9 and 12; by 3 for SCREEN 1 and 10, and by 1 for SCREEN 2 and 11.

na_th_an


MaskingAndSprites - page last edited 2004-12-24 16:57:53 by 84.122.252.103 (home) (edit)
Blast WIKI - by RoboticBoy - edited and tweaked for our evil purposes by Hexadecimal Disaster