sb: add transparent sprite support

This commit is contained in:
Vince Weaver 2023-03-13 23:55:12 -04:00
parent 18317502d3
commit aaed2d1b39
10 changed files with 260 additions and 95 deletions

View File

@ -33,7 +33,7 @@ DUCK_POND: duck_pond.o
duck_pond.o: duck_pond.s zx02_optim.s \
zp.inc hardware.inc \
gr_copy.s duck_score.s gr_putsprite.s \
gr_copy.s duck_score.s gr_putsprite_mask.s \
draw_ducks.s move_ducks.s \
graphics/duck_sprites.inc graphics/num_sprites.inc
ca65 -o duck_pond.o duck_pond.s -l duck_pond.lst

View File

@ -15,19 +15,29 @@ draw_duck1:
bmi duck1_draw_right
duck1_draw_left:
lda #<d1_left1_mask
sta MASKL
lda #>d1_left1_mask
sta MASKH
lda #<d1_left1_sprite
sta INL
lda #>d1_left1_sprite
jmp do_draw_duck1
duck1_draw_right:
lda #<d1_right1_mask
sta MASKL
lda #>d1_right1_mask
sta MASKH
lda #<d1_right1_sprite
sta INL
lda #>d1_right1_sprite
do_draw_duck1:
sta INH
jsr gr_put_sprite
jsr gr_put_sprite_mask
done_draw_duck1:
rts
@ -51,19 +61,29 @@ draw_duck2:
bmi duck2_draw_right
duck2_draw_left:
lda #<d2_left1_mask
sta MASKL
lda #>d2_left1_mask
sta MASKH
lda #<d2_left1_sprite
sta INL
lda #>d2_left1_sprite
jmp do_draw_duck2
duck2_draw_right:
lda #<d2_right1_mask
sta MASKL
lda #>d2_right1_mask
sta MASKH
lda #<d2_right1_sprite
sta INL
lda #>d2_right1_sprite
do_draw_duck2:
sta INH
jsr gr_put_sprite
jsr gr_put_sprite_mask
done_draw_duck2:
rts

View File

@ -190,7 +190,7 @@ done_loop:
.include "gr_copy.s"
.include "gr_offsets.s"
.include "gr_putsprite.s"
.include "gr_putsprite_mask.s"
.include "gr_pageflip.s"
.include "duck_score.s"

View File

@ -2,13 +2,14 @@
draw_score:
ldy #0
lda #42
sta YPOS
ldx #10
draw_score_1_loop:
lda #42
sta YPOS
lda score_xpos,Y
sta XPOS
@ -17,12 +18,18 @@ draw_score_1_loop:
lda score1_h,Y
sta INH
lda mask1_l,Y
sta MASKL
lda mask1_h,Y
sta MASKH
txa
pha
tya
pha
jsr gr_put_sprite
jsr gr_put_sprite_mask
pla
tay
@ -62,6 +69,34 @@ score2_h:
.byte >four_sprite
.byte >zero_sprite
mask1_l:
.byte <d_mask
.byte <one_mask
.byte <colon_mask
.byte <space_mask
.byte <zero_mask
mask2_l:
.byte <d_mask
.byte <two_mask
.byte <colon_mask
.byte <four_mask
.byte <zero_mask
mask1_h:
.byte >d_mask
.byte >one_mask
.byte >colon_mask
.byte >space_mask
.byte >zero_mask
mask2_h:
.byte >d_mask
.byte >two_mask
.byte >colon_mask
.byte >four_mask
.byte >zero_mask
score_xpos:
.byte 1, 5, 8,11,15
.byte 22,26,29,32,36
@ -93,6 +128,10 @@ update_d1_score:
sta score1_l+4
lda number_sprites_h,Y
sta score1_h+4
lda number_masks_l,Y
sta mask1_l+4
lda number_masks_h,Y
sta mask1_h+4
; check if leading zero
@ -108,6 +147,12 @@ update_d1_score:
sta score1_l+3
lda #>space_sprite
sta score1_h+3
lda #<space_mask
sta mask1_l+3
lda #>space_mask
sta mask1_h+3
jmp done_d1_score
d1_score_no_lead_zero:
@ -123,6 +168,12 @@ d1_score_no_lead_zero:
lda number_sprites_h,Y
sta score1_h+3
lda number_masks_l,Y
sta mask1_l+3
lda number_masks_h,Y
sta mask1_h+3
done_d1_score:
@ -153,4 +204,29 @@ number_sprites_h:
.byte >eight_sprite
.byte >nine_sprite
number_masks_l:
.byte <zero_mask
.byte <one_mask
.byte <two_mask
.byte <three_mask
.byte <four_mask
.byte <five_mask
.byte <six_mask
.byte <seven_mask
.byte <eight_mask
.byte <nine_mask
number_masks_h:
.byte >zero_mask
.byte >one_mask
.byte >two_mask
.byte >three_mask
.byte >four_mask
.byte >five_mask
.byte >six_mask
.byte >seven_mask
.byte >eight_mask
.byte >nine_mask

