Palette change mid frame: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(stubbing this, seems to be a frequent topic on the forum)
 
(some information about the problem)
Line 7: Line 7:
''Indiana Jones and the Last Crusade'' changes its background colour many times across the title screen for a gradient sky effect:
''Indiana Jones and the Last Crusade'' changes its background colour many times across the title screen for a gradient sky effect:
* [//forums.nesdev.org/viewtopic.php?p=139925#p139925 Annotated analysis of Indiana Jones]
* [//forums.nesdev.org/viewtopic.php?p=139925#p139925 Annotated analysis of Indiana Jones]
== Details ==
To write to the palette in the middle of the screen, the following sequence of operations need to be done:
# Disable rendering ($2001)
# Set PPU address ($2006)
# Write new palette ($2007)
# Restore PPU address ($2006)
# Re-enable rendering ($2001)
Ideally, these should be done within or mostly within horizontal blanking to minimize the appearance of visual errors. There are several problems:
* NTSC horizontal blank only lasts 21 cycles, which is not enough time to fit all of these steps at once.
** Half of the address may be written to $2006 early.
** Three values can be loaded into the A, X, Y registers in advance of blanking to avoid extra load cycles.
** Most IRQ or $2001 polling techniques for timing are subject to jitter, varying by about 7 cycles, which cuts into the usable horizontal blank time significantly.
* Because sprites are evaluated one line in advance, turning off rendering will cause the first line of sprites to be corrupted after re-enabling.
** Sprites can be hidden for one line ($2001) after the change to minimize the appearance of error.
* Whenever the PPU address is pointing at a palette entry, this will become the current background colour whether rendering is on or off.
Because of these issues, it is best not to use this techniques where sprites may overlap the affected lines. ''Indiana Jones'' hides some potential visual errors by only working where the background is already blank, and only changing the background color. Games that change colors for a status bar can use blank lines at the top of the status bar to similarly avoid visual errors.
== See Also ==
* [[PPU palettes]]
* [[PPU scrolling]]
* [[PPU rendering]]
* [[PPU sprite evaluation]]
* [[Consistent frame synchronization]]
* [[Errata]]


== References ==
== References ==
* [//forums.nesdev.org/viewtopic.php?t=16679 Forum thread]: Palette swap within the game region?
* [//forums.nesdev.org/viewtopic.php?t=16679 Forum thread]: Palette swap within the game region?
* [//forums.nesdev.org/viewtopic.php?p=209711#p209711 Forum post]: Re: The quest for mid-screen palette changes!
* [//forums.nesdev.org/viewtopic.php?p=209711#p209711 Forum post]: Re: The quest for mid-screen palette changes!

Revision as of 21:40, 8 December 2017

Changing palette entries in the middle of a frame on the NES is difficult, but marginally possible.

A few games are known to change palette entries for a status bar region:

  • Fantastic Adventures of Dizzy
  • Startropics

Indiana Jones and the Last Crusade changes its background colour many times across the title screen for a gradient sky effect:

Details

To write to the palette in the middle of the screen, the following sequence of operations need to be done:

  1. Disable rendering ($2001)
  2. Set PPU address ($2006)
  3. Write new palette ($2007)
  4. Restore PPU address ($2006)
  5. Re-enable rendering ($2001)

Ideally, these should be done within or mostly within horizontal blanking to minimize the appearance of visual errors. There are several problems:

  • NTSC horizontal blank only lasts 21 cycles, which is not enough time to fit all of these steps at once.
    • Half of the address may be written to $2006 early.
    • Three values can be loaded into the A, X, Y registers in advance of blanking to avoid extra load cycles.
    • Most IRQ or $2001 polling techniques for timing are subject to jitter, varying by about 7 cycles, which cuts into the usable horizontal blank time significantly.
  • Because sprites are evaluated one line in advance, turning off rendering will cause the first line of sprites to be corrupted after re-enabling.
    • Sprites can be hidden for one line ($2001) after the change to minimize the appearance of error.
  • Whenever the PPU address is pointing at a palette entry, this will become the current background colour whether rendering is on or off.

Because of these issues, it is best not to use this techniques where sprites may overlap the affected lines. Indiana Jones hides some potential visual errors by only working where the background is already blank, and only changing the background color. Games that change colors for a status bar can use blank lines at the top of the status bar to similarly avoid visual errors.

See Also

References