Basics of using a mask...
Code:
DEFINT A-Z
SCREEN 13
DIM SpriteImage(129)
DIM SpriteMask(129)
DIM SaveBackground(129)
'Create the sprite
LINE (0, 0)-(15, 15), 255, BF
CIRCLE (8, 8), 7, 4, , , .83
PAINT (8, 8), 4
CIRCLE (10, 7), 2, 12, , , .83
PAINT (10, 7), 12
GET (0, 0)-(15, 15), SpriteImage(0)
'Create the mask from the sprite
FOR y = 0 TO 15
FOR x = 0 TO 15
IF POINT(x, y) = 255 THEN
PSET (x + 16, y), 0
ELSE
PSET (x + 16, y), 255
END IF
NEXT
NEXT
GET (16, 0)-(31, 15), SpriteMask(0)
CLS
'Draw some shiznit on the screen
FOR x = 0 TO 319
LINE (x, 0)-(x, 199), x AND 255
NEXT
FOR x = 0 TO 304
'Wait for vsync
WAIT &H3DA, 8, 8
WAIT &H3DA, 8
'restore old background
IF x > 0 THEN PUT (x - 1, 92), SaveBackground(0), PSET
'save new background
GET (x, 92)-(x + 15, 107), SaveBackground(0)
'Put sprite while preserving background
PUT (x, 92), SpriteMask(0), OR
PUT (x, 92), SpriteImage(0), AND
NEXT
Once you get a lot of sprites, it'll start to flicker. Then your choice is either a lib or SetVideoSeg...
Code:
DEFINT A-Z
'$DYNAMIC
DECLARE SUB SetVideoSeg (Segment)
DIM Buffer(32006) 'an extra 16 bytes are needed so that the image
Buffer(6) = 2560 'can be aligned evenly on a segment (the 4 bytes for
Buffer(7) = 200 'the x and y sprite size normally throw this off, so we
BufferSeg = VARSEG(Buffer(0)) + 1 'have to shift everything over 12 bytes
SCREEN 13
SetVideoSeg BufferSeg 'Draw all the setup stuff on the buffer
DIM SpriteImage(129)
DIM SpriteMask(129)
DIM SaveBackground(129)
'Create the sprite
LINE (0, 0)-(15, 15), 255, BF
CIRCLE (8, 8), 7, 4, , , .83
PAINT (8, 8), 4
CIRCLE (10, 7), 2, 12, , , .83
PAINT (10, 7), 12
GET (0, 0)-(15, 15), SpriteImage(0)
'Create the mask from the sprite
FOR y = 0 TO 15
FOR x = 0 TO 15
IF POINT(x, y) = 255 THEN
PSET (x + 16, y), 0
ELSE
PSET (x + 16, y), 255
END IF
NEXT
NEXT
GET (16, 0)-(31, 15), SpriteMask(0)
CLS
'Draw some background shiznit on the buffer
FOR x = 0 TO 319
LINE (x, 0)-(x, 199), x AND 255
NEXT
FOR x = 0 TO 304
'restore old background
IF x > 0 THEN PUT (x - 1, 92), SaveBackground(0), PSET
'save new background
GET (x, 92)-(x + 15, 107), SaveBackground(0)
'Put sprite while preserving background
PUT (x, 92), SpriteMask(0), OR
PUT (x, 92), SpriteImage(0), AND
'Copy the buffer to video memory
SetVideoSeg &HA000
'WAIT &H3DA, 8 'Wait for vsync (optional)
PUT (0, 0), Buffer(6), PSET
SetVideoSeg BufferSeg
NEXT
SUB SetVideoSeg (Segment) STATIC
DEF SEG
IF VideoAddrOff& = 0 THEN ' First time the sub is called
' We need to find the location of b$AddrC, which holds the graphics
' offset (b$OffC) and segment (b$SegC). Since b$AddrC is in the default
' segment, we can find it by setting it to a certain value, and then
' searching for that value.
SCREEN 13 ' Set b$SegC to A000 (00A0 in memory)
PSET (160, 100), 0 ' Set b$OffC to 7DA0 (not needed in the IDE)
FOR Offset& = 0 TO 32764 ' Search for b$AddrC, which is
IF PEEK(Offset&) = &HA0 THEN ' in the default segment and
IF PEEK(Offset& + 1) = &H7D THEN ' should have a value of
IF PEEK(Offset& + 2) = &H0 THEN ' A0 7D 00 A0.
IF PEEK(Offset& + 3) = &HA0 THEN
VideoAddrOff& = Offset& + 2 ' If we found it, record the
EXIT FOR ' offset of b$SegC and quit
END IF ' looking. (Oddly, changing
END IF ' the b$OffC doesn't seem to
END IF ' do anything, so this is why
END IF ' this sub only changes b$SegC)
NEXT
END IF
' Change b$SegC to the specified Segment
POKE VideoAddrOff&, Segment AND &HFF
POKE VideoAddrOff& + 1, (Segment AND &HFF00&) \ &H100
END SUB