Ppu pallete and HSV help!!

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Ppu pallete and HSV help!!

Post by Anes »

Im trying to implement hue and value conversion incomming from the nes pallete.
Im very new to this and i need help.
According the wiki:
76543210
||||||||
||||++++- Hue (phase, determines NTSC/PAL chroma)
||++----- Value (voltage, determines NTSC/PAL luma)
++------- Unimplemented, reads back as 0
I found this HSV to RGB code -> http://www.cs.rit.edu/~ncs/color/t_convert.html
i pass the value of hue (bits 0-4) and Value (bits 5-6) and i can't get a good result.
Another thing is i haven't read the entire Wikipedia article about HSV. I just wanted a quick way.
Do i have to read the entire Wikipedia article?
Some code will be preciated.
thnks!!
ANes
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Ppu pallete and HSV help!!

Post by lidnariq »

It'll be easier to figure out what's going wrong if you provide us with an image of the colors your implementation is producing.
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: Ppu pallete and HSV help!!

Post by Anes »

It'll be easier to figure out what's going wrong if you provide us with an image of the colors your implementation is producing.
Ok im using:

Code: Select all

void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v )
{
	int i;
	float f, p, q, t;
	if( s == 0 ) {
		// achromatic (grey)
		*r = *g = *b = v;
		return;
	}
	h /= 60;			// sector 0 to 5
	i = floor( h );
	f = h - i;			// factorial part of h
	p = v * ( 1 - s );
	q = v * ( 1 - s * f );
	t = v * ( 1 - s * ( 1 - f ) );
	switch( i ) {
		case 0:
			*r = v;
			*g = t;
			*b = p;
			break;
		case 1:
			*r = q;
			*g = v;
			*b = p;
			break;
		case 2:
			*r = p;
			*g = v;
			*b = t;
			break;
		case 3:
			*r = p;
			*g = q;
			*b = v;
			break;
		case 4:
			*r = t;
			*g = p;
			*b = v;
			break;
		default:		// case 5:
			*r = v;
			*g = p;
			*b = q;
			break;
	}
}
And i get nearly invisible colors when i pass "0" to Saturation value in that function.
But if i change it for something bigger, like "128" i get this:

Image
ANes
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Ppu pallete and HSV help!!

Post by lidnariq »

Are you properly scaling the hue from its original range in the NES (1 through 12) up to the range of values expected by this function?

For the NES, the used saturation is a more complex function of the exact color specified, Colors $x0, $xD, $xE, $xF have 0 saturation, and the other ones have a similar but slightly varying saturation as a function of the upper nybble.
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: Ppu pallete and HSV help!!

Post by Anes »

Are you properly scaling the hue from its original range in the NES (1 through 12) up to the range of values expected by this function?
No im not scaling them. 1 trough 12? aren't they 4 bits wide (0 to 15)?. How do i dothat?
For the NES, the used saturation is a more complex function of the exact color specified, Colors $x0, $xD, $xE, $xF have 0 saturation, and the other ones have a similar but slightly varying saturation as a function of the upper nybble.
I didn't know that.
ANes
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Ppu pallete and HSV help!!

Post by lidnariq »

So, as you recall, only the bottom 6 bits of the value written are used. Of those, before you can parse things as HSV some special casing needs to happen first:
If the lower nybble is 0, 13, 14, or 15, saturation is 0.
If the lower nybble is 14 or 15, value is 0.
If the lower nybble is 1 through 12, these have color. Saturation and value are some function of the upper bits 4 and 5. Hue needs to be expanded from this range (1 through 12) to whatever your conversion function wants. (If your hue is specified in degrees, try (nybble-1)×30)
The exact values of $00, $10, $20, $30, $0d, $1d, $2d, and $3d are fixed greys, use a lookup table.
In the case of $0d, it's out of gamut (darker than black). Treat it as black normally, or something obvious (rainbow?) when debugging games.
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: Ppu pallete and HSV help!!

Post by Anes »

I think i will up. I don't understand well. I think i need more explanation.

Thank you very much for the help anyway.
ANes
Bavi_H
Posts: 141
Joined: Sun Mar 03, 2013 1:52 am
Location: Texas, USA
Contact:

Re: Ppu pallete and HSV help!!

Post by Bavi_H »

