Alright, filling the screen with tiles from compressed data is working in my program.

Now I encounter the problem that I was able to circumvent in my previous game by simply hardcoding the upper static background graphics and by only using one and the same palette for the lower, dynamic part of the screen:

How do I set a palette attribute value if I know the x and y position of the corresponding tiles?

Let me elaborate:

I understand that each attribute value refers to a 16 x 16 pixels (2 x 2 tiles) area. Alright, fair enough.But why did they also have to align each attribute byte in a square format?

Why couldn't one attributes byte, which contains the palette information for four 16 x 16 areas, simply refer to a 64 x 16 area? Why does it have to be a 32 x 32 area?

This makes connecting the PPU address offset of a certain tile with the PPU address offset of the corresponding attribute value a pain in the ass.

So, is there a good function that can change the attributes value according to an x and y position?

x: Meta tile x position from 0 to 15. (Tile position would be x * 2 and pixel position would be x * 16.)y: Same as x, only for y.palette: Palette index value from 0 to 3.

attributes:An array that is a copy of the 64 attribute bytes from a single name table from the PPU.This value gets changed:The palette index value is written to the correct two bits in this array. So, after writing the changed array back into the PPU to $23C0, $27C0, $2BC0 or $2FC0, the 2 * 2 tiles at location x * 16, y * 16 use this new palette value.

Why couldn't one attributes byte, which contains the palette information for four 16 x 16 areas, simply refer to a 64 x 16 area? Why does it have to be a 32 x 32 area?

An uniform distribution makes more sense, I guess, and several games took advantage of the format by using 32x32-pixel metatiles. There's isn't much you can do with 64x16.

Quote:

This makes connecting the PPU address offset of a certain tile with the PPU address offset of the corresponding attribute value a pain in the ass.

It's indeed a pain in the ass, specially if you scroll vertically and have to deal with the bottomost attribute row being only 16 pixels high.

Quote:

So, is there a good function that can change the attributes value according to an x and y position?

The math I use is the one rainwarrior posted. Divide the coordinates by 2 to find the address of the attribute byte, use mod 2 to index a set of masks that can be used to manipulate the bits.

For each possible quadrant of an attribute byte, I have a pair of masks, one to clear the relevant bits in a pre-existing attribute byte, and another (the inverse of the other) to clear the unwanted bits of a byte fetched from the metatile's attributes that contains the palette index repeated 4 times. After clearing the bytes separately, I OR them together to form the final byte.

With attributes, since you have to read-modify-write each byte, it's often more convenient to keep a copy of the attribute data in RAM for unrestricted manipulation, and then upload rows or columns to VRAM as necessary.

Apart from the fact that on the NES, you should rather work with static and global variables instead of local ones, would you say the function is efficient enough or is there something that can be optimized?

Yeah, Assembly is surely better.But I managed to write a complete scrolling platformer in C with only the low level stuff (everything that is in vblank, access to the PPU etc.) and some general purpose functions (copy array, fill array, randomizer) written in Assembly.Therefore, unless I really get into trouble, I continue writing the functions in C for now. Makes it 10 times easier for me to write code.

So, is it my code that's still in error because I didn't convert the algorithm correctly from Assembly to C? Or is the algorithm itself as written down by psychopaticteen and tokumaru that's incorrect/insufficient?

Who is online

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum