This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Change palette values per scanline in practical way

Change palette values per scanline in practical way
by on (#163307)
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)?
Re: Change palette values per scanline in practical way
by on (#163308)
You can change the palettes for a status bar, or other vaguely similar things, but that's approximately it.
Re: Change palette values per scanline in practical way
by on (#163309)
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.
Re: Change palette values per scanline in practical way
by on (#163312)
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?
Re: Change palette values per scanline in practical way
by on (#163313)
You should be looking at this Indiana Jones title screen.
Re: Change palette values per scanline in practical way
by on (#163314)
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.
Re: Change palette values per scanline in practical way
by on (#163315)
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?
Re: Change palette values per scanline in practical way
by on (#163316)
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.
Re: Change palette values per scanline in practical way
by on (#163318)
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?
Re: Change palette values per scanline in practical way
by on (#163319)
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.
Re: Change palette values per scanline in practical way
by on (#163320)
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.
Re: Change palette values per scanline in practical way
by on (#163330)
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.
Re: Change palette values per scanline in practical way
by on (#163338)
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...
Re: Change palette values per scanline in practical way
by on (#163339)
Thanks everyone who helped!

Actually I am interested exactly in pushing the limits.
Re: Change palette values per scanline in practical way
by on (#163351)
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.
Re: Change palette values per scanline in practical way
by on (#163352)
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.
Re: Change palette values per scanline in practical way
by on (#163357)
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.
Re: Change palette values per scanline in practical way
by on (#163364)
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.
Re: Change palette values per scanline in practical way
by on (#163366)
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. :)
Re: Change palette values per scanline in practical way
by on (#163367)
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).
Re: Change palette values per scanline in practical way
by on (#163368)
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.
Re: Change palette values per scanline in practical way
by on (#163369)
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).
Re: Change palette values per scanline in practical way
by on (#163370)
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.
Re: Change palette values per scanline in practical way
by on (#163371)
Just gonna throw out there that if a bigger palette is one of your main goals, you might want to consider Sega Master System.
Re: Change palette values per scanline in practical way
by on (#163372)
If you want to do something impressive, try to do some raster effects...

http://www.zophar.net/pdroms/nes/raster ... grams.html
Re: Change palette values per scanline in practical way
by on (#163374)
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.
Re: Change palette values per scanline in practical way
by on (#163391)
dougeff wrote:
If you want to do something impressive, try to do some raster effects...
http://www.zophar.net/pdroms/nes/raster ... grams.html

Image

That probably drives certain TVs crazy, too. ;-D
Re: Change palette values per scanline in practical way
by on (#163433)
I've already made a mid-frame palette update demo you can try here: viewtopic.php?f=2&t=12830

It 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...
Re: Change palette values per scanline in practical way
by on (#163436)
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.