cliff: start re-writing the peasant sprite code

This commit is contained in:
Vince Weaver 2024-08-30 02:21:26 -04:00
parent f3803fb655
commit 55955b22e6
7 changed files with 409 additions and 48 deletions

View File

@ -28,10 +28,12 @@ CLIFF: cliff.o
ld65 -o CLIFF cliff.o -C $(LINKER_SCRIPTS)/apple2_6000.inc
cliff.o: cliff.s zx02_optim.s \
move_peasant.s draw_peasant.s \
hgr_copy.s hgr_partial_restore.s \
hgr_sprite.s \
hgr_sprite.s hgr_sprite_bg_mask.s \
cliff_graphics/cliff_base.hgr.zx02 \
sprites/enemy_sprites.inc \
sprites/walk_sprites.inc \
zp.inc hardware.inc
ca65 -o cliff.o cliff.s -l cliff.lst

View File

@ -359,12 +359,12 @@ done_cliff:
.include "hgr_partial_restore.s"
.include "hgr_1x28_sprite_mask.s"
.include "gr_copy.s"
.include "hgr_copy.s"
.include "cliff_graphics/peasant_robe_sprites.inc"
; .include "cliff_graphics/peasant_robe_sprites.inc"
bg_data:
.incbin "cliff_graphics/cliff_base.hgr.zx02"
@ -431,13 +431,13 @@ sprites_mask_h:
; currently 4, should check this and error if we overflow
save_xstart:
.byte 0, 0, 0, 0
.byte 0, 0, 0, 0, 0
save_xend:
.byte 0, 0, 0, 0
.byte 0, 0, 0, 0, 0
save_ystart:
.byte 0, 0, 0, 0
.byte 0, 0, 0, 0, 0
save_yend:
.byte 0, 0, 0, 0
.byte 0, 0, 0, 0, 0
;========================================
@ -458,3 +458,62 @@ rock_x:
rock_y:
.byte 12,12,12
.include "hgr_sprite_bg_mask.s"
.include "sprites/walk_sprites.inc"
walk_sprites_xsize:
.byte 2, 2, 2, 2, 2, 2 ; right
.byte 2, 2, 2, 2, 2, 2 ; left
.byte 2, 2, 2, 2, 2, 2 ; up
.byte 2, 2, 2, 2, 2, 2 ; down
walk_sprites_ysize:
.byte 30, 30, 30, 30, 30, 30 ; right
.byte 30, 30, 30, 30, 30, 30 ; left
.byte 30, 30, 30, 30, 30, 30 ; up
.byte 30, 30, 30, 30, 30, 30 ; down
walk_sprites_data_l:
.byte <walk_r0_sprite,<walk_r1_sprite,<walk_r2_sprite
.byte <walk_r3_sprite,<walk_r4_sprite,<walk_r5_sprite
.byte <walk_l0_sprite,<walk_l1_sprite,<walk_l2_sprite
.byte <walk_l3_sprite,<walk_l4_sprite,<walk_l5_sprite
.byte <walk_u0_sprite,<walk_u1_sprite,<walk_u2_sprite
.byte <walk_u3_sprite,<walk_u4_sprite,<walk_u5_sprite
.byte <walk_d0_sprite,<walk_d1_sprite,<walk_d2_sprite
.byte <walk_d3_sprite,<walk_d4_sprite,<walk_d5_sprite
walk_sprites_data_h:
.byte >walk_r0_sprite,>walk_r1_sprite,>walk_r2_sprite
.byte >walk_r3_sprite,>walk_r4_sprite,>walk_r5_sprite
.byte >walk_l0_sprite,>walk_l1_sprite,>walk_l2_sprite
.byte >walk_l3_sprite,>walk_l4_sprite,>walk_l5_sprite
.byte >walk_u0_sprite,>walk_u1_sprite,>walk_u2_sprite
.byte >walk_u3_sprite,>walk_u4_sprite,>walk_u5_sprite
.byte >walk_d0_sprite,>walk_d1_sprite,>walk_d2_sprite
.byte >walk_d3_sprite,>walk_d4_sprite,>walk_d5_sprite
walk_mask_data_l:
.byte <walk_r0_mask,<walk_r1_mask,<walk_r2_mask
.byte <walk_r3_mask,<walk_r4_mask,<walk_r5_mask
.byte <walk_l0_mask,<walk_l1_mask,<walk_l2_mask
.byte <walk_l3_mask,<walk_l4_mask,<walk_l5_mask
.byte <walk_u0_mask,<walk_u1_mask,<walk_u2_mask
.byte <walk_u3_mask,<walk_u4_mask,<walk_u5_mask
.byte <walk_d0_mask,<walk_d1_mask,<walk_d2_mask
.byte <walk_d3_mask,<walk_d4_mask,<walk_d5_mask
walk_mask_data_h:
.byte >walk_r0_mask,>walk_r1_mask,>walk_r2_mask
.byte >walk_r3_mask,>walk_r4_mask,>walk_r5_mask
.byte >walk_l0_mask,>walk_l1_mask,>walk_l2_mask
.byte >walk_l3_mask,>walk_l4_mask,>walk_l5_mask
.byte >walk_u0_mask,>walk_u1_mask,>walk_u2_mask
.byte >walk_u3_mask,>walk_u4_mask,>walk_u5_mask
.byte >walk_d0_mask,>walk_d1_mask,>walk_d2_mask
.byte >walk_d3_mask,>walk_d4_mask,>walk_d5_mask

