I'm not nearly at this point yet, but I thought I'd toss this out there merely to see if anyone else thinks it's possible, and if I should pursue it.
Let's say I have a cave area much like the caves in Zelda II, but not full screen and not annoying. More like wide screen. The character has a flashlight. When it's off, the background is black. When the flashlight is on, the area in front of him is illuminated. I mean, hard illuminated, like the background is on in front of him, no fancy shadows from uneven terrain, Just simple on.
Would it be possible, perhaps using CHR-RAM and an increased VBLANK time to have arcs (diagonal lines) from a point on player, to the ground and to the ceiling, and have it move with the player? The whole tile wouldn't be 'on', but merely part of it?
For Example ( a simplication):
Off:
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
On:
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
Arc:
1 1 0 0
1 1 1 0
1 1 1 1
1 1 1 1
Arc after player moves forward one pixel.
1 0 0 0
1 1 0 0
1 1 1 0
1 1 1 1
Sounds extremely complicated, but I'm not sure the effect you want to achieve.
If some jittering in the light is acceptabe (usually it's what happens with a real torchlight) you might consider switching nametables/pattern tables and/or do $2001 writes mid-scanline. This will only work on the NES and accurate emulators tough.
You could :
- Have one pattern table be filled with tiles that are identical but darker than the other, and switch pattern tables with $2000
- Do the same as above but with CHR-ROM bankswitching instead
- Use a mapper with 1-screen mirroring ability, and have both nametables with identical tiles, but one is dark and the other is colored. Switch tables midscanlie trough the mapper. This won't work with any regular H or V mirroring because writes to $2000.1 are ignored mid-frame, and writes to $2000.0 are taken into account only one time per scan line. However, it might be possible if you don't scroll to show table at $2400 or $2800 and switch between H and V to have a similar effect.
- Use the color emphasis and/or grayscale bit of $2001. For example, light areas could be with grayscale on so it looks lit up, but you're limited to 3 for the lit area which sucks.
It sounds similar to the lighting system in Nethack, if you're in a dark room. Except it doesn't care which direction your facing, it just lights(displays) the surrounding area.
It probably would be easiest to do it on the nametable. You would have to re-draw the entire nametable when you went enter/exit 'on' or 'off' mode. 'Arc' mode updates could fit in vblank depending on how big it is and how far you want to optimize it, it would need to handle erasing the the previously-lit parts as well as drawing the newly lit ones.
If it's OK for the updates to not be full speed, and if there's no scrolling (or 4-screen memory maybe), you could do double-buffering and not display an 'incomplete' nametable. Kinda slows stuff down though.
It can be done, it's just tricky to get a whole lot of stuff into VRAM in a single vblank. If there's a good way to buffer it and deal with updates that take more than a frame, then the rest can be done pretty easy.
I think the best way to describe what he wants is this, from SNES Mario world. Bowser level where you hit the special bloack and that disco-ball thing comes on at the top of the screen.
Dang, that would be ridiculous to get a eclipse. You also have to change the sprite pallet and such to go with the light. I'd say might have a chance, but I don't think a curve would be possible.
This would be a pretty hard effect to pull off on the NES, depending on how you want to go about it.
Is the dark part completely black or is it still distinguishable background, only darker? If it's completely black, and the illuminated area is not huge (64 x 64 pixels or smaller), I can think of a way to do it.
I would clear the name tables using, say, color 1 (it could also be colors 2 or 3), and would make that color black. Then I would cut out a circle with the size of the spotlight, and it would be filled with color 0. Moving the flashlight would mean changing the scroll to reposition the circle, and the "background" would actually be made of sprites with the "behind background" bit set, that would follow the spotlight as it moved.
If the dark areas are not 100%, then the effect is much more complex.
Personally I would never do this by modifying the pattern tables. Pixel manipulation is very painstaking and slow on the NES. Modifying the name table is more like it, but you'd have to be OK with a rough jagged circle as the edge of the flashlight.
To make things really complex you could use extremely well timed code along with the color emphasis bits. I can imagine someone going crazy trying to do something like this, but I guess it's still an option.
I don't know if it's related since I read the thread very fast but I remember someone did a quick demo with bit emphasis. It was a fly with some kind of round light around it. Maybe it was Blarg who did it, I don't remember well. If I find it back I will dig it up. Not sure if it was you're looking for thought.
It's a demo from
loopy (Firefly). That's the exact effect I meant when I talked about using the emphasis bits. Looks insanely hard to pull off, and the contrast between light and dark isn't that great.
I just though of another way to go about it. Again, the spotlight can't be very large because we'll be using sprites.
Anyway, the idea is to have the dark background drawn normally, using the name tables. The spotlight would be made of sprites, that use the same tiles as the background (there ar 3 option here: 1. duplicate the tiles; 2. use 8x16 sprites; 3. have both sprites and background use the same pattern table) but with a brighter palette.
To make the spot light round and capable of moving smoothly, a few mask sprites (high priority sprites set to be displayed behind the background) could surround the highlighted rough-edged area.
The disadvantage is the sprite count, which would limit the size of the spotlight to 48 pixels or so, not considering game characters that might be in the scene as well.
EDIT: Apparently this would need too many sprites, so the spotlight would end up being too small.
Well, I don't think this is impossible, and I can think of a solution that might work. This doesn't fully accomplish the task, but it might suffice. You would have all the background defined as the dark, or "lights off" color. Then you would have a section around the player that's colored as "lights on" with the attribute table. Since this would be square, and wouldn't move smoothly with the player, you'll need to use sprite overlays to make it round. To do this, you could have a yellow circle (assuming the light is mostly yellow) around the player (also assuming the light is just a circle of light around the player) made of sprites. This circle should be pretty thick, and dither out towards the edges. As the player moves around, the attribute table gets updated to make the peices around them light, and to make sure all other peices are dark. The sprite overlays would hide this updating as well as rounding the edges of the light sections.
The problem with this is that the ring around the player wouldn't be transparent (only slightly in the dithered parts of the ring). The other problem with this is if the lit part of the background is supposed to be small, it would require a very thick opaque ring of sprites to hide the updates. In this case, it might be better to use the same palette for the whole background, and just have dark and light tiles defined in the pattern tables, so that you update the name table as the player moves rather than the attribute table. This allows you to have more definition of the bright parts around the player, so you can have a thinner ring of sprites to hide the updates.
Sorry if this doesn't make sense; I'm in class right now half listening to a lecture!
Thanks a lot guys! You've given me a lot to chew on! I think I'm probably going to try to implement something like this (eventually), though I'm still VERY early in my project. I'll be sure to let you guys know how it turns out!
I wanted it to be single screen shortcut like areas, so single screen mirroring and nametables looks like the way to go, but I might try some clever use of sprites as well, since they're probably won't be many enemies.
Although, a puzzle boss you fight with a flashlight might be cool...
How about you make all the pallets dark, and inbetween the light, make them all brighter and set the NES color intensity bits high, would that create a good enough effect? I have no idea how to implement such an idea though, sorry.
Aaron