when can i change the palette?

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

Post Reply
iamooos
Posts: 16
Joined: Tue Oct 18, 2022 2:37 pm

when can i change the palette?

Post by iamooos »

i was originally led to believe by the technical articles that i read, that i could change the palette any time i wanted and there was just a limit to the size of the attribute table.

but it doesn't seem to be the truth?

i can only use like one palette per frame?

i thought you would be able to change palette for the second nametable, but it's not possible?

i thought you would be able to change palette after splitting the screen with a sprite 0 hit, but it cannot be done???


please tell me what the rules and limits are for changing the palette, cause i want to create some waterfall style effects by cycling a palette, but now it sounds like it will be really hard and limited to do something that sounded so simple?????????

is there something i am missing? i want to be able to split the screen, and maybe have a cycling palette waterfall in one of the splits. or god forbid both even (or different colors altogether in both of the splits), am i being unrealistic? i don't think i am asking the poor famicom to display ps2 era graphics.

this should be possible with mapper0 i thought.



setting the background tile palette after sprite0 code changes the color of everything above before the split too, it affects the entire screen. that's not what i want at all
is the NES limited to setting the palette once per frame and locking it in place and that's the colors that will show up on screen, period, i thought i woud be able to switch it mid frame if i wasn't too picky about 16x16 pixel blocks? turns out i was mistaken?
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: when can i change the palette?

Post by Quietust »

You can only update the palette while the PPU is not busy rendering the screen, so that only leaves you two options:
1. Update it during VBLANK (along with your other VRAM updates).
2. Disable rendering mid-screen, perform the update, then re-enable rendering.

The second technique is generally only needed if you're trying to be really fancy, and you need to be careful when doing it in order to avoid graphical glitches.
iamooos wrote: Sun Oct 23, 2022 4:16 am i thought you would be able to change palette for the second nametable, but it's not possible?
There is only one palette inside the PPU, and it applies to all 4 nametables (and all sprites) at the same time.
iamooos wrote: Sun Oct 23, 2022 4:16 am i thought you would be able to change palette after splitting the screen with a sprite 0 hit, but it cannot be done???
As mentioned above, you can do this, but the PPU won't be able to render the existing background while you do so, so there will be a visible glitch.
iamooos wrote: Sun Oct 23, 2022 4:16 am setting the background tile palette after sprite0 code changes the color of everything above before the split too, it affects the entire screen. that's not what i want at all
It sounds like you might be using an inaccurate emulator which renders the entire screen all at once rather than one scanline at a time - use a better one and what you're trying ought to work fine.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: when can i change the palette?

Post by tokumaru »

iamooos wrote: Sun Oct 23, 2022 4:16 ami was originally led to believe by the technical articles that i read, that i could change the palette any time i wanted
You definitely CAN'T change the palette at any time. The palette is accessed as if it was part of VRAM, so the same limitations as those of other VRAM accesses apply. In a nutshell, you can't write to VRAM while the NES is rendering an image.
and there was just a limit to the size of the attribute table.
The attribute tables just say which palette each 16x16-pixel area uses, and the only options are 0, 1, 2 or 3, which are the 4 background palettes the NES has.
i can only use like one palette per frame?
This is generally the case, seeing as vblank (the period between frames when the PPU is not rendering) is the safest time to write to VRAM. In theory, you can manually disable rendering mid-frame and write to VRAM, but there are several limitations and timing issues that make this much more difficult than it sounds.
i thought you would be able to change palette for the second nametable, but it's not possible?
Both name tables have access to the same 4 palettes, always. Any palette changes will affect both name tables.
i thought you would be able to change palette after splitting the screen with a sprite 0 hit, but it cannot be done???
It can be done, but it's hard. First - you have to disable rendering, otherwise you can't access VRAM. Disabling rendering means that the picture will be blank for a few scanlines - no background, no sprites, just a solid color. Second - the solid color that gets displayed changes depending on the palette entry that the VRAM address is currently pointing to. So if you mindlessly change several color in a row, the blank scanlines will look like a rainbow glitchfest. To avoid glitches, you have to time the VRAM writes so they happen during hblank, which lasts long enough just for a couple of color changes, so you need several blank scanlines in order to update multiple colors. Third - after messing with the VRAM address, the scroll is messed up, so you need to use the infamous $2006/5/5/6 trick to restore the scroll to what it's supposed to be before turning rendering back on. Fourth - disabling rendering mid-frame interferes with the OAM refresh cycle and can cause OAM corruption when you turn rendering back on. There are very precise moments when rendering must be disabled and enabled to avoid this.
i want to create some waterfall style effects by cycling a palette
Waterfall effects don't require any mid-frame palette changes, you can simply change the palette during vblank, between frames. The real problem with palette cycling on the NES is that the palettes are really small and there are few of them. This means that the cycles are very short (3 frames if the background color is not part of the cycle) and with only 4 palettes, 1 palette dedicated to this effect is 25% of everything you have.

