It is currently Fri Nov 24, 2017 7:18 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Tue Nov 07, 2017 2:48 am 
Offline

Joined: Wed May 15, 2013 9:33 am
Posts: 9
On the topic of palette swaps. I've read a few documents and came to know that palette swapping between an HUD (as long as it doesn't contain sprites) and the game portion is possible and not too hard. If minor graphical glitches are tolerated, then it won't consume too much time either.
However it becomes very problematic if one wants to do a palette swap within the game region e.g. splitting the game region into two blocks and use different palettes for them.

The specific case is, I have a few blank scanlines to spend, but the protagonist's sprites still need to display correctly on these scanlines.
So:
> Is it possible at all?
> If not, any alternative solutions to make it involve least noticable graphical glitches?


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 2:52 am 
Offline
Formerly WheelInventor

Joined: Thu Apr 14, 2016 2:55 am
Posts: 1024
Location: Gothenburg, Sweden
I don't know a way to avoid it other than making a level so that objects of interest never overlap the seam, which could work on some specific platforming stage layouts.

Just switching the common bg colour should be even faster than overwriting a full palette entry, if that helps.

One last option i can think of is playing with timed emphasis bits to get rows of different colour, but again, sprite presentation will be affected.

_________________
http://www.frankengraphics.com - personal NES blog


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 10:29 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
Quoting bananmos

"1) Turn off BG and sprite rendering using $2001
2) Write palette address to $2006 (though high byte can be latched before step (1)
3) Write palette color to $2007
4) Restore scroll position using $2006 and $2005 writes. (as it is a fixed yscroll location with no xscroll, you can probably get away with writing $2006 only and skip the highest fine Y-scroll bit)
5) Turn on BG and sprite rendering using $2001

And even with all those steps carefully optimised, there is the final gotcha: Any midscreen palette change will corrupt the sprites being fetched for the next line."

Source...
viewtopic.php?f=2&t=15142

Edit. Misspelled.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Last edited by dougeff on Tue Nov 07, 2017 10:32 am, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 10:32 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5842
Location: Canada
It's feasible to change one palette entry per scanline, during the horizontal blank period, but yeah, having to turn off rendering for this does mean you will lose a the following scanline of sprites too.

lidnariq made a nice timing diagram a while ago of Indiana Jones doing it:
https://forums.nesdev.com/viewtopic.php?p=139925#p139925

The only thing special about moving it up and down is that this is just one more factor on top of all the other timing you need to account for. A scanline IRQ (e.g. MMC3) would probably help a lot here.


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 10:43 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
BTW, I the Indiana Jones Last Crusade does 2 writes to $2006 to realign the scroll after the palette write. This can only be done at a exactly divisible by 8 Y position.

Therefore, to do more than 1 palette change would be spread out over (8 * # of palette changes) scanlines.

(# of palette changes, minus one, times 8)

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Last edited by dougeff on Tue Nov 07, 2017 5:21 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 11:01 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5842
Location: Canada
Oh, yeah I forgot about that limitation.

Horizontal blank is only about 21 cycles. Time for I guess 4 or 5 writes? You can shift some of the needed writes out into the visible part of the scanline (and some of them can be visually benign), but yeah it's not enough for a full flush of the scroll registers, unfortunately.


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 11:26 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6458
Location: UK (temporarily)
dougeff wrote:
BTW, I the Indiana Jones Last Crusade does 2 writes to $2006 to realign the scroll after the palette write. This can only be done at a exactly divisible by 8 Y position.
Wut?

Fine Y can be set to 0 through 3, just not 4-7. Fine X can't be changed.


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 11:39 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
Hmm. Well, I've never tested multiple palette writes mid-screen.

I thought 2 writes to $2006 cleared the fine Y. Is that not correct?

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 11:43 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5842
Location: Canada
dougeff wrote:
Hmm. Well, I've never tested multiple palette writes mid-screen.

I thought 2 writes to $2006 cleared the fine Y. Is that not correct?

It clears only the top bit of fine Y.

Reference:
Wiki: $2006 first write


Though it also pays to notice that Indiana Jones is able to do some of its writes early without visual artifacts specifically because it's only changing the background colour.


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 12:08 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6458
Location: UK (temporarily)
rainwarrior wrote:
It clears only the top bit of fine Y.
See also: Visual2C02 transistor t15006

Quote:
Though it also pays to notice that Indiana Jones is able to do some of its writes early without visual artifacts specifically because it's only changing the background colour.
And also because the background color is the only thing being displayed when it turns off the screen early.


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 1:11 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
I ran some tests. (emulators)

I think you can safely change 3 palette colors in 1 H-blank (contiguous palette entries), maybe 4 (I was getting occasional glitchiness when trying 4).

I didn't test how sprites react to this change. It would have to be tested on an actual NES. Maybe another day.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 1:37 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6458
Location: UK (temporarily)
I mean, we know the window. Disabling rendering will always break sprites on the following scanline. Disabling rendering at the wrong time will break sprites for the rest of the field.

Each scanline has 85px that aren't used for blitting pixels to the display; of those, 64 pixels (the eight sprite fetch periods) can be stolen without breaking background rendering. If the left or right edges of the screen are just the backdrop color you can steal a little more time.

64px is only 21cy; if all the values you're writing can fit in A, X, and Y without loading new values, then you have exactly the amount of time to update one palette entry (6 writes * 4 cycles/write - 3 cycles for the first write being loaded in)


w7n wrote:
a few blank scanlines to spend, but the protagonist's sprites still need to display correctly on these scanlines.
So:
> Is it possible at all?
In summary: No. But you could use a horizontal stripe of background tiles that are equivalent to your protagonist's sprite, and set the background scroll appropriately.


Top
 Profile  
 
PostPosted: Tue Nov 07, 2017 9:31 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5842
Location: Canada
dougeff wrote:
I think you can safely change 3 palette colors in 1 H-blank (contiguous palette entries), maybe 4 (I was getting occasional glitchiness when trying 4).

If rendering is off, yes, it's very convenient to use groups of 4 colours per scanline. Something like:
Code:
BIT $2007 ; skip background colour
STA $2007
STX $2007
STY $2007

It's only 16 cycles but it's helpful to have some wiggle room for placement within the horizontal blank. (Also, depending on your TV, parts of that 64-pixel "blank" area might actually be visible.)

This leaves the PPU address pointing at the next background colour slot, too, so you can leave it there across the next visible scanline without any funny colours showing. ...and of course you're going to want a blank scanline after it to give you an opportunity to reload the scroll and put the renderer back in order.

I do this in my palette display ROM: thread


Top
 Profile  
 
PostPosted: Fri Nov 10, 2017 12:18 am 
Offline

Joined: Wed May 15, 2013 9:33 am
Posts: 9
Thanks everyone, I've got a better grasp of the whole thing. Seems that besides the HUD it could only be used in certain cutscenes at best.


Top
 Profile  
 
PostPosted: Fri Nov 10, 2017 8:46 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1835
Location: DIGDUG
"If rendering is off, yes"


Oh (slap head). You guys were talking about changing a palette WITHOUT turning rendering off.

I was testing turning rendering off, and writing 3 palette colors, then 2 writes $2006 to set scroll, then screen back on, without glitches.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group