Yet yet another NES palette capture

A place for your artistic side. Discuss techniques and tools for pixel art on the NES, GBC, or similar platforms.

Moderator: Moderators

Post Reply
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Yet yet another NES palette capture

Post by thefox »

Just for fun, I decided to try what kind of an NES palette I would get by capturing from my el cheapo USB capture stick (Terratec Cinergy Hybrid T USB XS). I wrote a ROM to display all of the colors one after another, ran the ROM on my NTSC NES and PAL NES, captured a video with VirtualDub, and ran an AviSynth script to generate a palette picture.

Capture format was YUY2 (the stick doesn't support anything else), losslessly compressed with Lagarith (probably didn't help much). Settings (brightness/contrast/hue/saturation/sharpness) were at defaults.

ROM + source for ASM6 is attached (read the source header for usage instructions). The captured videos are pretty big (~50 MB) so I won't put them here.

Here are the palettes I got:
ntsc.png
ntsc.png (4.06 KiB) Viewed 12939 times
pal.png
pal.png (4.08 KiB) Viewed 12939 times
AviSynth script: (If somebody else wants to use this, you will need to tweak a thing or two.)

Code: Select all

# c = AVISource( "ntsc-nes-full-palette.avi" )
c = AVISource( "pal-nes-full-palette.avi" )

# CONFIG: Use TFF or BFF depending on input video. If the colors aren't laid
# out properly, you picked the wrong one. "Properly" means gray in the upper
# left corner, then blue, and so on.
c = c.AssumeTFF()
# c = c.AssumeBFF()

# Remove bogus deinterlacing.
c = c.SeparateFields()

# Trim to only the relevant frames.
# CONFIG: Set the first (gray) frame.
# kFirstFrame = 47 # ntsc-nes-full-palette.avi
kFirstFrame = 48 # pal-nes-full-palette.avi
c = c.Trim( kFirstFrame, kFirstFrame+511 )

# Convert to RGB to have a common colorspace to work in independent of the
# input video format.
# \todo Not sure if there are downsides to doing this conversion?
c = c.ConvertToRGB()

# Crop to remove some crap from the borders.
kResultSize = 128
kCropHorz = (c.Width()  - kResultSize)/2
kCropVert = (c.Height() - kResultSize)/2
c = c.Crop( kCropHorz, kCropVert, -kCropHorz, -kCropVert )

# Average the result by resizing down.
# \note Resizing to less than 4x4 produces an error.
# \todo Not really sure how good of a job this really does of averaging
#       all the colors.
c = c.BicubicResize( 4, 4 )

# Crop to actually go down to 1x1.
c = c.Crop( 2, 2, -1, -1 )

# Convert to a single 16x32 frame.
c = c.WeaveColumns( 16 )
c = c.WeaveRows( 32 )

# Resize the palette elements up.
kPaletteElemSize = 24
c = c.PointResize( c.Width()*kPaletteElemSize, c.Height()*kPaletteElemSize )

c
Attachments
nes-palette-displayer-v01.zip
(2.52 KiB) Downloaded 468 times
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Yet yet another NES palette capture

Post by dougeff »

I know this is off subject, sorry...but what's the deal with your website being down (fauxgame)?
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Yet yet another NES palette capture

Post by thefox »

dougeff wrote:I know this is off subject, sorry...but what's the deal with your website being down (fauxgame)?
I used to have a VPS at LeaseWeb where I was hosting my sites. Through their amazing competency they managed to delete all of the data on my server without notice. I have some (fairly old) backups, but I can't bother to set up a new server, so I'll upload some of the old stuff to a new site when I get around to it.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Yet yet another NES palette capture

Post by tepples »

If you don't need any server-side stuff, you can just put your web root on Amazon S3.
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Re: Yet yet another NES palette capture

Post by Dwedit »

Github lets you host static websites for free.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Yet yet another NES palette capture

Post by tepples »

Don't GitHub Pages have to be the documentation for associated open source projects also hosted by GitHub?

