When I looked at the CHR ROM of few games(e.g MC kids and smb2) I could see a number of duplicate tiles. I am wondering why would there be redundant data at the time when memory was so costly? Did the duplicate tiles serve any special purpose?
Typically, a mapper supporting CHR ROM operates on pages of 64, 128, or 256 tiles at once. If you want to have a given tile in view no matter what page you have open, you need to put it in all the pages that might fill a given slot. For example, SMB2 wants the 1-up mushroom available no matter what character is selected. To go smaller than a 64-tile page, you probably need to use CHR RAM and suffer a substantial speed penalty of copying tiles into RAM during vertical blanking. Some games managed to take the penalty in stride (e.g. Battletoads); others didn't (e.g. Ikari Warriors).
A good example is the mapper MMC1 which swaps CHR-ROM in 8K or 4K pages. The game Ninja Gaiden uses MMC1 which means that certain sprites used in every level such as the Ninja Player and Items must be duplicated in other 4K sections of CHR-ROM which contain the different enemy graphics for each level and Boss. I suppose despite the high cost of ROM they still needed CHR-ROM. In Ninja Gaiden they did for bankswitching the background for the status bar and play field to use different tiles.
MC Kids shuts off the screen early to mask out the bottom 16 scanlines from showing scrolling updates. It's probably the only game that could have pulled a Battletoads and updated lots of tiles, but didn't.
Nadia wrote:
When I looked at the CHR ROM of few games(e.g MC kids and smb2) I could see a number of duplicate tiles. I am wondering why would there be redundant data at the time when memory was so costly? Did the duplicate tiles serve any special purpose?
A game could have redundant tiles because of the way their level/map compression works. Say level 1 in an NROM game uses tiles $20-$3F. Then level 2 uses tiles $40-$5F, level 3 uses $60-$7F, etc. If there is a tile in level 1 that should also appear in level 2, then it will be redefined somewhere between $40 and $5F. This is just a random example of a possibility; I don't know of any game that does this. I could explain many ways this system could be vastly improved, but it's just an example of what could be the case. Some programmers are willing to make sacrifices in CHR ROM space for PRG ROM space or just for simplicity. It just depends on how the code interacts with those tiles as well as the bankswitching capabilities like people were talking about. With CHR RAM, I really don't see much point in defining the same tile twice. In my game, ChateauLeVania, the current CHR updating system can access any tile defined in any PRG bank, so I -never- have to define the same tile twice. With 512k of PRG space total, this gives me a lot of room for defining graphics.
Celius wrote:
With CHR RAM, I really don't see much point in defining the same tile twice.
I do. I've developed a falling block game that uses multiple blank tiles, which represent different objects in the playfield:
- ordinary empty space,
- a space into which blocks are waiting to fall after a line clear, and
- an invisible solid block (not yet used, but had TTC not launched a disinformation campaign in May 2009, it would have been used for a game mode like that depicted starting at 5:10 of this video).
A game using metatiles (like Super Mario Bros.) would obviously translate all invisible blocks into identical tiles in the transfer buffer before copying it into VRAM. But because the cells are mapped to individual tiles, the engine just copies rows of the playfield directly to VRAM in a pair of unrolled loops, one for each of two players. It's a tradeoff between wasting 32 bytes of CHR ROM vs. 220 bytes of main RAM for a transfer buffer.
Another reason you might get multiple blank tiles is that it can be convenient to have the blank tile at both position $00 (zero) and position $20 (ASCII space).
Sorry, I meant more along the lines of defining it in ROM. Sure I see some point in loading the same tile into CHR RAM at multiple locations, but I don't see the point really in defining the same data in ROM twice. But there is always some exception.
In one of my games, for speed purposes, I update tiles always 8 at a time (or else it wouldn't be possible to animate the main character properly). So in some cases, animated objects that use less than 8 tiles will have some repeated tiles across the blocks of 8 it uses. I guess I'm one of the exceptions. =)
SMB2 is also a unique example of a game being converted from CHR-RAM to CHR-ROM. The prototype version mentioned here, uses RAM.
http://themushroomkingdom.net/smb2_proto.shtml
They seem to have added a lot of background animations, and also the ending screen is pretty heavy on tile usage. Obviously they had a lot of extra memory to burn.
tokumaru wrote:
In one of my games, for speed purposes, I update tiles always 8 at a time (or else it wouldn't be possible to animate the main character properly). So in some cases, animated objects that use less than 8 tiles will have some repeated tiles across the blocks of 8 it uses. I guess I'm one of the exceptions. =)
Could you elaborate please? Do you use CHR bank switching for animating the character?
Nadia wrote:
Could you elaborate please? Do you use CHR bank switching for animating the character?
Kinda. I'm using CHR-RAM, so there is no bankswitching in the regular sense of the word, but I tried to implement a pseudo-bankswitching scheme, that works in blocks of 8 tiles (128 bytes). The program requests these CHR updates and they are carried out during VBlank as possible. The main character makes use of it the most (each of it's animation frames must be loaded to be used), but background animations and other things use it too, just not as frequently.
So in some cases I have to repeat tiles or leave some blank inside each of these groups. I only do this with graphics that change during the level though, other graphics are stored compressed in the ROM.