Ninja'd thrice while I was composing this:
FitzRoy wrote:
I'm doing some pixel art and I'd like to know if there's a technical limitation holding back smooth animation on NES hardware. Seems like most games use very few frames for running. I was able to dramatically improve Contra's run animation by going from 3 unique leg positions to 5.
The following factors are why you don't often see 15 to 30 fps sprite animations on NES:
ROM size limitAt launch, a game had only 8 KiB of CHR ROM, allowing up to 256 distinct background tiles and 256 distinct sprite tiles (or 128 tall tiles in 8x16 mode). In 8x16 mode, a sprite can borrow a pair of tiles from the background half.
Later games are affected by ROM size to a lesser extent. Only a handful of licensed games are larger than the 512 KiB
Mega Man 4 through
Mega Man 6, and some of them cut back on player cels in order to fit more background environments and enemy cels. Late development of
The Curse of Possum Hollow was a game of Sokoban as I moved code and data around to fit them in the banks of the 512 KiB PRG ROM.
CHR ROM bank switching granularity limitMMC3-class mappers support only 4 sprite windows. You can put different cels of a character's animation in different banks, and then you animate by changing banks. But if you have more than four actors on the screen, at least two of them have to share a window, and the sprite sheet for that actor is thus limited to one bank, which is 64 tiles (or 32 tall tiles in 8x16 mode). Borrowing from the background pattern table isn't possible in levels that use parallax scrolling due to a quirk in the MMC3's interval timer.
Here's how
Curse lays out its PPU address space:
$0000-$0FFF (4K): Playfield or parallax loop
$1000-$13FF (1K): Current frame of Donny or Tami
$1400-$17FF (1K): Enemy sprite sheet 1
$1800-$1BFF (1K): Enemy sprite sheet 2
$1C00-$1FFF (1K): Common sprites, such as powerups, projectiles, lifts, and small objects that appear in many environments
The game uses 8 banks of tiles for Donny and 7 more for Tami, switching to whatever bank has the tiles for a particular cel. If a sprite sheet is only one bank (32 tall tiles in 8x16 mode), more than one enemy on the screen can use it, but an enemy with a larger sprite sheet (that is, a boss) will hog one of the sprite windows. So level designs have to be careful not to try to put more than two different enemy types together, or three if two of the enemy types are in the same sprite sheet.
MMC1-class mappers used with CHR ROM (e.g. SLROM, SKROM) have even coarser granularity: each page is 4 KiB or 256 tiles or 128 tall tiles in 8x16 mode. Thus all the sprite tiles used by a level have to fit into one 4K bank, including the player and enemies for a given environment type. The player's tiles also have to be repeated for different environment type.
CHR RAM bandwidth limitLet's say a game streams cels from PRG ROM to CHR RAM in order to circumvent bank switching granularity.
Haunted: Halloween '85 does this for all sprites, and
Battletoads does this for some sprites. Under normal circumstances, only about 128 bytes can be copied from ROM (or a decompression buffer in RAM) to CHR RAM in each NTSC vertical blanking period. This means eight tiles or four tall tiles in 8x16 mode. If an actor uses more than that, it has to be double-buffered; fortunately, there's enough CHR RAM on the sprite half of the pattern table to double-buffer everything. But if you decide to have many actors changing their cel at once, they may lag. One thing
Haunted does to hide the lag is try to guess the actor's next cel based on what most commonly follows the current cel and then preload that into each actor's back buffer.
FitzRoy wrote:
Is it possible to delay each frame individually by a different amount?
Yes, each cel in a sequence can have a different duration, but a particular engine might not necessarily support that. It's slightly more difficult code-wise to scale duration-per-cel to an actor's movement speed, as might happen in a walk cycle.
FitzRoy wrote:
Lastly, has anyone made a demo showing a heavy frame running animation like that in Super Metroid?
I've never played
Super Metroid. How many cels does Samus (or whatever other character you're thinking of) have? I made a tech demo with a 12-cel walk cycle during the early development of a project related to
Concentration Room, but it didn't have a lot else going on.