I don't think I'm quite a newbie anymore, though still a freshman NES programmer. I've been using 8x8 sprites in my game up until now and I think it is much too late to change it for this project, but I'm trying to understand 8x16 sprites so that I could potentially use them in a future game.
According to
NESDoc.pdf, if the tile index is even, the pattern table at $0000 is used, if it is odd, the pattern table at $1000 is used. I would assume the following examples line up with this explanation:
Your sprite says to use tile index 0:
*32 contiguous bytes of pattern data, or two 8x8 tiles, will be read from $0000 and drawn vertically on the screen (8x16).
Your sprite says to use tile index 255:
*32 contiguous bytes of pattern data, starting with 16 bytes from $1FF0 and wrapping to $0000 (grabbing another 16 bytes), will be read and drawn vertically on the screen.
Is that right?
$00: $0000-$001F
$01: $1000-$101F
$02: $0020-$003F
$03: $1020-$103F
$04: $0040-$005F
[...]
$FE: $0FE0-$0FFF
$FF: $1FE0-$1FFF
With the lower bit selecting the side of the pattern table, you can't select tile 255 on the $1000 side as the first of two tiles. With a sprite value of 255 you'd be taking the last two tiles on the $1000 side.
It's been awhile but I'm pretty sure what I said is correct.
So an odd tile index is essentially treated as index-1? That makes a little more sense. So if you say, "tile 255," you really get two tiles from the second pattern table starting at tile 254, also using tile 255? Or is it more like it is just using the lowest bit to select the table, then using the upper 7 bits as an index from 0 to 127 to look up a 32 byte chunk?
If bit0 is clear you use $0000. If set you start at $1000. The upper 7 bits are used to determine which set of 2 tiles to use. So I think you do understand it.
So if you have a tilenumber of #$31, you are wanting tile #$30 on the $1000 side as your starting tile, which is followed by #$31 on that side. If you did Tile #$30, it would take tiles #$30 and #$31 also, but from the opposite side. I think that's pretty clear.
Thanks. What is the biggest advantage you can think of to using 8x16 sprites? One I can think of is it would mean any meta sprite routine you write would have to do a lot less work. Assuming a given meta sprite is an even number of 8x8 sprites tall, it'd be *half* the work. The only downside I can see is that if you're developing graphics with some kind of duplicate removal tool, you may have slightly fewer opportunities to remove duplicates. I can think of a situation with my main character where the back of his head and his shoulder are depicted in two separate frames, and in one frame his shoulder changes. With 8x8 sprites, I can re use the back of his head. 8x16 sprites would not allow this. Though, I suppose since you can use tiles from either pattern table, there could be a way to work around that. Unless you plan to max out each pattern table for sprites and background.
The biggest advantage is that there are 64 tall sprites instead of small sprites. So instead of being able to render 16 (16x16) sprites, you can render 32 of them.
Pros of 8x16 :
- More sprites can be overall placed to the screen
- Metatile drawing have less sub-tile to deal with -> faster execution time
- Can use tiles from both pattern tables
Cons of 8x16 :
- Less optimal use of CHR ROM/RAM space
- If you only need one tile, you need to place a second (dummy) blank tile and thus increase flickering (bullets in Gradius, Contra games, whip in Castlevania games)
I like to think of it like this: Bit 0 of the index actually becomes bit 8, and bit 0 is cleared.
Code:
h g f e d c b a = bits of the index written to the OAM
p = pattern table selected through bit 3 of $2000
Actual index used for 8x8 sprites:
p h g f e d c b a
Actual index used for 8x16 sprites:
a h g f e d c b 0
In the case of 8x16 sprites, p is not used, and since bit 0 is always 0, only even tiles start a 16x8 sprite.
This is probably how the hardware operates, and that resulting index is just multiplied by 16 (there's no actual multiplication, the bits are just placed 4 bits to the left) in order to get the actual address of the pattern to use.
The main advantage for 8x16 sprites is in any game with large characters. That's why SNES and Genesis with more resources have the ability to use sprites of much larger sizes. It would take significantly more cpu time setting up to draw a character composed of 8x8 blocks instead of 16x16 or possibly even 32x32 if you decided to go that route.
tokumaru, your explanation is very nice. It is short and easy to understand.
I often use 8x16. First because I like to use some tiles for both sprites and background, like when a wall breaks its pieces fly off as sprites. Of course I could replicate a few tiles on the sprite pattern table, but that's harder when the tiles in question are animated.
Another reason is that I like to draw big, complex sprites, and if I used 8x8 I would run out of sprites fairly quickly, and I really don't need the extra flickering.
It seems to me that most later games used 8x16, because they had to compete with the 16-bit consoles, so they had to put more action on the screen.
One thing I look at when choosing between 8x8 and 8x16 sprites is whether I'm using CHR-ROM or CHR-RAM. If I'm using CHR-ROM, I have to see how much space I have to work with. In an NROM project (which I'm working on now), I have very little space to work with, meaning I have to be very careful with how many tiles I define. Like Bregalad was saying, if you have a one-tile sprite you want to draw, you have to define an empty tile after that tile which is really bad if you are working with little space. If you have 128k or something of CHR-ROM, then you should feel more open to using 8x16 sprites. In my other project which uses 512k of PRG and CHR-RAM, I use 8x16 sprites. I am not forced to waste -space- by defining a blank tile after a single tile sprite in the pattern table. This greatly reduces my concerns in using 8x16 sprites.
The main reason I like them is because you can have a lot more objects made of sprites on screen. My character in my avatar is made of 4 8x16 sprites when standing still. That's really great, I think, compared to the 8 it would take if I were using 8x8. I also have some enemies that are pretty big (64x32 pixels) that require 16 sprites to be drawn (actually 12 because I was a bit clever with the placement) rather than 32 or 24. My status bar is also drawn with sprites, and thankfully it only takes 10 sprites rather than 20, which it would take if I were using 8x8. The sprites used on screen still add up when using 8x16, but they do a lot less quickly than 8x8.
Another thing to consider is versatility. When you use 8x16, you are allowed to use both BG and sprite tiles for the sprites, which could be seen as a boost in versatility. However, the sprites you define may not be as reusable as 8x8 sprites can be. In my NROM project, I find myself reusing a lot of the same tiles for different parts of enemies and stuff because I'm using 8x8 sprites. In my other project, I usually define a brand new peice of graphics for each part of an enemy, especially in something like animation where I would like to reuse one part of the 8x16 sprite, but I can't because the other part doesn't work with the movement.
And like Bregalad was also talking about, even if you have blank parts in an 8x16 sprite, it will cause flickering if it's on a scanline with too many sprites. If you have a good sprite-flickering routine that pays good attention to what should have priority though, this shouldn't be such a big issue.
If you want MMC3 interrupts, you don't really get both pattern tables of course.
You can't rotate an 8x16 sprite so it's 16x8, and put such rotated sprites side by side to overcome the 8 sprite scanline limitation, can you? Would be pretty awesome if you could.
The NES PPU can't rotate an 8x16 pixel sprite.
The only way to rotate an 8x16 pixel sprite is to rotate the screen. For example, the arcade game Centipede uses rotated 8x16 pixel sprites. But this obviously isn't available to games designed to run on a standard TV, so the NES version of Centipede had to go with two side-by-side 8x8s.