A86: Re: 16x16 sprite routine?
[Prev][Next][Index][Thread]
A86: Re: 16x16 sprite routine?
Here is one(by Matt Johnson; never tested by me) it does 16*X size sprites:
PutSprite:
push bc ; Save BC (X, Y)
push de ; Save DE
push hl ; Save HL (Start of Sprite Data)
push hl ; Save HL (Start of Sprite Data)
push bc
ld d, c
ld e, d
call FindPixel ; Finds pixel at E, D
pop bc
; PutSprite needs pixel at B, C
; A = Bitmask with one bit set; this will be the bit (pixel) "counter"
ex de,hl ; DE = Address in Display of Sprite
pop hl ; HL = Start of Sprite Data
ld b,(hl) ; B = X width of Sprite
inc hl ; Next byte
ld c,(hl) ; C = Y width of Sprite
inc hl ; Next byte (now pointing at actual sprite data)
push hl ; Save the twice incremented HL into stack
pop ix ; IX = The recently twice incremented HL
ex de,hl ; HL = Address in Display of Sprite
PS_NewRow:
push bc ; Save X width of Sprite and Y width of Sprite
ld d,(ix) ; D = (IX), so D = First byte from Sprite
inc ix
ld e,(ix) ; E = (IX), so E = Second byte from Sprite
inc ix ; IX points to next row
push af ; Save Bitmask
push hl ; Save HL, Address in Display of Sprite
PS_NewCol: ; Now the fun begins, remember A is the bitmask, D = the Left
Column Byte from Sprite
sla e ; 16-bit rotation DE
rl d
push af ; Save Bitmask
jr nc,PS_NoPixel ; Check pixel from sprite to see if it is set
or (hl) ; Sets Pixel at the "current bit" (Bitmask is the "bit counter")
ld (hl),a ; (HL) = A, Save changes to
jr PS_NextPixel
PS_NoPixel:
cpl ; Invert Bitmask
and (hl) ; Clears pixel at the "current bit" (Bitmask is the "bit
counter")
ld (hl),a ; (HL) = A Save changes
PS_NextPixel:
pop af ; Restore Bitmask
rrca ; A is rotated right *through* carry
jr nc,PS_SameByte ; If the carry was set, that means that one bit set in
A (bit counter)
; rotated all the way to the end right into carry and recycles back
into Bit 7
; so it can be used for the next byte
inc hl ; Move on to next byte
PS_SameByte:
djnz PS_NewCol ; B = X (width of sprite), so it loops to PS_NewCol X
times. This means that is X = 6,
; it will Shift Right the bitmask (move the bit counter to the right) 6
times, comparing
; each bit of the bitmask and the sprite and setting or clearing the
pixel in that
; particular bit. It then moves on the the next pixel.
; Move on to the next row
pop hl ; Recover HL, the Address in Display of the Sprite
pop af ; Recover AF, A = Bitmask
ld de,16 ; DE = 16
add hl,de ; HL = HL + 16, this moves down ONE row in the Display Area
(128 width / (8 bits/pixel) = 16 bytes)
pop bc ; Recover X_width and Y_height of Sprite
dec c ; C = Y_height of Sprite, subract one, which means one row of the
Sprite has been drawn
jr nz,PS_NewRow ; If there are more rows to be drawn, go back to PS_NewRow
; No more rows. Since there were "effectively" 3 pushes before PS_NewRow,
there must be three pops that way the
; ret statement will retrieve the correct address when it returns to the
calling program.
pop hl
pop de
pop bc
ret
; =============================================================
; Dan Eble & James Yopp FindPixel routine
; Input: D = y, E = x
; Output: HL= addr in vid mem, A = bitmask, C is modified
; =============================================================
FindPixel:
ld hl,FP_Bits
ld a,e
and $07 ; a = bit offset
add a,l
ld l,a
adc a,h
sub l
ld h,a
ld c,(hl) ; c = bitmask for (hl)
;48 t-states up to this point
ld hl,FP_RLD
ld (hl),d
ld a,e ; a = x/8 (byte offset within row)
rrca
rrca
rrca
rld
or $FC
ld l,(hl)
ld h,a ; hl -> byte in vid mem
ld a,c ; now a = bitmask for (hl)
;121 t-states up to this point
ret
FP_RLD: .db $00
FP_Bits: .db $80,$40,$20,$10,$08,$04,$02,$01
-----Original Message-----
From: YosterIsle@aol.com <YosterIsle@aol.com>
To: assembly-86@lists.ticalc.org <assembly-86@lists.ticalc.org>
Date: Tuesday, September 22, 1998 8:48 PM
Subject: A86: 16x16 sprite routine?
>
>Does anyone know of a 16x16 sprite routine for the 86? I'd like to just put
>one 16x16 sprite instead of two 8x16 ones in my Wak-A-Goomba game. Speed
isn't
>too important.
>