For this reason, some games with suitable mappers create these effects by changing the tiles over time instead of the palette. For this you need either CHR-RAM or the ability to switch CHR-ROM banks in small enough chunks, but both of these techniques have their own catches too.
i don't think i am asking the poor famicom to display ps2 era graphics.
This is not a very good attitude going into retro game development. You're not being forced to use limited hardware, you're doing it because you chose to do it. Knowing the limitations of the machines you're considering working with should be a part of your decision making process, and there's no point in getting angry because a machine can't do something you wanted it to. You can always go with a more modern console if you find the limitations too annoying.
setting the background tile palette after sprite0 code changes the color of everything above before the split too
If you don't change them back for the next frame, then yeah, it does. The NES only has 1 set of palettes, so once you change them, those changes are permanent. If you want the next frame to have different colors above the split, you have to restore the palette to its previous state after the current frame finishes rendering and before the next one starts.

Keep in mind that, like I explained above, mid-frame palette changes on the NES are notoriously hard to pull off correctly. Very few games did it back in the day (only 4 or 5 games out of the entire library are known to do it, if I'm not mistaken), and most homebrewers, even the most experienced ones, avoid it.
User avatar
Individualised
Posts: 310
Joined: Mon Sep 05, 2022 6:46 am

Re: when can i change the palette?

Post by Individualised »

tokumaru wrote: Sun Oct 23, 2022 6:15 am Very few games did it back in the day (only 4 or 5 games out of the entire library are known to do it, if I'm not mistaken)
I may be mistaken or simply misremembering (especially for the former game), but don't games like Double Dragon 2 and Boogerman change the palette mid-screen in order to have a seperate palette for the status bar? Otherwise how come the status bars in those games appear to have an incorrect palette when viewed in an emulator's nametable viewer?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: when can i change the palette?

Post by tokumaru »

I can't debug any games right now, but I'll take a look later. I definitely wasn't counting pirate demakes like Boogerman when I said that, though.

Different colors for a status bar is probably the most reasonable use case for mid-screen palette changes, since a few blank scanlines aren't such a big deal in that situation.
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: when can i change the palette?

Post by Memblers »

Individualised wrote: Sun Oct 23, 2022 9:58 am I may be mistaken or simply misremembering (especially for the former game), but don't games like Double Dragon 2 and Boogerman change the palette mid-screen in order to have a seperate palette for the status bar? Otherwise how come the status bars in those games appear to have an incorrect palette when viewed in an emulator's nametable viewer?
I looked at Double Dragon 2, and it starts out with a status bar in both nametables, with one of them having unitialized attribute table but isn't displayed because of scrolling. It alternates which nametable holds the status bar as it scrolls vertically. So it's just attribute differences, and offscreen stuff looking weird as usual.
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: when can i change the palette?

Post by rainwarrior »

Individualised wrote: Sun Oct 23, 2022 9:58 amI may be mistaken or simply misremembering (especially for the former game), but don't games like Double Dragon 2 and Boogerman change the palette mid-screen in order to have a seperate palette for the status bar? Otherwise how come the status bars in those games appear to have an incorrect palette when viewed in an emulator's nametable viewer?
Not Double Dragon 2, and not sure how to find the bootlege Boogerman game, but there's probably a different reason for what you saw in that one...

If you want an example of a game that does it, Startropics does indeed change some palette entries for the status bar.

It's doable, but it's not easy. I'd consider it an expert level NES rendering effect. If attempted, there will be a collateral impact on your game's design. It's not just something that can be added on in isolation.

With rendering totally off (i.e. blank black scanlines) we can change 3 colours in hblank per scanline. Startropics has some blank lines at the top of its status bar in this way.

If you can't do black lines of rendering off to separate things, you can only change 1 colour in hblank per scanline, and it's even harder to pull off. Indiana Jones does this for a sky gradient on its title screen.
User avatar
Individualised
Posts: 310
Joined: Mon Sep 05, 2022 6:46 am

Re: when can i change the palette?

Post by Individualised »

Memblers wrote: Sun Oct 23, 2022 9:31 pm I looked at Double Dragon 2, and it starts out with a status bar in both nametables, with one of them having unitialized attribute table but isn't displayed because of scrolling. It alternates which nametable holds the status bar as it scrolls vertically. So it's just attribute differences, and offscreen stuff looking weird as usual.
That's probably what I was thinking of - since Boogerman also features full 4 way scrolling with a status bar it was probably the same thing there too. Thanks for checking.
iamooos
Posts: 16
Joined: Tue Oct 18, 2022 2:37 pm

Re: when can i change the palette?

Post by iamooos »

thanks!!

so it's probably doable but best not to even try?

i just want to make sure i can at least turn off the ppu at the right time, but i don't think my code is working.


i should be able to read the 2002 address like this,





B = PEEK(0x2002);

and then if multiplied by bit number 6 mask is true


if((B & 0x40) != 0)
{

ppu_off();

}




but i can't even make this work on the emulator, i don't know why, i believe its supposed to work like this?

the sprite 0 is on a blue strip at the middle of the screen, its the same code as shiru's split sample.

i tried doing it before and after wait for nmi, but really none of it is the behavior i expect to get
Last edited by iamooos on Mon Oct 24, 2022 3:43 pm, edited 1 time in total.
User avatar
Individualised
Posts: 310
Joined: Mon Sep 05, 2022 6:46 am

Re: when can i change the palette?

Post by Individualised »

What emulator are you using?
iamooos
Posts: 16
Joined: Tue Oct 18, 2022 2:37 pm

Re: when can i change the palette?

Post by iamooos »

i'm using MESEN, i think it's debugger is awesome even if i dont realy know how to use it, but it seems like it has all the bells and whistles
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: when can i change the palette?

Post by rainwarrior »

iamooos wrote: Mon Oct 24, 2022 3:33 pmso it's probably doable but best not to even try?
I'd say if you really want it, it can be done, but the timing is tricky to get right. It's the kind of thing you definitely have to try against a real NES machine, and can't really rely on emulators to diagnose whether your code is correct. I don't know how much experience you already have with the NES, but I probably wouldn't recommend it yet if you'd consider yourself a beginner.


As far as the timed code you're asking about goes, there are a few things I'd suggest.

1. When waiting for sprite 0, the first step is waiting for the sprite flag to clear, otherwise it's possible you will get the old sprite value from the previous frame. (It clears at the end of vblank.)

2. Waiting for sprite 0 and doing simple render changes is okay to do in C like this, but the timing for horizontal blank that you need for palettes is far too narrow for C. It would have to be done in assembly.

In C it would be fine for waiting then changing the horizontal scroll, or hiding sprites for a status bar, or something like that, which might be okay if it happens anywhere in the middle of a scanline. Palette changes have to be much more precise.

3. You should not turn the PPU off in C code in response to a sprite 0 hit event. In general turning the PPU off should be either precisely timed in assembly, or made to happen during vblank when the PPU is already inactive and safe to interact with. I don't know what your "ppu_off()" function does, but if I was making a C library for NES, I would have that function automatically wait for vblank, and it just wouldn't work mid-screen.

(The main reason for this is a sprite corruption hardware bug, see: the last entry in the Errata article OAM section.)

4. I would recommend waiting for both vblank and sprite 0 hit in your loop ($C0 not just $40). This gives a fallback in case there was some bug or problem affecting the sprite. Vblank is guaranteed to happen at the end of the frame, but if sprite 0 doesn't happen your program could get caught in an infinite loop. So, testing for $C0 rather than $40 will give you a fallback that lets your game keep going in the worst case.

In assembly the wait would look like this:

Code: Select all

; wait for sprite 0 flag to clear
:
bit $2002
bvs :-
; wait for sprite 0 or vblank to happen
lda #$C0
:
bit $2002
beq :-
In C the wait might look like:

Code: Select all

while (PEEK(0x2002) & 0x40);
while (0 == (PEEK(0x2002) & 0xC0));
// wait finished
However, for a couple of reasons I would strongly recommend putting code that interacts with the hardware registers in assembly functions, rather than trying to peek and poke at that hardware from C. Like, put that assembly code above into a function wrapper and then your C code could look like this:

Code: Select all

sprite0_hit();
Last edited by rainwarrior on Wed Nov 09, 2022 5:21 pm, edited 1 time in total.
iamooos
Posts: 16
Joined: Tue Oct 18, 2022 2:37 pm

Re: when can i change the palette?

Post by iamooos »

thank you so much for your detailed answer.
i wish i was more experienced in the hardware so it isn't wasted on me, but i think i will come back to this sooner rather than later.

i fell ill and couldn't respond earlier. but i really appreciate the clarity
Post Reply