From 996c5ea02360a9bfdc8774454d5ec5fa8092eb45 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 11 Sep 2024 20:29:06 -0400 Subject: [PATCH] peasant: missed a file --- games/peasant/hgr_sprite_bg_mask.s | 391 +++++++++++++++++++++++++++++ 1 file changed, 391 insertions(+) create mode 100644 games/peasant/hgr_sprite_bg_mask.s diff --git a/games/peasant/hgr_sprite_bg_mask.s b/games/peasant/hgr_sprite_bg_mask.s new file mode 100644 index 00000000..90df73ef --- /dev/null +++ b/games/peasant/hgr_sprite_bg_mask.s @@ -0,0 +1,391 @@ + ;=============================================== + ; hgr draw sprite, with bg mask in GR $400 + ;=============================================== + ; used primarily to draw Rather Dashing + ;=============================================== + ; *cannot* handle sprites bigger than 256 bytes + ; + ; attempts to shift for odd/even column + ; ideally sprite palette has precedence over background + ; if completely transparent then let bg keep palette + + ; Location at CURSOR_X CURSOR_Y + + ; for now, BG mask is only all or nothing (from LORES) + ; so we just skip drawing if behind + ; this version handles arbitrary width sprites, which complicates + ; things + + ; X is sprite to draw + + ; Y is save slot + +hgr_draw_sprite_bg_mask: + +; ldy #4 ; FIXME, should be proper save slot + + ; save info on background to restore + + lda CURSOR_X + sta save_xstart,Y + + lda CURSOR_Y + sta save_ystart,Y + + ; calculate end of sprite on screen for Xpos loop + ; also save for background restore + + lda peasant_sprites_xsize,X + clc + adc CURSOR_X + sta hdsb_width_smc+1 + sta save_xend,Y + + ; calculate bottom of sprite for Ypos loop + ; also save for background restore + + lda peasant_sprites_ysize,X + sta hdsb_ysize_smc+1 + clc + adc CURSOR_Y + sta save_yend,Y + + ; set up mask countdown value + + lda #0 + sta MASK_COUNTDOWN + + ; calculate peasant priority + ; based on head location + ; see chart later + + lda CURSOR_Y + sec + sbc #48 ; Y=48 + lsr ; div by 8 + lsr + lsr + clc + adc #2 + sta PEASANT_PRIORITY + + ; set up sprite pointers + lda peasant_sprites_data_l,X + sta h728_smc1+1 + sta h728_smc2+1 + lda peasant_sprites_data_h,X + sta h728_smc1+2 + sta h728_smc2+2 + + ; set up mask pointers + lda peasant_mask_data_l,X + sta h728_smc3+1 + sta h728_smc4+1 + lda peasant_mask_data_h,X + sta h728_smc3+2 + sta h728_smc4+2 + + ;=============================== + ; main loop + ; X = row counter at times (CURRENT_ROW is real one) + ; Y = col counter + + ldx #0 ; X is sprite counter + stx CURRENT_ROW ; zero row counter + +hgr_sprite_bm_yloop: + lda MASK_COUNTDOWN ; FIXME is this same as CURRENT_ROW + + and #$3 ; only update every 4th + bne mask_good + + + ;====================== + ; recalculate mask + + txa + pha ; save sprite counter + + lda CURRENT_ROW + clc + adc CURSOR_Y + tax ; X has row + + ldy CURSOR_X ; Y has column + ; FIXME: we have multi-width now + jsr update_bg_mask + + pla ; restore sprite counter + tax + +mask_good: + + 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 ; always page2 + + + ;============================ + ; set up inner loop + + ldy CURSOR_X + + lda #0 + sta SPRITE_TEMP + sta MASK_TEMP + +hsbm_inner_loop: + + + + lda MASK + bne draw_sprite_skip + + ;============================ + ; not masked so actually draw + + ;========================= + ; pick if even or odd + + lda CURSOR_X + ror + bcs hsbm_draw_sprite_odd + + ;============================ + +hsbm_draw_sprite_even: + +h728_smc1: + lda $d000,X ; load sprite value + sta TEMP_SPRITE +h728_smc3: + lda $d000,X ; load mask value + + jmp hsbm_draw_sprite_both + + +hsbm_draw_sprite_odd: + +h728_smc2: + lda $f000,X ; load sprite data + + ; PSSS SSSS + ; rol C=P, SSSS SSST + + ; want to set bit7 to C? + + rol SPRITE_TEMP + rol + sta SPRITE_TEMP + bcc hsbm_pal0 +hsbm_pal1: + ora #$80 ; set pal bit + bne hsbm_pal_done +hsbm_pal0: + and #$7f ; clear pal bit + +hsbm_pal_done: + sta TEMP_SPRITE + +h728_smc4: + lda $f000,X ; load sprite data + + rol MASK_TEMP + rol + sta MASK_TEMP + +hsbm_draw_sprite_both: + eor #$FF + and #$7F + sta TEMP_MASK + + ; if mask is $7f then skip drawing + cmp #$7f + beq draw_sprite_skip + + ; do actual sprite-ing + + lda (GBASL),Y ; load background + and TEMP_MASK + ora TEMP_SPRITE + + sta (GBASL),Y ; store out + +draw_sprite_skip: + + inx ; increment sprite pointer + iny ; increment column + + + + +hdsb_width_smc: + cpy #6 + bne hsbm_inner_loop + + + + inc MASK_COUNTDOWN ; increment row + + inc CURRENT_ROW + lda CURRENT_ROW + +hdsb_ysize_smc: + cmp #28 + bne hgr_sprite_bm_yloop + + rts + + + ;=================== + ; update_bg_mask + ;=================== + ; Column (xpos/7) in Y + ; Row 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 in the lo-res lookup + beq bg_mask_even + + ; setup mask based on odd/even + +bg_mask_odd: + lda #$f0 + bne bg_mask_mask ; bra + +bg_mask_even: + lda #$0f +bg_mask_mask: + sta MASK + + ; X is current row here + + ; converting to which row in lores + ; 0 -> 0 low + ; 4 -> 0 high + ; 8 -> 1 low + ; .... + ; 191 -> 23 high + + 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 ; because our lookup is multiple of two + tax + + ; set up row for mask lookup + + lda gr_offsets,X + sta BASL + lda gr_offsets+1,X + sta BASH + + ; read out current mask color + + lda (BASL),Y + + ; get high/low properly + + 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 + + ; special cases? + + cmp #$0 ; 0 means collision, find mask + bne mask_not_zero ; by iteratively going down till + + ; mask 0 here, which means can't walk there but doesn't give + ; prioirty. This can happen if there's a don't walk spot + ; above you even if not on it. In this case, find the actual + ; mask by looking down the screen until we find an actual + ; proper mask value + + ldy xsave + + ldx ysave ; move to next lower lookup value + 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 +;==================== + +ysave: +.byte $00 +xsave: +.byte $00