Anes wrote:According the wiki:
76543210
||||||||
||||++++- Hue (phase, determines NTSC/PAL chroma)
||++----- Value (voltage, determines NTSC/PAL luma)
++------- Unimplemented, reads back as 0
The bits of the color number are not strictly divided into hue and value like that. That's a very rough interpretation. If you do an image search for NES palette, you can find images like this that will give you a rough overview of how the NES colors numbers work:
the_NES_palette_by_erik_red.png
the_NES_palette_by_erik_red.png (4.38 KiB) Viewed 4127 times
Notice the columns where the color number ends in _0, _D, _E, and _F are all grayscale. In HSV, these colors have an undefined hue and zero saturation. The HSV value is somewhere between 0 for black and 1 for white.

Only the columns for color numbers that end in _1 to _C have a defined hue and a non-zero saturation. There are 12 columns of chromatic colors, so you might want to divide the 360 degree hue range into 12 parts each 30 degrees apart. If we take a starting guess that column _6 is the pure red hue (0 degrees), then you might add 30 degrees each column toward green, then blue, then back to red.*

Code: Select all

  color  HSV hue (degrees)
  -----  -------
    _1   210
    _2   240
    _3   270
    _4   300
    _5   330
    _6     0
    _7    30
    _8    60
    _9    90
    _A   120
    _B   150
    _C   180
To really understand how the color works, you have to read up about NTSC color signals. My basic understanding is this: The colors for a line of video are encoded into one signalthat changes as the line progresses across the screen. If the signal changes slowly, it's interpreted as grayscale colors. If the signal fluctuates quickly, it's interpreted as chromatic colors.

Take a look at the nesdev wiki article NTSC video, section Brightness Levels. For now, look at the "normalized" values for the rows "Color xx". For these normalized values, 0 represents black and 1 represents white.

For the grayscale colors, I think the HSV value is the normalized value from this table. Per the note under the table, columns _E and _F use the same level as color 1D (= 0 = black). And as I mentioned above, for grayscale colors, the hue is undefined and the saturation is zero.

The chromatic colors fluctuate the signal level between the _0 level on that row, and the _D level on that row. In HSV, I think the saturation is the height of the quickly fluctuating signal from low to high, and the value is the height of the middle of the fluctuating signal from the zero black level.

saturation = high - low
value = (high + low) / 2

Code: Select all

             _
             |    ^   ^   ^
  saturation |   | | | | | |
             |   | | | | | |   -
             |   | | | | | |   |
             _  .   v   v   .  | value
                               |
              0 -------------  -
* I think the real way to decode NTSC colors is much more complicated, but I think this might be a starting approximation. For example, you may have to tweak the starting hue value to something other than zero. Also, I think in the real way NTSC color maps to HSV, the hue values may not be equal steps of HSV hue 30 degrees apart. For example, on a vectorscope, the 6 main chromatic RGB colors (red, yellow, green, cyan, blue, and magenta) are unevenly spaced around the NTSC color phase circle, but in HSV these 6 main colors are equally spaced around the HSV hue circle. The 12 NES hues are equally spaced around the NTSC color phase circle, so there's some more complicated conversion to get them to the "correct" HSV hue circle values.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Ppu pallete and HSV help!!

Post by tepples »

Bavi_H is correct. NES color is HSL, but not in some paint programs' HSL/HSV color space that's based on following the edges of the RGB cube. It's based on an HSL interpretation of the YUV color space, where L is Y, and S and H are the polar coordinates of U and V.

Until you figure out how to synthesize your own palette, I'd recommend just preloading Bisqwit's palette.
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: Ppu pallete and HSV help!!

Post by Anes »

thanks for the answers.
Bavi_H is correct. NES color is HSL, but not in some paint programs' HSL/HSV color space that's based on following the edges of the RGB cube. It's based on an HSL interpretation of the YUV color space, where L is Y, and S and H are the polar coordinates of U and V.

Until you figure out how to synthesize your own palette, I'd recommend just preloading Bisqwit's palette.
I checked Bisqwit's web site, then i generated a palette and loaded, but it was too dark. What values in Bisqwit's web site would be for a "standard" or "acceptable" nes pallete??
ANes
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Ppu pallete and HSV help!!

Post by tepples »

The following settings on that page should be fairly accurate to how I've seen TVs configured: hue 0, sat 1.5, contrast 1.0, brightness 1.0, gamma 2.0-2.2
User avatar
Anes
Posts: 621
Joined: Tue Dec 21, 2004 8:35 pm
Location: Mendoza, Argentina

Re: Ppu pallete and HSV help!!

Post by Anes »

Thanks guys!!
ANes
Post Reply