View File

@ -1,105 +1,72 @@
;==============
;===============
; gr_put_sprite
;==============
; Sprite to display in INH,INL
;===============
; Sprite to display in INL/INH
; MASK (for transparency) on MASKL/MASH
; Location is XPOS,YPOS
; Note, only works if YPOS is multiple of two
gr_put_sprite:
; trashes A,X,Y
ldy #0 ; byte 0 is xsize ; 2
lda (INL),Y ; 5
sta CH ; xsize is in CH ; 3
iny ; 2
gr_put_sprite:
ldy #0
lda (INL),Y ; xsize
clc
adc XPOS
sta XMAX
sta gps_xmax_smc+1 ; store xmas (self-modify)
lda (INL),Y ; byte 1 is ysize ; 5
sta CV ; ysize is in CV ; 3
iny ; 2
lda YPOS ; make a copy of ypos ; 3
sta TEMPY ; as we modify it ; 3
;===========
; 28
lda (INL),Y ; ysize
asl ; mul by 2
clc
adc YPOS
sta gps_ymax_smc+1
iny
tya
tax
lda INL
sta gps_src_smc+1
lda INH
sta gps_src_smc+2
gr_put_sprite_loop:
sty TEMP ; save sprite pointer ; 3
ldy TEMPY ; 3
bpl put_sprite_raw_pos ; if < 0, skip to next
clc ; skip line in sprite too
lda TEMP
adc CH
tay
bne raw_increment_y
put_sprite_raw_pos:
psr_smc1:
cpy #48 ; bge if >= 48, done sprite
bcs raw_sprite_done
ldy YPOS
lda gr_offsets,Y
sta OUTL
lda gr_offsets+1,Y
clc
adc DRAW_PAGE
sta OUTH
lda gr_offsets,Y ; lookup low-res memory address ; 4
clc ; 2
adc XPOS ; add in xpos ; 3
sta OUTL ; store out low byte of addy ; 3
clc ; never wraps, handle negative
lda gr_offsets+1,Y ; look up high byte ; 4
adc DRAW_PAGE ; ; 3
sta OUTH ; and store it out ; 3
ldy TEMP ; restore sprite pointer ; 3
ldy XPOS
gr_put_sprite_row:
cpy #40
bcs gr_put_sprite_dont_draw ; don't draw if out of bounds
; OUTH:OUTL now points at right place
gps_src_smc:
lda $f000,X
sta (OUTL),Y
ldx XPOS ; load xposition into x ; 3
;===========
; 34
raw_put_sprite_pixel:
lda (INL),Y ; get sprite colors ; 5
iny ; increment sprite pointer ; 2
sty TEMP ; save sprite pointer ; 3
gr_put_sprite_dont_draw:
iny
inx
gps_xmax_smc:
cpy #40
bne gr_put_sprite_row
inc YPOS
inc YPOS
lda YPOS
gps_ymax_smc:
cmp #40
cpx #0 ; if off-screen left, skip draw
bmi skip_drawing
cpx #40
bcs skip_drawing ; if off-screen right, skip draw
bne gr_put_sprite_loop
ldy #$0 ; 2
sta COLOR ; save color for later ; 3
; check if top pixel transparent
raw_put_sprite_all:
lda COLOR ; load color ; 3
sta (OUTL),Y ; and write it out ; 6
;============
; 9
raw_put_sprite_done_draw:
skip_drawing:
ldy TEMP ; restore sprite pointer ; 3
inc OUTL ; increment output pointer ; 5
inx ; increment x counter ; 2
cpx XMAX
bne raw_put_sprite_pixel ; if not done, keep looping ; 2nt/3
;==============
; 12/13
raw_increment_y:
inc TEMPY ; each line has two y vars ; 5
inc TEMPY ; 5
dec CV ; decemenet total y count ; 5
bne gr_put_sprite_loop ; loop if not done ; 2nt/3
;==============
; 17/18
raw_sprite_done:
gr_put_sprite_done:
rts ; return ; 6

