Qbasicnews.com

Full Version: clipping path for sprites
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
when using get/put, is it possible to impose a sprite on a complicated background without including the entire black box around it?

is there a "safe" color that won't impose when PUT-ing with PSET?
Masking(if you know how)

http://rel.betterwebber.com/MyProgs/Scroll.zip


Or use a LIB

Check out my reply on your other thread.
Check out the tutorials on this site (not the FAQ), for tutorials by Dark Dread on placing sprites on complex backgrounds.
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