Using an in-cart chip to render silhouettes or outlines of sprites onto the background layer, so sprites can use 4 colors as opposed to the usual 3.
Never throught about this, but yeah sounds interesting. However wouldn't it requires --terribly-- complex logic on the cart ? Something something even more than the MMC5 ?
Maybe there can be dual 256x32x8-bit buffers, with the 6502 buffering the "shadow image" on one buffer while the other is being superimposed over the background layer by the chip.
Yeah, this idea has popped into my mind a few times. But like Bregalad said, it'd require some fairly advanced logic, probably an FPGA with internal RAM.
The most straightforward way I could think of would be to basically have a duplicated sprite renderer in the chip, which would be able to logically AND the CHR data bus before the PPU receives it, based on screen positions and 1-bit CHR patterns in this extra SPR-RAM.
Would need quite a bit of redundant hardware and CHR memory though, for just one extra color...
And now for "Taking the limit as x increases without bound", with your friend Pino:
Someone needs to make a TV tuner circuit for the NES. I've described before how it would work: decode NTSC, put luma on tile data, and put average chroma over 8x1 pixels on attribute. Then we can put all this enhancement chip garbage to rest with "Just plug your Xbox 360 into your NES."
Bananmos wrote:
Yeah, this idea has popped into my mind a few times. But like Bregalad said, it'd require some fairly advanced logic, probably an FPGA with internal RAM.
The most straightforward way I could think of would be to basically have a duplicated sprite renderer in the chip, which would be able to logically AND the CHR data bus before the PPU receives it, based on screen positions and 1-bit CHR patterns in this extra SPR-RAM.
Would need quite a bit of redundant hardware and CHR memory though, for just one extra color...
In the post above, I stated that the 6502 can software render the sprite shadows to a buffer, so it doesn't need a duplicated sprite renderer.
It just needs to be able to calculate the current screen position, fetch the next 8 needed pixels from the buffer, and barrel shift them with the previous 8 pixels.
So in other words, sort of how sprites were drawn back on the ZX Spectrum.
tepples wrote:
So in other words, sort of how sprites were drawn back on the ZX Spectrum.
Not really. The background will be drawn the same way it allways is. The chip will just super-impose silhouettes ontop of the bg patterns being fetched. Then the PPU renders sprites ontop of the silhouettes to acheive 4-color sprites.
But.... that means the silhouettes will all be square-shaped, or they will still need tile colour 0 to be transparent so the silhouettes can have a shape of their own, thus making tiles 3 colours only again!
Think about it and you'll see it's a problem that can't be corrected through "chip magic"
A mapper can replace the BG attribute and pattern table fetches to give *4* more colors (one being the BG color) from any BG palette. So 7 colors + transparency = pseudo 3 bpp. If this is done it should be highly hardware accelerated (preemptively masking sprite pattern fetches) otherwise it'll be hell to program and slow. If someone's going this far they should also enhance the BG too. I think it'd be nice to allow each tile to select any 4 colors of the 13. Oh an a programmable MMC2-like feature to expand past 256 tiles. And individual tile auto-animation like the Neo Geo.
While we are at it, how bout a second 6502 core running at a faster clock rate so you can process more calculations each frame to avoid slowdowns and have even more going on at once in your game.
Worked for Super Mario RPG.
Sooooo,
Doing it with CHR-RAM + software mapping would work but be really slow to upload, it might work if done only on the hero's sprite and if this sprite is fairly small (something like 16x16) so you have at worse something like 6 tiles to upload, so why not. One more color can be very significant, and doing it with two-layered sprites will eat some of the precious 8 sprites per scanline.
Doing it with a chip sounds nice, but the chip would have to be complicated. In addition to the normal CHR ROM/RAM, an additional layer of CHR-ROM/RAM of at least 1BP should be present in the mapper, and the mapper should be able to logically AND the normal BG with it's internal "sprite shadow rednering" as Bananmos said.
While you're doing something as complex, why not extend it to more BP so you can allow other BG colors to be used in your sprites too ? That way you could get for example if you have one color in common in all BG palettes, 5 color sprites (transparent color + shared color + normal 3) without eating some of the precious 8 sprites per limitation.
However, again this would require a crazy complex FPGA based mapper.
For really large sprites (probably more than 24x24), it's possible to do this for the middle of the sprite manually, by just using solid colors on the nametable and change them as the player advances, this way the transparent color in the middle of the sprites becomes this "solid" color, while the transparent colors of the border of the sprites are really transparent.
I think this is common on some older computers, but on the NES it's not practical due to the 16x16 attribute limitation, so I guess again a shared color between all the palettes is more suitable for this.
Quote:
it's possible to do this for the middle of the sprite manually, by just using solid colors on the nametable and change them as the player advances, this way the transparent color in the middle of the sprites becomes this "solid" color, while the transparent colors of the border of the sprites are really transparent.
This would only work if the sprite is aligned perfectly with the current fine X scroll, and if it only moves in blocks of 8 pixels at a time. Otherwise the "solid" pixels will scroll over the BG tile and become transparent (and vice versa with the actually transparent pixels).
And there's also that fundamental attribute limitation with the PPU. At best, each 8x1 block has to use the same attribute data. So the only way to make a silouette/outline that could be freely moved like a sprite would be to have all 4 BG palettes share the same color -- so basically you'd have to use $3F00 as the extra color unless you want to waste a good chunk of your palette.
Bregalad wrote:
While you're doing something as complex, why not extend it to more BP so you can allow other BG colors to be used in your sprites too ? That way you could get for example if you have one color in common in all BG palettes, 5 color sprites (transparent color + shared color + normal 3) without eating some of the precious 8 sprites per limitation.
However, again this would require a crazy complex FPGA based mapper.
...and maybe you can designate a palette for tiles that the sprites don't cross, so you can still use that extra color.
This is all too much work for too little gain, IMO.
tokumaru wrote:
This is all too much work for too little gain, IMO.
That. Move to SNES if you need that much hardware.
3gengames wrote:
tokumaru wrote:
This is all too much work for too little gain, IMO.
That. Move to SNES if you need that much hardware.
Not to discourage innovation, but I agree with this. I think there are some more worthwhile things that can be done for the NES.
*cough*
Well now I trought a bit more about this trick, and I think it's not that stupid to consider doing it in software when you use CHR RAM.
For example in a RPG with all 16x16 sprites, you could use this trick on the hero, it's arguable the look of the hero is more important than the look of other stuff so you want him to have one more color while still having a black outline.
If you scroll only in one direction at a time, you just have to reserve a total of 6 tiles for this and dynamically upload them every frame when the player is moving, which is doable with some unrolled loop. You'll also have to upload four nametable bytes every 8 pixels of scrolling (in addition to the normal updates).
So yes this is quite a few updates, but you can use one more color on the hero while still having 3 NPCs on the same line without flickering, while using a 2-layered hero would only allow 2 NPCs on the line, 3 will flicker. Also you'd have to store both layers in CHR RAM while here you only reserve 6 background tiles for that effect.
In games with bigger sprites which does multi directional scrolling, it's probably not worth the trouble as it would require way too much updates on both name tables and pattern tables for only one more color while multilayering allows 2/3 more colors (typically 2 as you'd have a black color common in all palettes for outlines - but not compularly).
So this sounds like a decent idea for RPGs.
Wizards and Warriors 3 did software pixel plotting to ensure that a sprite 0 hit would happen no matter what, that's what this suggestion reminds me of.
Not only Wizard & Warriors III but also Wizard & Warriors I, II, Solar Jetman, and possibly other Rare game did it, but with a signle pixel it wasn't too complex and didn't require too many updates.
In a RPG you'd need 6 tiles instead of just one for the trick, and you'd have to store multiple animation frames of mask corresponding to different metasprites.
I guess I'll have to write a proof of concept ROM that demonstrate this feature.
Bregalad wrote:
Not only Wizard & Warriors III but also Wizard & Warriors I, II, Solar Jetman, and possibly other Rare game did it, but with a signle pixel it wasn't too complex and didn't require too many updates.
Yeah, I remember seeing this in Marble Madness, one of the BG tiles has a single pixel that will slide up and down along with the scrolling.
I just bump to say I'm working on the proof of concept, don't you guys think I've given up.
However it ended up a bit more complicated than I expected to generate the nametable updates. I now did a program that follows the player by animating NT and PT updates, so all's left is programming the dynamic "AND" mask. Unfortunately I have a lot of work in real life so I'm not sure if I'll be able to end this demo before Christmas, but I'll try my best.
The demo is done ! (phew, right before christmas)
Download
here for full source code, or if you are only interested in the ROM
here.
There is currently no collision detection on purpose to show the effect on different kind of tiles.
Nice demo! It's quite a good example of where this technique could be useful in software. Although Jut Breed did manage to have colorful characters even without it, if you disregard all the reddish enemies :)
Another type of AND mask that comes to mind is to support sprites being partially by BG without requiring a one color background such as is the case for sprite priority. This is sort of the opposite of the technique discussed in this thread, as you modify the sprite CHR based on the BG it intersects.
Solstice is a nice example of doing this trick in software. But the fact that it runs in a small part of the screen with the rest of the screen blanked may be related to all the CHR-RAM updates it needs to do to pull this off...
The Mega Man series and Super Mario Bros. 2 USA (for Mario and Princess) used a sprite overlay trick to create characters of more than 3 colors.
In case of Mega Man, the face is a distinct white-yellow sprite that is overlayed on the blue-cyan-black body, and in case of Mario and Princess, the eyes were overlayed over the character's non-hollow face. (Why they did not use it for Luigi and Toad, I don't know.)
Quote:
Another type of AND mask that comes to mind is to support sprites being partially by BG without requiring a one color background such as is the case for sprite priority.
Yeah. This can also be done by using a higher priority sprite with the "behind BG" flag set and having the shape you want to give to the BG. Castlevania uses this for the door entrance, SMB3 uses it for pipes (instead of simply making Mario "behind BG" like SMB1 does).
This priority could also be done in my demo by placing the hero's sprite "behind BG", which would have no effect as the BG is transparent where the sprite is, but then alter the logic so that the player shadow is NOT masked where you want the player to be masked. The player would still be visible through the BG color as he's literally "behind BG".
Of course it would require adding some more complex logic where it's already quite complex.
If you simply want to hide the player behind some tiles and not some others though it's as simple as not uploading the name table with the special tiles, but you're limited to square tile-aligned shapes.