Is it possible to change the palette's values per a scanline in a practical way (so it can be used in a game and not only demo)?
You can change the palettes for a status bar, or other vaguely similar things, but that's approximately it.
After every scanline? No. A clean palette change requires several blank lines, one for each of the eight 3-color subpalettes. There's an Indiana Jones game that changes the background color ($3F00) only, and only on the title screen, and with a few blank tiles at the right side, but that's it.
By "several blank lines" you mean blank scan lines? Right?
Concerning the title screen of Indiana Jones: I see empty tiles in the left not right. Isn't?
You should be looking at
this Indiana Jones title screen.
The problem with changing palettes mid-frame on the NES is that a lot needs to be done: set the VRAM address, write the new color(s), and restore the scroll to what it was supposed to be. There's only a teeny tiny window in hblank during which you can manipulate the VRAM address without corrupting the display, which is not nearly long enough to accommodate everything that needs to be done, so you really need forced blanking, which means blank scanlines. And by "blank" I mean completely blank, not even sprites can be rendered in those scanlines.
Thanks a lot guys!
I hoped maybe it was possible to sacrifice side tiles to extend hblank possibilites.
The fact that it's needed to sacrifice entire scanline is sad.
Everything becomes quite impractical.
So as tepples said (and I have understood it right) it's needed one scanline to change 3 values in single palette?
greatkreator wrote:
The fact that it's needed to sacrifice entire scanline is sad.
There are 2 reasons why you need to sacrifice entire scanlines. The first is that sprites can get corrupted when rendering is temporarily disabled, so you have to turn rendering off and on at proper times, if you need sprites. The other reason is a PPU "feature" that causes the color being pointed by the VRAM address to be drawn on screen when rendering is disabled. This means that if you wrote new colors during the visible part of the scanline, you'd SEE little dashes of color on the screen as the writes happened, so the actual updates must still happen during hblank to prevent such glitches.
Quote:
So as tepples said (and I have understood it right) it's needed one scanline to change 3 values in single palette?
That sounds about right.
Is the same situation with the attribute table values? Only 3 32x32 attribute block can be changed?
If I don't use sprites or/and scrolling does it help anyhow to increase number of changed colors or attribute block values?
So you're going to rewrite the attributes in vRAM during an IRQ so that the colors of the tiles change before they're rendered on screen?
It might be possible, since you can write to vRAM during hBlank a little, but you're not gaining anything.
You would still have to select from the sames colors you already had available.
MMC5's approach is sort of like that idea. The cart swaps into different attribute values every 8x8 tile so you get 8x8 attributes. You can't do this with IRQs. If you try to write to vRAM while it is rendering, everything goes haywire.
The only way I've reasonably found to get more colors in the playfield is to swap colors as they scroll off. This requires one full screen with 3 colors max. Changing the background color would require no tiles on screen that use the background color, so that is a bit more impractical.
greatkreator wrote:
Is the same situation with the attribute table values? Only 3 32x32 attribute block can be changed?
With attributes you have a little more freedom, since you can update them during the visible part of the blank scanline. You can update around 14 bytes during one blank scanline.
Quote:
If I don't use sprites or/and scrolling does it help anyhow to increase number of changed colors or attribute block values?
Not using sprites doesn't help with palette changes because there's still the "color being updated gets displayed" thing. As for scrolling, even if you're not modifying the scroll over time, the PPU is ALWAYS using the scroll for rendering, and changing the VRAM address messes with the scroll, so you absolutely have to fix it before turning rendering back on.
Quote:
Change palette values per scanline in practical way
The only
practical way is : Don't. Changing palette is too complicated, so it is only an interested feature for tech demoes or such where you're ready to waste a lot of CPU time to pull out nice effects that push the hardware to the limits.
Some games use a different palette for two halves of the screen, so it's not all that impractical if you don't mind a seam in the screen.
Examples: Super Off Road, Day dreamin' davey, Back to the Future...
Thanks everyone who helped!
Actually I am interested exactly in pushing the limits.
greatkreator wrote:
Actually I am interested exactly in pushing the limits.
We all are! However, pushing the limits of a system like the NES is never "practical" and will always have strong constraints like using a particular mapper, or using a lot of CPU time, and writing fine-tuned timed code.
It's not a problem for me at all. I am ready for that.
I just need to know about its theoretical possibilities.
Just not to be trying to get physically impossible things.
Quote:
Just not to be trying to get physically impossible things.
I think you're getting to that ballpark with changing palettes on scanlines.
I started inquiring about it when I stated doing scanline stuff, and was pretty quickly convinced that doing this to get more than 4 palettes in the playfield was not possible.
If you blank out a line, your sprites blank out too, so you can't plan for a blank line in the background to cover it. So you have to have a part of the screen over which nothing will pass. That makes this good for status bars and almost nothing else.
What's about skip odd lines in odd frames and skip even lines in even frames? To simulate some kind of "interlace".
It may work. At least on LCDs.
I'm not a hardware guy, BUT, I don't think you'll get the effect you want.
The resolution of NTSC is quite a bit greater than the resolution of the NES. Every scanline you blank will represent more than one blanked scanline on your screen.
I honestly do think you'll be better suited to push boundaries in other areas. That's what I'm doing.
The NES composite signal is not a conforming NTSC signal but instead a 240p signal compatible with most NTSC monitors.
How well this palette technique will work depends on how your monitor responds to the RGB121 technique (
images;
demo ROM).
But then you'll spend almost all your time manipulating the display, with nothing left for the game logic. You'd hardly get a consistent effect anyway, considering how differently each TV treats 240p analog signals. It would certainly look like crap (too much flicker) on CRTs and probably also on consoles modded for RGB and HDMI.
Also, correct me if I'm wrong, but I believe sprites won't show up as soon as you turn rendering back on, because sprites need an entire scanline of evaluation so they can be displayed on the NEXT scanline (this is why there are no sprites on scanline 0, they're being evaluated to show up on scanline 1), so every time you turn rendering off, you get at least 2 scanlines without sprites.
Just to add a little more detail about those demo pictures...
He's got nametable #0 filled with the green elements of the picture, amd nametable #1 filled with the red and blue elements of the picture, and using timed code to change the H scroll (or is it, changing the nametable selection) at the end of every scanline.
Cool, but impractical for an actual game (except maybe a static title screen).
If you want to change the palette in the middle of the gameplay area, I think this discussion is pretty much over. The way sprites work makes it completely impractical to rewrite the palette if they need to be present.
However, if this is for a status bar, a (spriteless) still image, or maybe even a video sequence, it may be possible to come up with a way to make this feasible. But you have to tell us where your going with this, otherwise we can't help.
Just gonna throw out there that if a bigger palette is one of your main goals, you might want to consider Sega Master System.
If you want to do something impressive, try to do some raster effects...
http://www.zophar.net/pdroms/nes/raster ... grams.html
darryl.revok wrote:
Just gonna throw out there that if a bigger palette is one of your main goals, you might want to consider Sega Master System.
Not only the palette is bigger (32 colors for the background), but you get to use 16 colors per tile! And you can flip tiles horizontally and vertically. Sprites are not as versatile though, since they all use only 1 of the 2 16-color palettes (but hey, it's still more than the total of 12 colors you get on the NES) and can't be flipped (ouch).
Normally I'm against suggesting a different platform when someone asks how to do something on a specific machine, but when they absolutely feel the need to bend such intrinsic aspects of the platform it should indeed be the time to ask oneself if that particular machine was the right choice for the project.
dougeff wrote:
If you want to do something impressive, try to do some raster effects...
http://www.zophar.net/pdroms/nes/raster ... grams.htmlThat probably drives certain TVs crazy, too. ;-D
I've already made a mid-frame palette update demo you can try here:
viewtopic.php?f=2&t=12830It is in fact possible to update a palette (single color) without destroying the sprites, HOWEVER, this only works on two precise spots of the screen.
But your question was "is it practical", and the answer is "not really."
Now that I think about it, I'm wondering if PPUMASK ($2001) has an influence on this. If the left column of sprites is enabled/disabled, maybe it can extend the window to update the palette without effecting the sprites. I'll look into this...
psc wrote:
If the left column of sprites is enabled/disabled, maybe it can extend the window to update the palette without effecting the sprites.
That shouldn't change anything... AFAIK, that setting only prevents the pixels from being displayed, it doesn't affect the sprite/background processing in any way.