Skip to content

Commit d597f21

Browse files
committed
Use standard RGB-YIQ matrix coefficients
https://forums.nesdev.org/viewtopic.php?p=172817#p172817 Bisqwit originally intended to match a certain palette using different display primaries ("FCC D65"). This resulted in colors that looked off. The modification here is to more closely match Bisqwit's own palette generator, which uses a more standard RGB-YIQ matrix. at hue 0, saturation 1.0, contrast 1.0, brightness 1.0, gamma 2.2 https://bisqwit.iki.fi/utils/nespalette.php IQ component coefficients are derived from the NTSC base matrix of luminance and color-difference. with color reduction factors and an additional 33 degree rotation of each respective component. https://www.nesdev.org/wiki/NTSC_video#Converting_YUV_to_signal_RGB
1 parent fa7c32f commit d597f21

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

Core/NES/BisqwitNtscFilter.cpp

+24-9
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ BisqwitNtscFilter::BisqwitNtscFilter(Emulator* emu) : BaseVideoFilter(emu)
6565
//Adjust outputbuffer to start at the middle of the picture
6666
outputBuffer += frameInfo.Width * (frameInfo.Height / 2);
6767

68-
DecodeFrame(120, 239 - GetOverscan().Bottom, _ppuOutputBuffer, outputBuffer, GetVideoPhaseOffset() + 120*341*_signalsPerPixel);
68+
DecodeFrame(120, 239 - GetOverscan().Bottom, _ppuOutputBuffer, outputBuffer, GetVideoPhaseOffset() + 120 * 341 * _signalsPerPixel);
6969

7070
_workDone = true;
7171
}
@@ -133,14 +133,29 @@ void BisqwitNtscFilter::OnBeforeApplyFilter()
133133

134134
_y = contrast / _yWidth;
135135

136-
_ir = (int)(contrast * 1.994681e-6 * saturation / _iWidth);
137-
_qr = (int)(contrast * 9.915742e-7 * saturation / _qWidth);
138-
139-
_ig = (int)(contrast * 9.151351e-8 * saturation / _iWidth);
140-
_qg = (int)(contrast * -6.334805e-7 * saturation / _qWidth);
141-
142-
_ib = (int)(contrast * -1.012984e-6 * saturation / _iWidth);
143-
_qb = (int)(contrast * 1.667217e-6 * saturation / _qWidth);
136+
// https://forums.nesdev.org/viewtopic.php?p=172817#p172817
137+
// Bisqwit originally intended to match a certain palette using different
138+
// display primaries ("FCC D65"). This resulted in colors that looked off.
139+
// The modification here is to more closely match Bisqwit's own palette
140+
// generator, which uses a more standard RGB-YIQ matrix.
141+
// at hue 0, saturation 1.0, contrast 1.0, brightness 1.0, gamma 2.2
142+
// https://bisqwit.iki.fi/utils/nespalette.php
143+
144+
// for some reason the original coefficients of bisqwit's decoding matrix
145+
// has been reduced by at least 10^-6
146+
double saturationFactor = 1000000;
147+
148+
// IQ coefficients are derived from the NTSC base matrix of luminance and color-difference
149+
// with color reduction factors and an additional 33 degree rotation of each respective component.
150+
// https://www.nesdev.org/wiki/NTSC_video#Converting_YUV_to_signal_RGB
151+
_ir = (int)(contrast * ( 0.956084 / saturationFactor) * saturation / _iWidth);
152+
_qr = (int)(contrast * ( 0.620888 / saturationFactor) * saturation / _qWidth);
153+
154+
_ig = (int)(contrast * (-0.272281 / saturationFactor) * saturation / _iWidth);
155+
_qg = (int)(contrast * (-0.646901 / saturationFactor) * saturation / _qWidth);
156+
157+
_ib = (int)(contrast * (-1.105617 / saturationFactor) * saturation / _iWidth);
158+
_qb = (int)(contrast * ( 1.702501 / saturationFactor) * saturation / _qWidth);
144159
}
145160

146161
void BisqwitNtscFilter::RecursiveBlend(int iterationCount, uint64_t *output, uint64_t *currentLine, uint64_t *nextLine, int pixelsPerCycle, bool verticalBlend)

0 commit comments

Comments
 (0)