sprite sizes

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
sprite sizes
by on (#175087)
Hello NES developers :D

I have a question related to sprite sizes in NES.

I know that the PPU deals with either 8x8 or 8x16 sprites and this what the PPU is configured to deal with

but I read that in real NES , there were 16x16 , 24x24

how then the PPU deals with them ?

thank's in advance
Re: sprite sizes
by on (#175089)
To make larger characters in an NES game, place multiple (hardware) sprites side by side. This can be done the obvious way:
Image

Or it can be done the efficient way:
Image
Re: sprite sizes
by on (#175090)
Thank's

I thought they are rendered as a one block not a multiple ones
Re: sprite sizes
by on (#175101)
Muhammad_R4 wrote:
I thought they are rendered as a one block not a multiple ones

No. The hardware only natively supports sizes of 8x8 and 8x16. You can visually accomplish whatever size you want by placing multiple sprites next to/above/below one another.
Re: sprite sizes
by on (#175103)
koitsu wrote:
...whatever size you want...

  • The 8 tiles per scanline creates a maximum width of 64 pixels coverage. If you have empty space you can spread that out wider, though.
  • The limit of 64 sprites onscreen creates a maximum of 8192 pixels coverage. e.g. a 64 x 128 pixel sprite rectangle is possible.
  • There is no explicit vertical size limit.
Re: sprite sizes
by on (#175109)
tepples wrote:
To make larger characters in an NES game, place multiple (hardware) sprites side by side. This can be done the obvious way:
Image

Or it can be done the efficient way:
Image

Your efficient way has some disadvantages, though:
While it does save graphics tiles, you have to sacrifice ROM space for meta sprites and execution speed of the update sprites function.
Because in this case, each single sprite in the meta sprite needs its own x and y offset value.
With the rectangle version, you only need a width and height per meta sprite (if all characters have the same width, then you don't even need the width). The sprite rendering function can then set the correct offsets itself.
This is what I did in my game to give the sprite updates a major boost and to reduce the ROM space of the meta sprite declarations.
Re: sprite sizes
by on (#175110)
Unless you're doing something small like a 64k PRG project, I think temples method works fine. Size shouldn't be that much of an issue. Megaman games use tepples method (every 8x8 cell inside the meta sprite frame has it's own x/y/flip/pal attributes). Tepples' method can also save some potential cpu cycles too (by using/converting less sprite cells in a meta sprite).
Re: sprite sizes
by on (#175111)
The biggest advantage of doing it the efficient way is to reduce the risk of sprite overflow. Also don't forget that metasprites make it easy to reuse identical tiles among sprites in an animation. What you gain in CHR-ROM tends to make up for what you lose in PRG-ROM, especially since usually the latter is larger than the former. And the moment you want an object with a different size you'd need to make a separate routine if you aren't using metasprites anyway.
Re: sprite sizes
by on (#175112)
DRW wrote:
execution speed of the update sprites function

That's a couple of extra cycles per tile, multiplied by at most 64 tiles. The loss of efficiency we're talking about is on the order of a couple of scanlines per frame, at worst.

...except this is forgetting forgetting something important: the "efficient" metasprites have less tiles. Depends on the specific case, but I think there's much potential for metasprites to perform better than 2x2 arrangements, just by reducing the tile throughput.

The reduced horizontal coverage metasprites allow, also makes a huge visual difference w.r.t. flicker.

DRW wrote:
you have to sacrifice ROM space for meta sprites

This, on the other hand, I think is much more significant. This can be very important in an NROM game. Even in my own project with a half megabyte of PRG, I still find space constraints a lot more of a problem than performance constraints.

However, if you have sprites of more than one size, without metasprites you have to write more sprite code, which could easily take up as much space as a pile of metasprite data. ;)


Edit: sorry if this is a little redundant, two others have replied while I was typing. :P

Sik wrote:
What you gain in CHR-ROM tends to make up for what you lose in PRG-ROM, especially since usually the latter is larger than the former.

Very much agree with this. I find space in CHR pages pretty limited, probably one of the most difficult space-packing challenges in NES development trying to fit everything you need at once into 256 tiles. ;) The tradeoff for PRG space is often worth it.
Re: sprite sizes
by on (#175113)
DRW wrote:
While it does save graphics tiles, you have to sacrifice ROM space for meta sprites and execution speed of the update sprites function.
Because in this case, each single sprite in the meta sprite needs its own x and y offset value.
With the rectangle version, you only need a width and height per meta sprite (if all characters have the same width, then you don't even need the width). The sprite rendering function can then set the correct offsets itself.
This is what I did in my game to give the sprite updates a major boost and to reduce the ROM space of the meta sprite declarations.

Metasprites don't necessarily add a lot extra data, depending on how you format things.

Store the sprite tiles, along with the mirroring bits, as you normally would, in a metasprite--
Example:
Code:
metasprite_00:
.db $03,$00,$00,$01,$02,$40


Store the X/Y offsets in a separate "sprite pattern", defined as the first byte in a metasprite frame.
This way, the sprite offsets can be recycled, saving a large chunk of ROM space from being wasted.
Games like Castlevania and Contra used this trick, or rather, something quite similar.

Example:
Code:
pattern_03:     ; 16x16
$87,$87,$01,$87,$87,$01,$01,$01  (-7,-7), (+1,-7), (-7,+1), (+1,+1)

(This could easily have been 4-bit encoded, but I wanted to "stream" the offsets quickly.)
Re: sprite sizes
by on (#175114)
DRW wrote:
Your efficient way has some disadvantages, though:
While it does save graphics tiles, you have to sacrifice ROM space for meta sprites and execution speed of the update sprites function.
Because in this case, each single sprite in the meta sprite needs its own x and y offset value.

The metasprite system in Haunted: Halloween '85 is a compromise between the "(x, y) for every tile" method and the rectangle method. It stores each frame of animation as a set of horizontal strips each 16 pixels tall. Each strip is four bytes: a set of x, y, attributes, and starting tile number for the strip. The bits of the attribute field not used by OAM (bits 4-2) are used as a width value: 0 through 7 make the strip 1 to 8 tiles wide. It also allows strips to lie on top of each other for a Mega Man-style overlay used for the whites of Donny's eyes and the P emblem on his shirt and hat. Finally, defining a sprite as horizontal strips allows cels to be not so obviously rectangular:

ImageImage

For the sequel, I'm changing it to explicitly specify the tile number of each individual sprite, rather than implying n, n + 2, n + 4, n + 6, ... as HH85 did.