View File

@ -34,15 +34,11 @@ peasant_up:
beq peasant_up1
peasant_up2:
lda #<peasant_up2_sprite
sta INL
lda #>peasant_up2_sprite
ldx #13
jmp done_pick_draw
peasant_up1:
lda #<peasant_up1_sprite
sta INL
lda #>peasant_up1_sprite
ldx #12
jmp done_pick_draw
;=====================
@ -54,15 +50,11 @@ peasant_down:
beq peasant_down1
peasant_down2:
lda #<peasant_down2_sprite
sta INL
lda #>peasant_down2_sprite
ldx #19
jmp done_pick_draw
peasant_down1:
lda #<peasant_down1_sprite
sta INL
lda #>peasant_down1_sprite
ldx #18
jmp done_pick_draw
;=====================
@ -74,15 +66,11 @@ peasant_left:
bne draw_left1
draw_left2:
lda #<peasant_left2_sprite
sta INL
lda #>peasant_left2_sprite
ldx #7
jmp done_pick_draw
draw_left1:
lda #<peasant_left1_sprite
sta INL
lda #>peasant_left1_sprite
ldx #6
jmp done_pick_draw
@ -92,25 +80,18 @@ peasant_right:
bne draw_right1
draw_right2:
lda #<peasant_right2_sprite
sta INL
lda #>peasant_right2_sprite
ldx #1
jmp done_pick_draw
draw_right1:
lda #<peasant_right1_sprite
sta INL
lda #>peasant_right1_sprite
ldx #0
done_pick_draw:
sta INH
jsr hgr_draw_sprite_1x28
jsr hgr_draw_sprite_bg_mask
done_draw_peasant:
rts
;.include "sprites/peasant_sprites.inc"
;.include "sprites/peasant_robe_sprites.inc"

View File

@ -130,8 +130,8 @@ osprite_smc1:
hgr_draw_sprite_both:
lda (GBASL),Y ; load bg
backup_sprite_smc1:
sta $f000,X
;backup_sprite_smc1:
; sta $f000,X
eor TEMP_SPRITE
and TEMP_MASK

View File

