@@ -14,24 +14,26 @@ BisqwitNtscFilter::BisqwitNtscFilter(shared_ptr<Console> console, int resDivider
1414 _stopThread = false ;
1515 _workDone = false ;
1616
17- const int8_t signalLumaLow[4 ] = { -29 , -15 , 22 , 71 };
18- const int8_t signalLumaHigh[4 ] = { 32 , 66 , 105 , 105 };
17+ const int8_t signalLumaLow[2 ][ 4 ] = { { -29 , -15 , 22 , 71 }, { - 38 , - 28 , - 1 , 34 } };
18+ const int8_t signalLumaHigh[2 ][ 4 ] = { { 32 , 66 , 105 , 105 }, { 6 , 31 , 58 , 58 } };
1919
2020 // Precalculate the low and high signal chosen for each 64 base colors
21- for (int i = 0 ; i <= 0x3F ; i++) {
22- int r = (i & 0x0F ) >= 0x0E ? 0x1D : i;
23-
24- int m = signalLumaLow[r / 0x10 ];
25- int q = signalLumaHigh[r / 0x10 ];
26- if ((r & 0x0F ) == 13 ) {
27- q = m;
28- } else if ((r & 0x0F ) == 0 ) {
29- m = q;
21+ // with their respective attenuated values
22+ for (int h = 0 ; h <= 1 ; h++) {
23+ for (int i = 0 ; i <= 0x3F ; i++) {
24+ int r = (i & 0x0F ) >= 0x0E ? 0x1D : i;
25+
26+ int m = signalLumaLow[h][r / 0x10 ];
27+ int q = signalLumaHigh[h][r / 0x10 ];
28+ if ((r & 0x0F ) == 13 ) {
29+ q = m;
30+ } else if ((r & 0x0F ) == 0 ) {
31+ m = q;
32+ }
33+ _signalLow[h][i] = m;
34+ _signalHigh[h][i] = q;
3035 }
31- _signalLow[i] = m;
32- _signalHigh[i] = q;
3336 }
34-
3537 _extraThread = std::thread ([=]() {
3638 // Worker thread to improve decode speed
3739 while (!_stopThread) {
@@ -165,33 +167,53 @@ void BisqwitNtscFilter::RecursiveBlend(int iterationCount, uint64_t *output, uin
165167void BisqwitNtscFilter::GenerateNtscSignal (int8_t *ntscSignal, int &phase, int rowNumber)
166168{
167169 for (int x = -_paddingSize; x < 256 + _paddingSize; x++) {
168- uint16_t color = _ppuOutputBuffer[(rowNumber << 8 ) | (x < 0 ? 0 : (x >= 256 ? 255 : x))];
169-
170- int8_t low = _signalLow[color & 0x3F ];
171- int8_t high = _signalHigh[color & 0x3F ];
172- int8_t emphasis = color >> 6 ;
170+ // pixel_color = Pixel color (9-bit) given as input. Bitmask format: "eeellcccc".
171+ uint16_t pixel_color = _ppuOutputBuffer[(rowNumber << 8 ) | (x < 0 ? 0 : (x >= 256 ? 255 : x))];
172+
173+ int8_t emphasis = pixel_color >> 6 ;
174+ int8_t color = pixel_color & 0x3F ;
175+
176+ auto phase_shift_up = [=](uint16_t value, uint16_t amt) {
177+ amt = amt % 12 ;
178+ uint16_t uint12_value = value & 0xFFF ;
179+ uint32_t result = (((uint12_value << 12 ) | uint12_value) & 0xFFFFFFFF );
180+ return uint16_t ((result >> (amt % 12 )) & 0xFFFF );
181+ };
182+
183+ uint16_t emphasis_wave = 0 ;
184+ if (emphasis & 0b001 ) // tint R; color phase C
185+ emphasis_wave |= 0b000000111111 ;
186+ if (emphasis & 0b010 ) // tint G; color phase 4
187+ emphasis_wave |= 0b001111110000 ;
188+ if (emphasis & 0b100 ) // tint B; color phase 8
189+ emphasis_wave |= 0b111100000011 ;
190+ if (emphasis)
191+ emphasis_wave = phase_shift_up (emphasis_wave, (color & 0x0F ));
173192
174193 uint16_t phaseBitmask = _bitmaskLut[std::abs (phase - (color & 0x0F )) % 12 ];
194+ bool attenuate = 0 ;
175195
176- uint8_t voltage;
177- for (int j = 0 ; j < 8 ; j++) {
178- phaseBitmask <<= 1 ;
179- voltage = high;
180- if (phaseBitmask >= 0x40 ) {
181- if (phaseBitmask == 0x1000 ) {
182- phaseBitmask = 1 ;
183- } else {
184- voltage = low;
185- }
186- }
196+ int8_t voltage;
197+ for (int j = 0 ; j < _signalsPerPixel; j++) {
198+ // colors $xE and $xF are not affected by emphasis
199+ // https://forums.nesdev.org/viewtopic.php?p=160669#p160669
200+ if ((color & 0x0F ) <= 0x0D )
201+ attenuate = (phaseBitmask & emphasis_wave);
187202
188- if (phaseBitmask & emphasis) {
189- voltage -= voltage / 4 ;
203+ voltage = _signalHigh[attenuate][color];
204+
205+ // 12 phases done, wrap back to beginning
206+ if (phaseBitmask >= (1 << 12 )) {
207+ phaseBitmask = 1 ;
190208 }
191-
209+ else {
210+ // 6 out of 12 cycles
211+ if (phaseBitmask >= (1 << 6 ))
212+ voltage = _signalLow[attenuate][color];
213+ }
214+ phaseBitmask <<= 1 ;
192215 ntscSignal[((x + _paddingSize) << 3 ) | j] = voltage;
193216 }
194-
195217 phase += _signalsPerPixel;
196218 }
197219 phase += (341 - 256 - _paddingSize * 2 ) * _signalsPerPixel;
@@ -217,7 +239,7 @@ void BisqwitNtscFilter::DecodeFrame(int startRow, int endRow, uint16_t *ppuOutpu
217239 GenerateNtscSignal (rowSignal, phase, y);
218240
219241 // Convert the NTSC signal to RGB
220- NtscDecodeLine (lineWidth * _signalsPerPixel, rowSignal, outputBuffer, (startCycle + 7 ) % 12 );
242+ NtscDecodeLine (lineWidth * _signalsPerPixel, rowSignal, outputBuffer, (startCycle + 6 ) % 12 );
221243
222244 outputBuffer += rowPixelGap;
223245 }
0 commit comments