Lucradan wrote:
I'm going to have to use a board with CHR-RAM.
Yup.
Quote:
Unless I'm doing some hblank switching, I'm only going to be able to have at most 256 destructible tiles on the screen at once. Best case that's about 25% of the screen.
32KB RAM chips nowadays are easier to find than 8KB ones, so if you use a mapper with scanline IRQs you can easily have unique tiles for the entire screen by switching banks 3 times per frame. You can till pull off an entire screen of unique tiles using only 8KB of CHR-RAM if the image is only 2 colors, but there will only be 32 tiles left for sprites.
Quote:
I need a efficient mapping from pixel (x,y) to tile address
Assuming 4 256-tile banks, and a name table sequentially filled with 0-255, 0-255, 0-255, 0-191:
BankIndex: Y >> 6;
TileIndex: (Y << 2) AND %11100000 + (X >> 3);
TileRow: Y AND %00000111;
Plane0Address: TileIndex << 4 + TileRow;
Plane1Address: Plane0Address + 8;
NOTE: You can actually calculate the tile index differently if you arrange the relevant 5 bits of X and the relevant 3 bits of Y in different ways if it makes the calculation simpler, you just have to change the name table layout to reflect this.
To manipulate individual pixels of a row, you can use the index (X AND %00000111) to load a mask from the following tables:
Code:
PixelMasksSet:
.db %10000000
.db %01000000
.db %00100000
.db %00010000
.db %00001000
.db %00000100
.db %00000010
.db %00000001
PixelMasksClear:
.db %01111111
.db %10111111
.db %11011111
.db %11101111
.db %11110111
.db %11111011
.db %11111101
.db %11111110
Then you can OR the bytes from the pattern tables with the values from the first table to set bits, or AND them with the values from the second table to clear bits.
Quote:
I need to pull the 16 bytes of tile data from the CHR-RAM, put it in NES RAM, apply the mask, then write the data back. Either I split this up over two frames (one read, one write) or I somehow eleminate the need for the read from CHR-RAM altogether.
To eliminate the read you'd have to buffer all tiles in WRAM. There are mappers that allow you to have up to 32KB of WRAM.
Quote:
How does QIX do this?
I'm not familiar with this game.
Quote:
How much memory is there in CHR-RAM compared to CHR-ROM? And given there is only 1 bit in the rendering mask to indicate the tile page (typically background or sprite), how could you set it to a different page other than 1 or 0?
Bankswitching on the cartridge side.
Quote:
If the background tile is temporarily in NES RAM, pixel level collision detections should be a simple masking check, correct? If my sprite is at (x,y) on the screen, I get the tile data for the background directly behind it. I then calculate what the offset (dx,dy) that sprite is from the upper left pixel in the tile. This gives me an " AND " mask which I can then apply to the tile data and see if there is overlap.
Yes, you can do it like this. I advise against using sprite coordinates and dimensions in favor of logical object coordinates and bounding boxes though.