@ -0,0 +1,317 @@
;===============================================
; hgr draw sprite, with bg mask in GR $400
;===============================================
; used primarily to draw Rather Dashing
;===============================================
; attempts to shift for odd/even column
; cannot handle sprites bigger than 256 bytes
;
; Location at CURSOR_X CURSOR_Y
; for now, BG mask is only all or nothing
; so we just skip drawing if behind
; X is sprite to draw
; Y is save slot
hgr_draw_sprite_bg_mask:
ldy #4 ; FIXME
lda CURSOR_X
sta save_xstart,Y
lda CURSOR_Y
sta save_ystart,Y
lda walk_sprites_xsize,X
clc
adc CURSOR_X
sta hdsb_width_smc+1
sta save_xend,Y
lda walk_sprites_ysize,X
sta hdsb_ysize_smc+1
sta save_yend,Y
lda #0
sta MASK_COUNTDOWN
; calculate peasant priority
; based on head
lda PEASANT_Y
sec
sbc #48 ; Y=48
lsr ; div by 8
lsr
lsr
clc
adc #2
sta PEASANT_PRIORITY
; set up sprite pointers
lda walk_sprites_data_l,X
sta h728_smc1+1
lda walk_sprites_data_h,X
sta h728_smc1+2
; set up mask pointers
lda walk_mask_data_l,X
sta h728_smc3+1
lda walk_mask_data_h,X
sta h728_smc3+2
ldx #0 ; X is row counter
stx CURRENT_ROW
hgr_sprite_bm_yloop:
lda MASK_COUNTDOWN
and #$3 ; only update every 4th
bne mask_good
txa
pha ; save X
; recalculate mask
txa
clc
adc CURSOR_Y
tax
ldy CURSOR_X
jsr update_bg_mask
pla ; restore X
tax
mask_good:
lda MASK
bne draw_sprite_skip
lda CURRENT_ROW
clc
adc CURSOR_Y ; add in cursor_y
; calc GBASL/GBASH
tay ; get output ROW into GBASL/H
lda hposn_low,Y
sta GBASL
lda hposn_high,Y
sta GBASH
ldy CURSOR_X
lda #0
sta SPRITE_TEMP
sta MASK_TEMP
hsbm_inner_loop:
h728_smc1:
lda $d000,X ; or in sprite
sta TEMP_SPRITE
h728_smc3:
lda $d000,X ; mask with sprite mask
sta TEMP_MASK
hsbm_draw_sprite_both:
lda (GBASL),Y ; load background
eor TEMP_SPRITE
and TEMP_MASK
eor (GBASL),Y ; store out
sta (GBASL),Y ; store out
draw_sprite_skip:
inx
iny
hdsb_width_smc:
cpy #6
bne hsbm_inner_loop
inc MASK_COUNTDOWN
inc CURRENT_ROW
lda CURRENT_ROW
hdsb_ysize_smc:
cmp #28
bne hgr_sprite_bm_yloop
rts
;======================
; restore bg 1x28
;======================
restore_bg_1x28:
; restore bg behind peasant
; is this actually faster than using the generic version?
ldy CURSOR_Y ; y start point
ldx #27 ; height
restore_yloop:
; calc GBASL/GBASH using lookup table
clc
lda hposn_low,Y
adc PEASANT_X
sta restore_page1_smc+1
sta restore_page2_smc+1
; $40 -> $20 0100 0000 -> 0010 0000
; $41 -> $21 0100 0001 -> 0010 0001
; $51 -> $31 0101 0011 -> 0101 0001
lda hposn_high,Y
sta restore_page2_smc+2
eor #$60
sta restore_page1_smc+2
restore_page1_smc:
lda $DDDD
restore_page2_smc:
sta $DDDD
iny
dex
bpl restore_yloop
rts
;===================
; update_bg_mask
;===================
; newx/7 in Y
; newy in X
; updates MASK
update_bg_mask:
; rrrr rtii top 5 bits row, bit 2 top/bottom
sty xsave
mask_try_again:
stx ysave
txa
and #$04 ; see if odd/even
beq bg_mask_even
bg_mask_odd:
lda #$f0
bne bg_mask_mask ; bra
bg_mask_even:
lda #$0f
bg_mask_mask:
sta MASK
txa
lsr
lsr ; need to divide by 8 then * 2
lsr ; can't just div by 4 as we need to mask bottom bit
asl
tax
lda gr_offsets,X
sta BASL
lda gr_offsets+1,X
sta BASH
lda (BASL),Y
ldy MASK
cpy #$f0
bne mask_bottom
mask_top:
lsr
lsr
lsr
lsr
jmp mask_mask_mask
mask_bottom:
and #$0f
mask_mask_mask:
sta MASK
cmp #$0 ; 0 means collision, find mask
bne mask_not_zero ; by iteratively going down till
ldx ysave ; non-zero
ldy xsave
inx
inx
inx
inx
jmp mask_try_again
mask_not_zero:
cmp #$f ; priority F means always on top
beq mask_true
cmp PEASANT_PRIORITY
beq mask_false ; branch less than equal
bcc mask_false ; blt
mask_true:
lda #$ff
sta MASK
rts
mask_false:
lda #$00
sta MASK
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; priorities
; 0 = collision
; 1 = bg = always draw ; Y-48
; 2 0-55
; 3 56-63 ; 8/8+2 = 3
; 4 64-71 ; 16/8+2 = 4
; 5 72-79
; 6 80-87 ; 32/8+2 = 6
; 7 88-95
; 8 96-103
; 9 104-111
; 10 112-119
; 11 120-127
; 12 128-135 ; 8
; 13 136-143
; 14 144-151
; 15 = fg = always hide
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;====================
; save area
;====================
;save_sprite_1x28:
;.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
;.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
ysave:
.byte $00
xsave:
.byte $00

View File

@ -154,10 +154,12 @@ peasant_the_same:
; restore bg behind peasant
erase_peasant:
.if 1
lda PEASANT_Y
sta SAVED_Y1
clc
adc #28
adc #30
sta SAVED_Y2
ldx PEASANT_X
@ -165,7 +167,7 @@ erase_peasant:
inx
jmp hgr_partial_restore ; tail call
.endif

View File

@ -70,18 +70,18 @@ walk_sprites.inc: walk_sprites.png
$(HGR_SPRITE) -l walk_u4_mask walk_sprites.png 182 94 195 124 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_u5_sprite walk_sprites.png 210 63 223 93 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_u5_mask walk_sprites.png 210 94 223 124 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d0_sprite walk_sprites.png 238 63 252 93 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d0_sprite walk_sprites.png 238 63 251 93 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d0_mask walk_sprites.png 238 94 251 124 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d1_sprite walk_sprites.png 266 63 279 93 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d1_mask walk_sprites.png 266 94 278 124 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d1_mask walk_sprites.png 266 94 279 124 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d2_sprite walk_sprites.png 182 128 195 158 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d2_mask walk_sprites.png 182 159 251 189 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d3_sprite walk_sprites.png 210 128 195 158 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d3_mask walk_sprites.png 210 159 251 189 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d4_sprite walk_sprites.png 238 128 195 158 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d2_mask walk_sprites.png 182 159 195 189 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d3_sprite walk_sprites.png 210 128 223 158 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d3_mask walk_sprites.png 210 159 223 189 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d4_sprite walk_sprites.png 238 128 251 158 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d4_mask walk_sprites.png 238 159 251 189 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d5_sprite walk_sprites.png 266 128 195 158 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d5_mask walk_sprites.png 266 159 251 189 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d5_sprite walk_sprites.png 266 128 279 158 >> walk_sprites.inc
$(HGR_SPRITE) -l walk_d5_mask walk_sprites.png 266 159 279 189 >> walk_sprites.inc