User Tools

Site Tools


base:extract_row_from_tile_based_map

Extract row from tile based map

by Achim

Example 4×4 tile:

aabb
ccdd
eeff
gghh

Tile data stored in memory:

aabbccddeeffgghh

In order to read and plot the correct tile row for a vertical scrolling game, tileY has to be defined.

tileY: 00, ...    aabb
       04, ...    ccdd
       08, ...    eeff
       0c, ...    gghh

Again a map pointer is needed (top-left) and mapX (=map width) for correct map data handling. For a straight vertical scrolling game

mapX = number of tiles left to right. In case of 4×4 tiles: mapX=#$0a, in case of 5×5 tiles mapX=#$08.

Pseudo code for scrolling down (player moving up):

		
		lda tileY
		bne samemaprow		//top tile row done?
			
		lda map			//map - mapX
		sec
		sbc mapX
		sta map
		lda map+1
		sbc #$00
		sta map+1			
		lda #$10		//tileY=0c
samemaprow:	sec
		sbc #$04
		sta tileY		

		lda map			//don't mess up map pointer...
		sta maptmp
		lda map+1
		sta maptmp+1
			
		lda lo-bytescreentop
		ldx hi-bytescreentop
		jsr extractrow
		...

Pseudo code for scrolling up (player moving down):

			
		lda map			//using tmp again
		sta maptmp
		lda map+1
		sta maptmp+1	

		ldx numbertiles		//number of tiles top-bottom
!:		lda maptmp		//calculate map row bottom
		clc
		adc mapX
		sta maptmp			
		lda maptmp+1
		adc #$00
		sta maptmp+1
		dex
		bpl !-
						
		lda lo-bytescreenbottom
		ldx hi-bytescreenbottom
		jsr extractrow
			
		lda tileY
		cmp #$0c		//lowest tile row done?
		bne !+
		lda map			//map + mapX
		clc
		adc mapX
		sta map
		lda map+1
		adc #$00
		sta map+1
		lda #$fc		//tileY=00
!:		clc
		adc #$04
		sta tileY
		...

Extracting a row is pretty simple…

/*--------------------------------------------------------------------------
Extract row from tile data
by A. Volkers, 2011

a = lo-bytescreen
x = hi-bytescreen

->KickAssambler
--------------------------------------------------------------------------*/
.pc = $1000

.const tilemem	= 	48	//hi-byte tile data: $3000

.var tileY	=	$02	//row 00, 04, 08, 0c
.var map	= 	$03	//16bit address for main program
.var mapX	=	$04	//map width
.var tiledata	=	$fc	//16bit address tile
.var maptmp	=	$fe	//16bit tmp for mappointer



extractrow:	sta plotrow+1		//prepare selfmod
		clc
		adc #$28
		sta check+1		
		stx plotrow+2		
				
extract:	ldy #$00
		lda (maptmp),y		//calculate tile data address
		and #$0f		//use tables for 5x5 tiles instead			
		asl
		asl
		asl
		asl
		sta tiledata		//lo-byte
		lda (maptmp),y
		and #$f0
		lsr
		lsr
		lsr
		lsr
		clc
                adc #tilemem		//hi-byte
		sta tiledata+1		
				
		ldy tileY		//get actual tile row
		ldx #$03		//#$04 for 5x5 tiles
readtile:	lda (tiledata),y	//read actual tile data
plotrow:	sta $ffff		//selfmod for screen position	
		inc plotrow+1
		bne !+
		inc plotrow+2
!:		lda plotrow+1		
check:		cmp #$28		//40 chars done?
		beq exit
		iny
		dex
		bpl readtile
		inc maptmp		//next tile
		bne !+
		inc maptmp+1
!:		clv
		bvc extract		
exit:		rts

Check out this program which uses the same routine. Hardscrolling only, no colour RAM shifting: tile_row.zip

base/extract_row_from_tile_based_map.txt · Last modified: 2015-04-17 04:31 (external edit)