dos33fsprogs/games/keen/draw_tilemap.s

234 lines
4.3 KiB
ArmAsm
Raw Normal View History

2024-03-10 05:44:20 +00:00
;================================
; draw local tilemap to screen
;================================
2024-03-13 04:46:34 +00:00
; tilemap is 20x12 grid with 2x4 (well, 2x2) tiles
2024-03-10 05:44:20 +00:00
draw_tilemap:
ldx #0 ; offset in current tilemap ; 2
stx TILEMAP_OFFSET ; ; 3
2024-03-10 05:44:20 +00:00
; ldy #0 ; current screen Ypos to draw at ; 2
stx TILEY ; (we draw two at a time as lores ; 3
; is two blocks per byte)
2024-03-10 05:44:20 +00:00
; lda #0 ; init odd/even ; 2
stx TILE_ODD ; (tiles are two rows tall) ; 3
2024-03-10 05:44:20 +00:00
tilemap_outer_loop:
ldy TILEY ; setup output pointer to current Ypos ; 3
2024-03-14 04:08:19 +00:00
lda gr_offsets,Y ; get address of start of row ; 4+
sta GBASL ; 3
lda gr_offsets+1,Y ; 4+
clc ; 2
adc DRAW_PAGE ; adjust for page ; 3
sta GBASH ; 3
2024-03-10 05:44:20 +00:00
2024-03-13 04:46:34 +00:00
ldy #0 ; draw row from 0..39 ; 2
; might be faster to count backwards
; but would have to adjust a lot
2024-03-14 04:08:19 +00:00
2024-03-10 05:44:20 +00:00
tilemap_loop:
ldx TILEMAP_OFFSET ; get actual tile number ; 3
lda small_tilemap,X ; from tilemap ; 4
2024-03-10 05:44:20 +00:00
asl ; *4 ; point to tile to draw (4 bytes each) ; 2
asl ; 2
tax ; 2
2024-03-10 05:44:20 +00:00
lda TILE_ODD ; check to see if top or bottom ; 3
beq not_odd_line ; 2/3
inx ; point to bottom half of tile ; 2
inx ; 2
2024-03-10 05:44:20 +00:00
not_odd_line:
2024-03-14 04:32:22 +00:00
; draw two blocks
2024-03-14 04:24:03 +00:00
; note we don't handle transparency in the keen engine
2024-03-14 04:08:19 +00:00
lda tiles,X ; 4
sta (GBASL),Y ; draw upper right ; 6
2024-03-14 04:08:19 +00:00
iny ; 2
2024-03-14 04:24:03 +00:00
lda tiles+1,X ; 4
sta (GBASL),Y ; draw upper left ; 6
2024-03-14 04:24:03 +00:00
iny ; 2
2024-03-10 05:44:20 +00:00
inc TILEMAP_OFFSET ; point to next tile ; 5
2024-03-10 05:44:20 +00:00
cpy #40 ; until done ; 2
bne tilemap_loop ; 2/3
2024-03-14 05:21:45 +00:00
2024-03-10 05:44:20 +00:00
2024-03-14 04:08:19 +00:00
; row is done, move to next line
2024-03-14 04:24:03 +00:00
lda TILE_ODD ; toggle odd/even
2024-03-10 05:44:20 +00:00
eor #$1 ; (should we just add/mask?)
2024-03-14 04:24:03 +00:00
sta TILE_ODD
2024-03-14 04:32:22 +00:00
beq move_to_even_line
2024-03-10 05:44:20 +00:00
2024-03-14 04:08:19 +00:00
; move ahead to next row
2024-03-14 04:24:03 +00:00
; for even line we're already pointing to next
2024-03-14 04:32:22 +00:00
;move_to_even_line:
2024-03-14 04:24:03 +00:00
; lda TILEMAP_OFFSET
; clc
; adc #0
2024-03-14 04:32:22 +00:00
; jmp done_move_to_line
2024-03-14 04:24:03 +00:00
2024-03-14 04:08:19 +00:00
; reset back to beginning of line to display it again
2024-03-10 05:44:20 +00:00
move_to_odd_line:
2024-03-14 04:24:03 +00:00
lda TILEMAP_OFFSET
2024-03-10 05:44:20 +00:00
sec
2024-03-14 04:24:03 +00:00
sbc #TILE_COLS ; subtract off length of row
sta TILEMAP_OFFSET
2024-03-10 05:44:20 +00:00
2024-03-14 04:32:22 +00:00
move_to_even_line: ; no need, already points to
; right place
2024-03-10 05:44:20 +00:00
done_move_to_line:
2024-03-14 04:24:03 +00:00
ldy TILEY ; move to next output line
2024-03-14 04:32:22 +00:00
iny ; each row is two lines
2024-03-10 05:44:20 +00:00
iny
2024-03-14 04:24:03 +00:00
sty TILEY
2024-03-10 05:44:20 +00:00
2024-03-13 04:46:34 +00:00
cpy #48 ; check if at end
2024-03-10 05:44:20 +00:00
bne tilemap_outer_loop
rts
;===================================
; copy tilemap
;===================================
2024-03-14 05:21:45 +00:00
; local tilemap subset is 20x12 tiles = 240 bytes
; nicely fits in one page
;
; big tilemap is 128x80
; sad, was much cleaner to implement when 256x40
2024-03-13 04:46:34 +00:00
; TILEMAP_X, TILEMAP_Y specify where in big
TILEMAP_X_COPY_SIZE = 20
TILEMAP_Y_COPY_SIZE = 12
2024-03-10 05:44:20 +00:00
copy_tilemap_subset:
; TODO: lookup table?
; would be sorta big
lda #0
sta tilemap_count_smc+1
; original worse case: 23 cycles
; lookup table: 19 cycles
2024-03-10 05:44:20 +00:00
; set start
ldx TILEMAP_Y ; 3
lda tilemap_lookup_high,X ; 4
sta cptl1_smc+2 ; set proper row in big tilemap ; 4
lda tilemap_lookup_low,X ; 4
sta cptl1_smc+1 ; set proper row in big tilemap ; 4
; set start
; lda TILEMAP_Y ; 3
; lsr ; 2
; set odd/even
; ldx #0 ; 2
; bcc skip_odd_row ; 2/3
; ldx #$80 ; 2
;skip_odd_row:
; stx cptl1_smc+1 ; 4
; clc ; set start ; 2
; adc #>big_tilemap ; each even row is a page, so adding ; 2
; Y to top byte is indexing to row
; sta cptl1_smc+2 ; set proper row in big tilemap ; 4
2024-03-13 04:46:34 +00:00
2024-03-10 05:44:20 +00:00
lda #<small_tilemap
sta cptl2_smc+1 ; reset small tilemap to row0
2024-03-10 05:44:20 +00:00
cp_tilemap_outer_loop:
ldx TILEMAP_X
ldy #0
cp_tilemap_inner_loop:
; FIXME: make cptl1 take into account X offset and use one index?
; TODO: optimize, totally unroll?
2024-03-10 05:44:20 +00:00
cptl1_smc:
lda $9400,X ; 4
2024-03-10 05:44:20 +00:00
cptl2_smc:
sta $BC00,Y ; 5
iny ; 2
inx ; 2
2024-03-13 04:46:34 +00:00
cpy #TILEMAP_X_COPY_SIZE
2024-03-10 05:44:20 +00:00
bne cp_tilemap_inner_loop
; next line
clc
lda cptl1_smc+1
adc #$80
sta cptl1_smc+1
lda #$0
adc cptl1_smc+2
sta cptl1_smc+2
2024-03-10 05:44:20 +00:00
clc
lda cptl2_smc+1 ; increment row
2024-03-13 04:46:34 +00:00
adc #TILEMAP_X_COPY_SIZE
2024-03-10 05:44:20 +00:00
sta cptl2_smc+1
inc tilemap_count_smc+1
tilemap_count_smc:
lda #0
2024-03-13 04:46:34 +00:00
cmp #TILEMAP_Y_COPY_SIZE
2024-03-10 05:44:20 +00:00
bne cp_tilemap_outer_loop
2024-04-06 04:22:29 +00:00
done_tilemap_subset:
;==========================
2024-04-06 04:22:29 +00:00
; activate yorps
;==========================
2024-04-06 04:22:29 +00:00
2024-04-19 05:30:17 +00:00
ldx NUM_ENEMIES
beq done_yorps
2024-04-06 04:22:29 +00:00
clc
lda TILEMAP_X
adc #22
sta INL
activate_yorp_loop:
; if TILEMAP_X+22>YORP_X
lda INL
cmp enemy_data_tilex,X
bcc next_yorp
lda #1
sta enemy_data_out,X
next_yorp:
dex
bpl activate_yorp_loop
2024-04-06 04:22:29 +00:00
done_yorps:
2024-03-10 05:44:20 +00:00
rts