Mid-Frame Palette Swaps

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

SoleGooseProductions
Posts: 29
Joined: Mon Nov 11, 2013 2:23 pm

Mid-Frame Palette Swaps

Post by SoleGooseProductions » Wed Apr 01, 2015 6:03 pm

I have not seen a lot of information on this, but what I'd like to do (and I think I have heard is possible) is swap out the background palettes mid-frame, thereby separating the status bar from the playing field palettes. Just to note, I have divided the screen with a sprite 0 hit between the status bar and the playfield (allowing scrolling for the former, thanks Tokumaru!).

Besides the increased amount of color on the screen, my other goal is to be able to fade the playfield to black and move the player position between screens (in other words, faux flick-screen scrolling). I have this opeational, but the status bar currently must fade out as well. Besides a mid-frame palette change, which would allow the playfield to fade to black while preserving the status bar, is there another way to accomplish this same effect?

Thanks for any help!

User avatar
Drew Sebastino
Formerly Espozo
Posts: 3503
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Mid-Frame Palette Swaps

Post by Drew Sebastino » Wed Apr 01, 2015 6:45 pm

I don't really know anything about the NES, but if it's anything like the SNES, you change colors, not whole palettes at a time. I don't know how fast the NES can change colors, but what you could probably do for status bar is to have about 8 pixels vertically that are solid with one color so you can change 3 of the colors in that space, and then at the edge, you change the color of the bar to whatever you want it to be. I don't know how fast the NES can change colors, but I imagine it can do that.

lidnariq
Posts: 9867
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Mid-Frame Palette Swaps

Post by lidnariq » Wed Apr 01, 2015 7:27 pm

The NES requires that you turn off rendering to change the palette.

The strictest example of this is the title screen for Indiana Jones at the Last Crusade: viewtopic.php?p=139925#p139925 ­– they disable rendering for the rightmost ~20 pixels in order to change just one palette entry. You won't be able to do better, and you can only change the backdrop color this way. (It'll be visible as a dancing patch of color otherwise).

Less strict: You can change approximately 4 or 5 colors given one empty scanline, but the color of that blank scanline will be one of the colors you're replacing. See viewtopic.php?f=21&t=12299

Most aggressive: A fully-unrolled loop in RAM could replace all 13 colors of the backdrop in two scanlines, but your choice of either a smear of color or some odd greys will be visible. See also ccovell's demo Sayoonara!.

Least visible: You can change 6 bytes out of the 32 locations of palette RAM every scanline, minus three on both the first and last scanlines. Subtract two if you want to choose the color that will be visible on that scanline.

User avatar
tokumaru
Posts: 11908
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Mid-Frame Palette Swaps

Post by tokumaru » Wed Apr 01, 2015 7:34 pm

Mid-frame palette changes are very tricky, because rendering has to be disabled so the PPU can be written to, and when rendering is off and the VRAM address is pointing at the palette area (which it will be, since you'll be changing the palette), the colors being pointed at get displayed on the screen, instead of color 0.

This causes a "rainbow" to be displayed on the screen, which looks like a glitch. This can be minimized with the grayscale bit, so you get grays and white instead of colors, but that's not much better. To fully prevent glitches, you have to make sure that the VRAM address is only pointing at the palette area during HBlank, so you can realistically change about 2 colors per scanline.

If that's not a problem, and you can live with a few blank lines between the playfield and the status bar, just disable rendering (as close to the end of the scanline as possible, to avoid sprite corruption on the next frame), time your code so that the VRAM address is never pointing at $3F00-$3FFF during the visible portion of the scanline, set the scroll, and finally turn rendering back on.

tepples
Posts: 22162
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Mid-Frame Palette Swaps

Post by tepples » Wed Apr 01, 2015 8:03 pm

lidnariq wrote:Less strict: You can change approximately 4 or 5 colors given one empty scanline, but the color of that blank scanline will be one of the colors you're replacing.
I think this is the way forward. If the blank scanlines are drawn with the extra backdrop colors ($3F04 one line, $3F08 the next, $3F0C after that), the seam should look clean. Then you just have to make sure 13 cycles land within the (341-256)/3 = 28-cycle horizontal blanking period, giving plenty of margin.

Code: Select all

  bit $2007    ; Skip one of the extra backdrop colors, putting pointer at a color
               ; The last cycle of this instruction has to land in hblank.
  sta $2007    ; Write one color
  stx $2007    ; Write one color
  sty $2007    ; Write one color, putting pointer at next extra backdrop color
               ; The last cycle of this instruction has to land in hblank.
  ; OMITTED: wait for next scanline and load next 3 colors

User avatar
tokumaru
Posts: 11908
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Mid-Frame Palette Swaps

Post by tokumaru » Thu Apr 02, 2015 7:41 am

tepples wrote:

Code: Select all

  bit $2007    ; Skip one of the extra backdrop colors, putting pointer at a color
               ; The last cycle of this instruction has to land in hblank.
  sta $2007    ; Write one color
  stx $2007    ; Write one color
  sty $2007    ; Write one color, putting pointer at next extra backdrop color
               ; The last cycle of this instruction has to land in hblank.
  ; OMITTED: wait for next scanline and load next 3 colors
Cool idea, using the extra colors to your advantage. Also, it's a nice coincidence that each palette has 3 colors and the 6502 has 3 general purpose registers.

8bitMicroGuy
Posts: 314
Joined: Sun Mar 08, 2015 12:23 pm
Location: Croatia

Re: Mid-Frame Palette Swaps

Post by 8bitMicroGuy » Thu Apr 02, 2015 8:51 am

I was just wishing to do this to my game. The NESCraft would be split screen and when dawn would come after the night, the pallette on scanlines will change to show the sunlight effect.
tepples wrote:

Code: Select all

  bit $2007    ; Skip one of the extra backdrop colors, putting pointer at a color
               ; The last cycle of this instruction has to land in hblank.
  sta $2007    ; Write one color
  stx $2007    ; Write one color
  sty $2007    ; Write one color, putting pointer at next extra backdrop color
               ; The last cycle of this instruction has to land in hblank.
  ; OMITTED: wait for next scanline and load next 3 colors
I cannot find a nice explanation for what BIT does. Does it wait for HBlank or something?

User avatar
tokumaru
Posts: 11908
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Mid-Frame Palette Swaps

Post by tokumaru » Thu Apr 02, 2015 10:33 am

In this case, bit reads the PPU register without modifying any CPU registers. This is done to skip one color when writing to the palette.

User avatar
Jarhmander
Formerly ~J-@D!~
Posts: 511
Joined: Sun Mar 12, 2006 12:36 am
Location: Rive nord de Montréal

Re: Mid-Frame Palette Swaps

Post by Jarhmander » Thu Apr 02, 2015 4:32 pm

BIT is used here only for its read' side effect (reading $2007 will increment by 1/32 the PPU address just like writes). You could just as well use any of the compare instructions for that purpose (though CPY $2007 looks a bit bizarre, we're much more used to see BIT used as reads).
((λ (x) (x x)) (λ (x) (x x)))