View File

@ -0,0 +1,86 @@
;====================
; gr_put_sprite_mask
;====================
; Sprite to display in INL/INH
; MASK (for transparency) on MASKL/MASH
; Location is XPOS,YPOS
; Note, only works if YPOS is multiple of two
; trashes A,X,Y
gr_put_sprite_mask:
ldy #0
lda (INL),Y ; xsize
clc
adc XPOS
sta gps_xmax_smc+1 ; store xmas (self-modify)
iny ; 2
lda (INL),Y ; ysize
asl ; mul by 2
clc
adc YPOS
sta gps_ymax_smc+1
iny
tya
tax
lda INL
sta gps_src_smc+1
lda INH
sta gps_src_smc+2
lda MASKL
sta gps_mask_smc+1
lda MASKH
sta gps_mask_smc+2
gr_put_sprite_loop:
ldy YPOS
lda gr_offsets,Y
sta OUTL
lda gr_offsets+1,Y
clc
adc DRAW_PAGE
sta OUTH
ldy XPOS
gr_put_sprite_row:
cpy #40
bcs gr_put_sprite_dont_draw ; don't draw if out of bounds
; put the pixel
; based on monitor plot code
lda (OUTL),Y
gps_src_smc:
eor $f000,X ; load sprite data
gps_mask_smc:
and $f000,X
eor (OUTL),Y
sta (OUTL),Y
gr_put_sprite_dont_draw:
iny
inx
gps_xmax_smc:
cpy #40
bne gr_put_sprite_row
inc YPOS
inc YPOS
lda YPOS
gps_ymax_smc:
cmp #40
bne gr_put_sprite_loop
gr_put_sprite_done:
rts ; return ; 6

View File

@ -33,6 +33,20 @@ num_sprites.inc: lores_font.png
$(PNG2SPRITES) lores_font.png colon_sprite 8 6 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png d_sprite 12 6 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png space_sprite 16 6 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png zero_mask 0 14 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png one_mask 4 14 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png two_mask 8 14 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png three_mask 12 14 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png four_mask 16 14 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png five_mask 20 14 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png six_mask 24 14 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png seven_mask 28 14 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png eight_mask 0 20 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png nine_mask 4 20 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png colon_mask 8 20 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png d_mask 12 20 3 6 >> num_sprites.inc
$(PNG2SPRITES) lores_font.png space_mask 16 20 3 6 >> num_sprites.inc
####

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 756 B

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -162,8 +162,10 @@ XPOS = $F0
YPOS = $F1
XMAX = $F2
TEMP = $FA
TEMPY = $FB
TEMP = $F8
TEMPY = $F9
MASKL = $FA
MASKH = $FB
INL = $FC
INH = $FD
OUTL = $FE