[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fast tile renderer



Using the text page 1 bank to hold the information about what tiles to render, this routine does a quick render to hi-res page 1.  It's pretty tight, but could probably be more optimized.  What do you guys think?  Useless over-use of self-modifying code?  I'm all for keeping the cycle count low if there is a better way...

The shape table is organized in chunks of 32 bytes, such that each tile is 2 x 16 bytes (or 14x32 pixels).  

Right now I just threw together three test tile patterns so I could validate my multiply-by-32 routine worked, but the idea is to have a real tile editor and take the tile shape table stored in a separate file.

The "sp" and "flip" macros are used for convenience to make it easier to represent tiles as recognizable bit patterns in the code.

-------------------------------------------------------------------

; @com.wudsn.ide.asm.hardware=APPLE2 
!cpu 65c02
*=$6000
MAX_COLS=12
MAX_ROWS=11
VIEWPORT_META	= $400
currentRow		= $FA
currentCol		= $FB
tileYcounter	= $FC
unused			= $FD
VIEWPORT		= $2000

;--- Main tile drawing loop ---
drawTileView
			lda #MAX_ROWS
			sta currentRow
.drawRow
			lda #MAX_COLS
			sta currentCol
.drawCol	jsr drawTile
			dec currentCol
			bpl .drawCol
			dec currentRow
			bpl .drawRow
			rts			

;--- Draw tile indicated at currentRow and currentCol ---
drawTile
			lda currentRow			; A tile is 16 lines tall, which is 2 groups of 8 lines each
			asl
			tay						; Save currentRow*2 into x
			lda lookupLo,y
			adc currentCol			; Tile is two bytes wide so add X twice
			adc currentCol
			sta .getTile+1
			lda lookupHi,y
			sec
			sbc #$1C
			sta .getTile+2		
.getTile	lda $0000
			tax
			asl
			asl
			asl
			asl
			asl
			clc
			adc #(<ShapeTable)
			php
			sta .drawTileRead1 + 1	; Store lo-byte
			sta .drawTileRead2 + 1	; Store lo-byte
			txa
			lsr
			lsr
			lsr
			plp			
			adc #(>ShapeTable)
			sta .drawTileRead1 + 2
			sta .drawTileRead2 + 2
			ldx #0					; Set up offset for tile reads
			lda #16					; Set up row counter
			sta tileYcounter			
.drawTileUpdatePointers
			lda lookupLo,y
			clc
			adc currentCol			; Tile is two bytes wide so add X twice
			adc currentCol
			sta .drawTileStore1 + 1
			inc
			sta .drawTileStore2 + 1
			lda lookupHi,y
			sta .drawTileStore1 + 2
			sta .drawTileStore2 + 2
.drawTileLoop
.drawTileRead1
			lda ShapeTable,x
.drawTileStore1		; Store even column
			sta $0000
			inx
.drawTileRead2
			lda ShapeTable,x
.drawTileStore2		; Store odd column
			sta $0001
			inx
			dey
			dec tileYcounter
			beq .drawTileLoopEnd
			lda #$07
			and tileYcounter
			beq .drawTileFinishLoop
			lda .drawTileStore1 + 2
			clc
			adc #$04
			sta .drawTileStore1 + 2
			sta .drawTileStore2 + 2
			bne .drawTileLoop
.drawTileFinishLoop
			lda currentRow			; A tile is 16 lines tall
			asl						; Draw bottom half of the tile now
			inc
			tay						; Accum should be the (current row * 2)+1
			bne .drawTileUpdatePointers
.drawTileLoopEnd
			rts
lookupLo	!by $d0, $50, $d0, $50
			!by $d0, $50, $d0, $50
			!by $a8, $28, $a8, $28
			!by $a8, $28, $a8, $28
			!by $00, $80, $00, $80
			!by $00, $80, $00, $80
lookupHi	!by (>VIEWPORT)+3, (>VIEWPORT)+3, (>VIEWPORT)+2, (>VIEWPORT)+2
			!by (>VIEWPORT)+1, (>VIEWPORT)+1, (>VIEWPORT)+0, (>VIEWPORT)+0
			!by (>VIEWPORT)+3, (>VIEWPORT)+3, (>VIEWPORT)+2, (>VIEWPORT)+2
			!by (>VIEWPORT)+1, (>VIEWPORT)+1, (>VIEWPORT)+0, (>VIEWPORT)+0
			!by (>VIEWPORT)+3, (>VIEWPORT)+3, (>VIEWPORT)+2, (>VIEWPORT)+2
			!by (>VIEWPORT)+1, (>VIEWPORT)+1, (>VIEWPORT)+0, (>VIEWPORT)+0
!macro flip .v {
	!by (.v & 128) | ((.v & 1) << 6) | ((.v & 2) << 4) | ((.v & 4) << 2) | (.v & 8) | ((.v & 16) >> 2) | ((.v & 32) >> 4) | ((.v & 64) >> 6)
}
!macro sp .v {
	;!by (.v>>8)&255, .v&255
    +flip (.v>>8)&255
    +flip .v&255
}	
ShapeTable	;-------------0
			;    H6543210H6543210
			+sp %...#.#..........
			+sp %.#.#.#.#........
			+sp %.#.#.#.#........
			+sp %.#.#.#.#........
			+sp %...#........#.#.
			+sp %#....#....#.#.#.
			+sp %#..#......#.#.#.
			+sp %#....#....#.#.#.
			+sp %#..#..........#.
			+sp %........#...#...
			+sp %........#.....#.
			+sp %........#...#...
			+sp %........#.....#.
			+sp %................
			+sp %.#.#.#.#.#.#.#.#
			+sp %#.#.#.#.#.#.#.#.
			;-------------1
			;    H6543210H6543210
			+sp %......##.##.....
			+sp %#....#######....
			+sp %....####.####...
			+sp %#..###########..
			+sp %..######.######.
			+sp %################
			+sp %.#######.#######
			+sp %#.#############.
			+sp %...#####.#####..
			+sp %#...#########...
			+sp %.....###.###....
			+sp %#.....#####.....
			+sp %.......#.#......
			+sp %.###...........#
			+sp %....###.....###.
			+sp %.......#.###....
			;-------------2
			;    H6543210H6543210
			+sp %.#...#....#...#.
			+sp %..#...#....#...#
			+sp %.#.#...#....#...
			+sp %..#.#....#...#..
			+sp %...#.#....#...#.
			+sp %....#.#....#...#
			+sp %.#...#.#....#...
			+sp %..#...#..#...#..
			+sp %...#...#..#...#.
			+sp %....#....#.#...#
			+sp %.#...#....#.#...
			+sp %..#...#....#.#..
			+sp %...#...#....#.#.
			+sp %....#....#...#.#
			+sp %.....#....#...#.
			+sp %......#....#...#
			;-------------3
			;    H6543210H6543210
			+sp %.....###.###....
			+sp %...#####.#####..
			+sp %..##........###.
			+sp %.##..........##.
			+sp %.............##.
			+sp %..........###...
			+sp %.......#.###....
			+sp %...........###..
			+sp %............###.
			+sp %.............##.
			+sp %.............##.
			+sp %.............##.
			+sp %.............##.
			+sp %.##.........##..
			+sp %..######.####...
			+sp %...#####.###....