; MaxTile shared routines maxtile_flush_nmstl = $0084A8 maxtile_get_sprite_slot = $0084AC maxtile_get_slot = $0084B0 maxtile_finish_oam = $0084B4 ; MaxTile pointers !maxtile_mirror_max = $6180 !maxtile_mirror_high = $6190 !maxtile_mirror_normal = $61A0 !maxtile_mirror_low = $61B0 ; We are using MaxTile "direct mode" here, check the documentation ; for more information. ; Basically these are the trunk tiles, the "thick" ones are just repeated. ; This is the vertical pattern of the tiles and they are repeated until the ; pillar is drawn. thick_tree_1: db $C0,$E0 thick_tree_2: db $E1,$C1 medium_tree: db $C2,$E2 thin_tree: db $C4,$E4 ; This is the layer of each trunk, the format is simple: ; dw <16-bit position> : dw ; dw $FFFF ; <- end mark ; ; This can be updated to include scroll speed (right now it's hardcoded), as well ; background size. Currently all backgrounds are internally 512x224. ; ; The routine can be easily updated to support vertically large backgrounds, but ; more logic to avoid excess of tiles is welcome. tree_layer_1: dw $0000+$0055-$0008 : dw thin_tree dw $00AB+$0055-$0008 : dw thin_tree dw $0156+$0055-$0008 : dw thin_tree dw $FFFF tree_layer_2: dw $0080-$0010 : dw thick_tree_1 dw $0090-$0010 : dw medium_tree dw $0180-$0010 : dw thick_tree_1 dw $0190-$0010 : dw medium_tree dw $FFFF tree_layer_3: dw $0080-$0010 : dw thick_tree_1 dw $0090-$0010 : dw thick_tree_2 dw $0180-$0010 : dw thick_tree_1 dw $0190-$0010 : dw thick_tree_2 dw $FFFF ; Both init and main does the same thing. init: main: %invoke_sa1(sa1_main) rtl ; This is the routine that renders a "pillar", it takes a pattern ; and the x/y positions and draw a pillar on the screen. ; $00-$01 = x pos ; $02-$03 = tape ; $04-$05 = tape size ; $06 = current y pos ; $08 = layer y pos ; $0a = layer x pos ; $0c = maxtile buffer ; $0e = maxtile prop buffer render_pillar: rep #$20 lda $00 and #$01ff cmp #$0100 bcc .ok cmp #$01f0 bcs .ok sep #$20 rts .ok sep #$20 lda.b #~$1f trb $08 stz $06 ldy #$0000 .loop ldx $0c lda $00 sta $400000,x lda $06 sec sbc $08 sta $400001,x lda ($02),y sta $400002,x lda.b #%00111101 sta $400003,x dex #4 stx $0c iny cpy $04 bcc + ldy #$0000 + ldx $0e lda $01 and #$01 ora #$02 sta $400000,x dex stx $0e lda $06 clc adc #$10 sta $06 cmp #$e0 bcc .loop rts ; This is responsible for drawing a virtual layer, the only thing needed is to set ; your scroll value ($0A) and the pointer to the layer (Y register) render_layer: ldx $0000,y bmi .end rep #$20 txa sec sbc $0a sta $00 sep #$20 ldx $0002,y stx $02 phy jsr render_pillar ply iny #4 bra render_layer .end rts ; This basically gets the current MaxTile pointer, sets up the scrolling values ; and calls the render layers routines. sa1_main: phb phk plb rep #$10 ; configure maxtile ; unsafe: use the pointers without checking if there's slots free. ldx !maxtile_mirror_max+0 stx $0c ldx !maxtile_mirror_max+2 stx $0e ldx $1c stx $08 ; for now everything is two tiles ldy #$0002 sty $04 ; calculate scroll: $0A = ($1A + $1A/8) rep #$20 lda $1a lsr lsr lsr clc adc $1a sta $0a sep #$20 ; render virtual layer 1 ldy #tree_layer_1 jsr render_layer ; calculate scroll: $0A = ($1A + $1A/4) rep #$20 lda $1a lsr lsr clc adc $1a sta $0a sep #$20 ; render virtual layer 2 ldy #tree_layer_2 jsr render_layer ; calculate scroll: $0A = ($1A + $1A/2) rep #$20 lda $1a lsr clc adc $1a sta $0a sep #$20 ; render virtual layer 3 ldy #tree_layer_3 jsr render_layer ; finish maxtile ; store the new pointer, so MaxTile acknowledge the new tiles. ldx $0c stx !maxtile_mirror_max+0 ldx $0e stx !maxtile_mirror_max+2 sep #$10 plb rtl