;------------------------------------------------------------------------------- ;@doc:file ; ; === Sprite.asm === ; ; Provides methods for drawing sprites. ; ;@doc:end ;------------------------------------------------------------------------------- .module Sprite FullWhite .db $00, $00, $00, $00, $00, $00, $00, $00 FullBlack .db $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF Clip ld hl,(Graphics.VisitedPoints+0) call Graphics.ScaleX.HL ld (SpriteX),hl ld hl,(Graphics.VisitedPoints+2) call Graphics.ScaleY.HL call Graphics.FlipY16 ld (SpriteY),hl ; Check if X is out of bounds first. ld hl,(Graphics.Bounds+1) ; Max X ld h,0 ld de,(SpriteX) or a sbc hl,de jp p,+ scf ; Sprite out of bounds. ret + ld hl,(SpriteX) ; X ld de,7 add hl,de ld de,(Graphics.Bounds+0) ; Min X ld d,0 or a sbc hl,de jp p,+ scf ; Sprite is out of bounds. ret + ; if (maxy >= y) => sprite is in bounds. ld hl,(SpriteY) ; Y ex de,hl ld hl,(Graphics.Bounds+3) ; Max Y ld h,0 or a sbc hl,de jp p,+ scf ; Sprite out of bounds. ret + ex de,hl call Graphics.ClampY ld (MinSpriteY),hl ld de,(SpriteY) ; Y ; hl = Y to start drawing, de = specified Y or a sbc hl,de add hl,hl ld de,SpriteAccumulator add hl,de ld (SrcPtr),hl ; if (y + 7 >= miny) => sprite is in bounds. ld hl,(SpriteY) ; Y ld de,7 add hl,de ld de,(Graphics.Bounds+2) ; Min Y ld d,0 or a push hl sbc hl,de pop hl jp p,+ scf ; Sprite is out of bounds. ret + call Graphics.ClampY ld (MaxSpriteY),hl inc hl ld de,(MinSpriteY) or a sbc hl,de jr nz,+ scf ret + ld a,l ld (RowsToDraw),a ld hl,(MinSpriteY) add hl,hl add hl,hl ld d,h \ ld e,l add hl,hl add hl,de ld de,(Lcd.Buffer) add hl,de ld (DestPtr),hl ; Now we've handled Y, handle X. ld a,(SpriteX) and 7 ld (FineShift),a ld hl,(SpriteX) sra h \ rr l sra h \ rr l sra h \ rr l ld de,(DestPtr) add hl,de ld (DestPtr),hl ld a,%11111111 ld (FineMask),a ; Do we need to mask out the left of the sprite? ld hl,(Graphics.Bounds+0) ; Min X ld h,0 ld de,(SpriteX) ; Sprite X or a sbc hl,de jr z,+ jp m,+ ; Sprite needs clipping at the left. ld b,l ld a,%11111111 - srl a djnz - ld (FineMask),a + ; Do we need to mask out the right of the sprite? ld hl,(SpriteX) ; Sprite X ld de,7 add hl,de ld de,(Graphics.Bounds+1) ; Max X ld d,0 or a sbc hl,de jr z,+ jp m,+ ; Sprite needs clipping at the right. ld b,l ld a,(FineMask) ld h,a - add a,a djnz - and h ld (FineMask),a + or a ret .for p = 0 to 1 .if p == 0 LoadSpriteAccumulatorWhite .elseif p == 1 LoadSpriteAccumulatorBlack .endif ld de,(SpriteData) ld hl,SpriteAccumulator ld ixl,8 ld a,(FineMask) .if p == 1 cpl .endif ld ixh,a -- ld a,(de) .if p == 0 and ixh .elseif p == 1 or ixh .endif ld b,a .if p == 0 ld c,%00000000 .elseif p == 1 ld c,%11111111 .endif ld a,(FineShift) or a jr z,+ - .if p == 0 srl b .elseif p == 1 scf rr b .endif rr c dec a jr nz,- + ld (hl),b inc hl ld (hl),c inc hl inc de dec ixl jr nz,-- ret .loop .for p = 1 to 3 .if p == 1 DrawOr .elseif p == 2 DrawAnd .elseif p == 3 DrawEor .endif call Clip ret c .if p == 2 call LoadSpriteAccumulatorBlack .else call LoadSpriteAccumulatorWhite .endif ld de,(SrcPtr) ld hl,(DestPtr) ld a,(RowsToDraw) ld b,a - ld a,(de) inc de .if p == 1 or (hl) .elseif p == 2 and (hl) .elseif p == 3 xor (hl) .endif ld (hl),a inc hl ld a,(de) inc de .if p == 1 or (hl) .elseif p == 2 and (hl) .elseif p == 3 xor (hl) .endif ld (hl),a push de ld de,11 add hl,de pop de djnz - or a ret .loop .endmodule