This is just a theoretical technique I came up with to allow a special sprite, such as the player, to have 4 colors - presumably black and 3 others - without layering sprites.
The caveat is it requires CHR RAM and a ton of ROM to feasibly do. But I think it should be effective.
It works by creating a rudimentary form fake sprites in realtime. Here are my notes, hopefully they'll be comprehensible:
-------------------------------
extra color / shadow engine (fake sprites)
make background color black
have chr ram and reserve the maximize size of a sprite in the bg's pattern table. this will only work for objects
that are not reused on the same screen.
our mask is size of sprite + 1 in both directions ... so 16x32 becomes 3x5 tiles (15)
have everything ready to go before vblank
prepare an AND mask asset in relation to sprite graphics
it may make sense to store this mask in continuous column strips rather than left-to-right tiles.
now construct a fake sprite out of it
for the y axis,
start on the correct row and "spill" into the next tile the (8-(y mod 8)) row
for the x axis,
so basically rotate each row in an unrolled loop into the next column
after we've constructed a mask, we can AND the underlying tiles with it to create the final tiles
during vblank, place these tiles on the map under a sprite in order to add outlines,
or anywhere (with no sprites at all) to create shadows or other effects.
therefore a sprite can have 4 colors this way.
to speed things up,
the mask creation in the x direction can be precalculated, so for our 16x32 sprite this becomes 3x4 tiles (12) x 8 (- 4) = 92 PER FRAME
if our sprite has detailed animations we could have 50 or so frames for it. this would mean 4600 tiles needed, or 36800 bytes!
the mask application might be able to be done directly from the mask rather than preparing a vertically-scrolled intermediate version
other different effects can be done if the mask is reversed for instance and we use OR or XOR instead. however this might not look nice if the fake sprite crosses attribute zone boundaries.
The caveat is it requires CHR RAM and a ton of ROM to feasibly do. But I think it should be effective.
It works by creating a rudimentary form fake sprites in realtime. Here are my notes, hopefully they'll be comprehensible:
-------------------------------
extra color / shadow engine (fake sprites)
make background color black
have chr ram and reserve the maximize size of a sprite in the bg's pattern table. this will only work for objects
that are not reused on the same screen.
our mask is size of sprite + 1 in both directions ... so 16x32 becomes 3x5 tiles (15)
have everything ready to go before vblank
prepare an AND mask asset in relation to sprite graphics
it may make sense to store this mask in continuous column strips rather than left-to-right tiles.
now construct a fake sprite out of it
for the y axis,
start on the correct row and "spill" into the next tile the (8-(y mod 8)) row
for the x axis,
so basically rotate each row in an unrolled loop into the next column
after we've constructed a mask, we can AND the underlying tiles with it to create the final tiles
during vblank, place these tiles on the map under a sprite in order to add outlines,
or anywhere (with no sprites at all) to create shadows or other effects.
therefore a sprite can have 4 colors this way.
to speed things up,
the mask creation in the x direction can be precalculated, so for our 16x32 sprite this becomes 3x4 tiles (12) x 8 (- 4) = 92 PER FRAME
if our sprite has detailed animations we could have 50 or so frames for it. this would mean 4600 tiles needed, or 36800 bytes!
the mask application might be able to be done directly from the mask rather than preparing a vertically-scrolled intermediate version
other different effects can be done if the mask is reversed for instance and we use OR or XOR instead. however this might not look nice if the fake sprite crosses attribute zone boundaries.