SoleGooseProductions
Posts: 29
Joined: Mon Nov 11, 2013 2:23 pm

Re: Mid-Frame Palette Swaps

Post by SoleGooseProductions » Mon Apr 06, 2015 4:34 am

Thanks for the advice and direction guys. Tepples, the way that you propose to do things fits perfect with what I'd like to do, and should create a nice clean look. Thanks again!

User avatar
Tsutarja
Posts: 123
Joined: Sun Oct 12, 2014 11:06 am
Location: Finland

Re: Mid-Frame Palette Swaps

Post by Tsutarja » Mon Apr 06, 2015 9:04 am

tokumaru wrote:This causes a "rainbow" to be displayed on the screen, which looks like a glitch.
If this "rainbow" doesn't look too weird, can it be used as a graphical effect? Can it be manipulated where it's going to appear and can it cause other graphical glitches? Another important question is that is this effect emulated (on FCEUX for an example)?

EDIT: Also, there is something else that caught my attention: What exactly is HBlank and when does it happen?
UP SIDE DOWN A B A B B A B A Hidari migi
L R L R STOP & DASH & UP & TALK Ijou nashi

tepples
Posts: 22162
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Mid-Frame Palette Swaps

Post by tepples » Mon Apr 06, 2015 9:15 am

The "rainbow" is used as a graphical effect in the "flowing palette" demo and the game Micro Machines. I seem to remember the third-party NESRGB mod (but not the PlayChoice PPU swap mod) showing wrong colors with these programs.

Horizontal blanking (hblank) happens at the end of each scanline. On the NES, it lasts about 26 CPU cycles.

User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Mid-Frame Palette Swaps

Post by Movax12 » Mon Apr 06, 2015 9:27 am

BTW another game that uses this (I think with sprite 0 for timing): https://www.youtube.com/watch?v=geHAoWQGSfI
Changes palette at the status bar, obvious glitching. Maybe turn off your sound before clicking that link though.

User avatar
tokumaru
Posts: 11908
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Mid-Frame Palette Swaps

Post by tokumaru » Mon Apr 06, 2015 10:25 am

Tsutarja wrote:If this "rainbow" doesn't look too weird, can it be used as a graphical effect? Can it be manipulated where it's going to appear and can it cause other graphical glitches?
It's hard to make use of it for effects because of the lack of proper CPU-PPU synchronization. Blargg's palette demos uses a pretty complex trick to get the PPU and CPU as synchronized as possible, and there's still some jitter in them. In an actual game it would be even tougher to achieve proper synchronization, and even if you tried to be consistent with the effect it would jitter by several pixels, and that usually looks like a glitch.
Another important question is that is this effect emulated (on FCEUX for an example)?
No, not on FCEUX. But other emulators do emulate this (Nintendulator and Nestopia for sure).
EDIT: Also, there is something else that caught my attention: What exactly is HBlank and when does it happen?
You're probably familiar with the vertical blank (VBlank), which is the time when no video is generated and the TV is supposedly moving the beam back to the upper left corner of the screen. Well, the HBlank (horizontal blank) is similar, it's the time when the TV moves the beam from the end of a scanline (on the right) to the beginning of the next (on the left). It's a much smaller period than VBlank, and there's hardly any time to do any useful PPU operations there, but raster effects are usually timed around HBlank to avoid visible glitches.

User avatar
za909
Posts: 217
Joined: Fri Jan 24, 2014 9:05 am
Location: Hungary

Re: Mid-Frame Palette Swaps

Post by za909 » Mon Apr 06, 2015 11:49 am

If all of this is too much hassle for you, wouldn't it make sense to use the emphasis bits in $2001 for your status bar? You would still depend on one of the palettes but it would still produce different colors.

Post Reply