I'm slowly picking my way toward making a simple horizontal-scrolling platformer on the NES. I'm currently in the process of figuring out how to rework my BG collision code for PC to be more 6502-friendly. Normally I'd just start coding and see what sticks, but I'm not at all familiar with the 6502, so it's slow, tedious and prone to rewrites since a change in one area usually ends up affecting everything else. I'm hoping some more experienced heads might be able to point me in the right general direction.
1) Where should I put the data?
I want to use 16x16 metatiles for collision, but the map is stored in 32x32 metatiles for the scrolling code, so I should probably unpack it somewhere. I also want to avoid glitches at the edges of the screen, so I'll need more than one screen, and hence more than one page of RAM. The simplest solution I can think of would be a 512 byte array covering two screens, updated in the same manner as the nametables, with a ~64 pixel margin on either side of the visible area.
Are there any major pitfalls or better ways I should be aware of?
2) How should I get the data?
Not having address registers or cheap shifts is doing my head in. My first thoughts on how to look up a BG metatile goes something like this:
Am I on the right track?
3) How should I pick what data to get?
4 bits of subpixel precision would save both space (velocities can fit in 8 bits, since nothing in my game will get anywhere near 8 pixels/frame, and coordinates can fit in 16 bits, since 16 screens is plenty of room for a level) and time (block coordinates are aligned to a byte, so I can test the carry flag to see if a boundary had been crossed) in the collision detection stage, but it would require a monstrous amount of shifting (a nybble swap table could work too, I suppose) to get pixel coordinates for metasprite placement. Metasprite evaluation has to happen every frame, but collision detection can be skipped if an object hasn't entered a new tile, so that's probably a net loss.
That leaves 8 bits of subpixel precision. Most of the games I know anything about the internals of seem to use that anyway, so there's probably a reason for it. Any other suggestions?
1) Where should I put the data?
I want to use 16x16 metatiles for collision, but the map is stored in 32x32 metatiles for the scrolling code, so I should probably unpack it somewhere. I also want to avoid glitches at the edges of the screen, so I'll need more than one screen, and hence more than one page of RAM. The simplest solution I can think of would be a 512 byte array covering two screens, updated in the same manner as the nametables, with a ~64 pixel margin on either side of the visible area.
Are there any major pitfalls or better ways I should be aware of?
2) How should I get the data?
Not having address registers or cheap shifts is doing my head in. My first thoughts on how to look up a BG metatile goes something like this:
Code:
lda posX+0 ; pixel resolution
and $F0
sta pointer+0
lda posY+1 ; screen resolution
and $01
ior map_page ; must be even, so either 4 or 6
sta pointer+1
lda posY ; pixel resolution
lsr
lsr
lsr
lsr
tay
lda (pointer),y
and $F0
sta pointer+0
lda posY+1 ; screen resolution
and $01
ior map_page ; must be even, so either 4 or 6
sta pointer+1
lda posY ; pixel resolution
lsr
lsr
lsr
lsr
tay
lda (pointer),y
Am I on the right track?
3) How should I pick what data to get?
4 bits of subpixel precision would save both space (velocities can fit in 8 bits, since nothing in my game will get anywhere near 8 pixels/frame, and coordinates can fit in 16 bits, since 16 screens is plenty of room for a level) and time (block coordinates are aligned to a byte, so I can test the carry flag to see if a boundary had been crossed) in the collision detection stage, but it would require a monstrous amount of shifting (a nybble swap table could work too, I suppose) to get pixel coordinates for metasprite placement. Metasprite evaluation has to happen every frame, but collision detection can be skipped if an object hasn't entered a new tile, so that's probably a net loss.
That leaves 8 bits of subpixel precision. Most of the games I know anything about the internals of seem to use that anyway, so there's probably a reason for it. Any other suggestions?