mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-11-01 01:06:33 +00:00
206 lines
3.3 KiB
ArmAsm
206 lines
3.3 KiB
ArmAsm
;===========================================
|
|
; hgr draw sprite (only at 7-bit boundaries)
|
|
;===========================================
|
|
; can handle sprites bigger than a 256 byte page
|
|
|
|
; Note this is optimized for blue/orange sprites
|
|
; it treats black0 as transparent
|
|
|
|
; SPRITE in INL/INH
|
|
; Location at SPRITE_X SPRITE_Y
|
|
|
|
; xsize, ysize in first two bytes
|
|
|
|
; sprite AT INL/INH
|
|
|
|
|
|
; orange = color5 1 101 0101 1 010 1010
|
|
|
|
hgr_draw_sprite_big:
|
|
lda SPRITE_X
|
|
ror
|
|
bcs hgr_draw_sprite_big_odd
|
|
|
|
hgr_draw_sprite_big_even:
|
|
ldy #0
|
|
lda (INL),Y ; load xsize
|
|
clc
|
|
adc SPRITE_X
|
|
sta big_sprite_width_end_smc+1 ; self modify for end of line
|
|
|
|
iny ; load ysize
|
|
lda (INL),Y
|
|
sta big_sprite_ysize_smc+1 ; self modify
|
|
|
|
; point smc to sprite
|
|
lda INL ; 16-bit add
|
|
sta big_sprite_smc1+1
|
|
lda INH
|
|
sta big_sprite_smc1+2
|
|
|
|
|
|
ldx #0 ; X is pointer offset
|
|
stx CURRENT_ROW ; actual row
|
|
|
|
ldx #2
|
|
|
|
hgr_big_sprite_yloop:
|
|
|
|
lda CURRENT_ROW ; row
|
|
|
|
clc
|
|
adc SPRITE_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
|
|
|
|
clc
|
|
adc DRAW_PAGE
|
|
sta GBASH
|
|
|
|
ldy SPRITE_X
|
|
|
|
big_sprite_inner_loop:
|
|
|
|
|
|
big_sprite_smc1:
|
|
lda $f000,X ; load sprite data
|
|
beq big_sprite_transparent
|
|
sta (GBASL),Y ; store to screen
|
|
|
|
big_sprite_transparent:
|
|
inx ; increment sprite offset
|
|
|
|
; if > 1 page
|
|
bne big_sprite_no_page_cross
|
|
inc big_sprite_smc1+2
|
|
|
|
big_sprite_no_page_cross:
|
|
iny ; increment output position
|
|
|
|
|
|
big_sprite_width_end_smc:
|
|
cpy #6 ; see if reached end of row
|
|
bne big_sprite_inner_loop ; if not, loop
|
|
|
|
|
|
inc CURRENT_ROW ; row
|
|
lda CURRENT_ROW ; row
|
|
|
|
big_sprite_ysize_smc:
|
|
cmp #31 ; see if at end
|
|
bne hgr_big_sprite_yloop ; if not, loop
|
|
|
|
rts
|
|
|
|
|
|
|
|
hgr_draw_sprite_big_odd:
|
|
ldy #0
|
|
lda (INL),Y ; load xsize
|
|
clc
|
|
adc SPRITE_X
|
|
sta osprite_width_end_smc+1 ; self modify for end of line
|
|
|
|
iny ; load ysize
|
|
lda (INL),Y
|
|
sta osprite_ysize_smc+1 ; self modify
|
|
|
|
; point smc to sprite
|
|
lda INL ; 16-bit add
|
|
sta osprite_smc1+1
|
|
lda INH
|
|
sta osprite_smc1+2
|
|
|
|
|
|
ldx #0 ; X is pointer offset
|
|
stx CURRENT_ROW ; actual row
|
|
|
|
ldx #2
|
|
|
|
ohgr_sprite_yloop:
|
|
|
|
lda CURRENT_ROW ; row
|
|
|
|
clc
|
|
adc SPRITE_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
|
|
|
|
clc
|
|
adc DRAW_PAGE
|
|
sta GBASH
|
|
|
|
ldy SPRITE_X
|
|
|
|
clc
|
|
php ; store 0 carry on stack
|
|
|
|
osprite_inner_loop:
|
|
|
|
|
|
osprite_smc1:
|
|
lda $f000,X ; load sprite data
|
|
|
|
bne osprite_not_transparent
|
|
|
|
; we can't just skip if 0 because we might shift a bit in
|
|
; from previous byte
|
|
|
|
plp
|
|
bcs osprite_oops
|
|
clc
|
|
php
|
|
bcc osprite_transparent_done
|
|
|
|
osprite_not_transparent:
|
|
plp ; restore carry from last
|
|
osprite_oops:
|
|
rol ; rotate in carry
|
|
asl ; one more time, bit6 in carry
|
|
php ; save on stack
|
|
sec ; assume blur/orange
|
|
ror ; rotate it back down
|
|
|
|
sta (GBASL),Y ; store to screen
|
|
|
|
|
|
osprite_transparent_done:
|
|
inx ; increment sprite offset
|
|
|
|
; if > 1 page
|
|
bne osprite_no_page_cross
|
|
inc osprite_smc1+2
|
|
|
|
osprite_no_page_cross:
|
|
|
|
iny ; increment output position
|
|
|
|
|
|
|
|
osprite_width_end_smc:
|
|
cpy #6 ; see if reached end of row
|
|
bne osprite_inner_loop ; if not, loop
|
|
|
|
|
|
plp ; restore stack
|
|
|
|
inc CURRENT_ROW ; row
|
|
lda CURRENT_ROW ; row
|
|
|
|
osprite_ysize_smc:
|
|
cmp #31 ; see if at end
|
|
bne ohgr_sprite_yloop ; if not, loop
|
|
|
|
rts
|
|
|