Metatile troubles

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

zkip
Posts: 67
Joined: Tue Nov 20, 2012 1:59 pm

Re: Metatile troubles

Post by zkip »

Update: Argh! I need to go back to NES school.. lol.

New problem: The code you all have been so gracious to help me with is for one column. Now, I assumed that right before I turned the screen on, I could JSR to that routine that sets the map up then return to turn the screen on. Basically, I imagined I could just set the writing area to $2000 and proceed on to a routine that would fetch 16 bytes from a level data table indexed by a which row to draw. However, my new problem is that I have no idea how to set the PPU writing area to what it needs to be. Like +$00 for row 1, +$16(?) for row 2, +$32 for 3(?) etc. My first assumption would be something like just using x to index what row. However, the PPU register is write-twice so that pretty much defeats the idea of that. How is this accomplished? Pointers? Sorry, my go-to is always pointers for some reason. lol

I mean, I know the nametable deal ($2007) increments with every write, however the buffer is only 64 bytes. Get what I'm trying to say?
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Metatile troubles

Post by tokumaru »

zkip wrote:My first assumption would be something like just using x to index what row. However, the PPU register is write-twice so that pretty much defeats the idea of that. How is this accomplished? Pointers?
No, not pointers. Since the PPU is on a separate addressing space, there are not that many ways to access it. If you want direct access to any given byte, there's no other way than setting up the address through $2006 for every access. As you can imagine, this is slow should be avoided, specially during VBlank. Most programs take advantage of the auto-increment feature the PPU has: after each write/read, the address increments automatically (by 32, which is useful for drawing columns of tiles, or by 1, which is for nearly everything else).

Since you have divided your buffer into a top row and a bottom row, the easiest thing to do would be to set PPU address increments to 1 and just blast all 64 bytes in sequence. If you're drawing a whole screen (meaning rendering is turned off), you can even leave the PPU address untouched from one row of metatiles to the next. Something like this:

Code: Select all

	lda #$20 ;have the PPU point to the beginning of the name table
	sta $2006
	lda #$00
	sta $2006

	ldy #$00 ;start decoding the first metatile of the map
DecodeRow:
	ldx #$00 ;start filling the buffer from 0
DecodeMetatile:
	sty Scratch ;backup Y
	lda (LevelData), y ;get the index of the metatile
	jsr WriteTileToBuffer ;decompress it to the buffer
	ldy Scratch ;restore Y
	iny ;go to the next metatile
	cpx #$20 ;is the buffer full yet?
	bne DecodeMetatile ;if not, do another metatile

	ldx #$00 ;start uploading from the beginning of the buffer
CopyToPPU:
	lda Buffer, x ;get the byte
	sta $2007 ;write it
	inx ;move on to the next byte
	cpx #$40 ;have we done 64 yet?
	bne CopyToPPU ;if not, copy another byte

	cpy #$f0 ;have we done all 240 metatiles yet?
	bne DecodeRow ;if not, decode another row
Post Reply