EDIT: Probably not, though they're not secure.
User avatar
LightStruk
Posts: 45
Joined: Sat May 04, 2013 6:44 am

Re: Yet yet another NES palette capture

Post by LightStruk »

With the capture format set to YUY2, there are two colorspace conversions that led to the PNGs you posted: one from YIQ to YUV (in the capture hardware), and then another from YUV to RGB when the image was exported to RGB (in AviSynth, probably). The chroma subsampling in YUY2 (4:2:2) doesn't affect the results here, particularly if you are looking at the center of each rectangle.

I was going to ask which RGB primaries and white point you used, but with the intermediate YUV step, it gets even more complicated to produce the correct color.

As I pointed out here, the NTSC standard changed in 1987, AFTER the NES and Famicom were designed and released. The differences are a little bit subtle. If you're looking for what colors the designers saw when they made the PPU, not to mention what colors players saw on their own TVs before the late 1980s, then you should ensure that your NTSC captures use the right parameters.

As reported by Wikipedia, the correct primaries are:

Code: Select all

Xr     Yr     Xg     Yg     Xb     Yb     Xw     Yw
0.67	0.33	0.21	0.71	0.14	0.08   0.31   0.316
I'd be curious if your capture software or AviSynth lets you adjust these values.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Yet yet another NES palette capture

Post by tepples »

I thought YIQ was just a 33 degree phase rotation of YUV, because it was determined that the eye is more sensitive to chroma detail along the orange-teal axis than the green-magenta axis. The rotation from YIQ to YUV should be trivial to calculate in the card. In fact, all but the highest end devices decode NTSC as if it were YUV anyway because it's cheaper.
User avatar
LightStruk
Posts: 45
Joined: Sat May 04, 2013 6:44 am

Re: Yet yet another NES palette capture

Post by LightStruk »

tepples wrote:I thought YIQ was just a 33 degree phase rotation of YUV
I think that's right. I guess the same RGB primaries are plugged into the YUV->RGB equation as the YIQ->RGB equation, so it's just a question of whether AviSynth lets you change the primaries. ("c.ConvertToRGB()" almost certainly defaults to 1987 settings.)

The other reason a YUV capture might make determining the "true" palette more complicated is, if Wikipedia is to be believed, using a YUV filter instead of a YIQ filter is cheaper, but sacrifices some color accuracy.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Yet yet another NES palette capture

Post by thefox »

My goal here was not to find the one true palette, but rather to provide one data point from the wild. That's why I tried my best to document the model of the capture stick and what processing was done to obtain the result.

EDIT: Here are the .PAL files. The ones ending with "-full" contain all 512 colors; ones without only have the 64 non-emphasized colors.
terratec-cinergy-hybrid-t-usb-xs-nes-palettes.zip
(3.71 KiB) Downloaded 541 times
(Protip: Easy way to make a .PAL file from a palette image like that in the first post is to scale the image down (nearest neighbor) so that each color is 1x1 px, and then save it as a "raw" image (just the pixels, color components interleaved, no header). This can be done in Photoshop, and probably many other image editors as well.)
Last edited by thefox on Tue Jan 12, 2016 9:51 am, edited 2 times in total.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Yet yet another NES palette capture

Post by tepples »

LightStruk wrote:if Wikipedia is to be believed, using a YUV filter instead of a YIQ filter is cheaper, but sacrifices some color accuracy.
It sacrifices accuracy on the edges of colored areas, but not in flat areas. If you're just making an "NES palette", flat areas matter. If you're trying to emulate edge artifacts, you'll need to implement the YUV or YIQ decoder in software or in a shader anyway.
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Yet yet another NES palette capture

Post by dougeff »

...
Last edited by dougeff on Mon Feb 20, 2017 12:52 am, edited 1 time in total.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Yet yet another NES palette capture

Post by dougeff »

...
Last edited by dougeff on Mon Feb 20, 2017 12:52 am, edited 3 times in total.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Yet yet another NES palette capture

Post by dougeff »

Edit (removed)...reasons.
nesdoug.com -- blog/tutorial on programming for the NES
Post Reply