diff --git a/crt_core.c b/crt_core.c index eda68b6..8295b1c 100644 --- a/crt_core.c +++ b/crt_core.c @@ -66,6 +66,9 @@ crt_sincos14(int *s, int *c, int n) /* convolution is much faster but the EQ looks softer, more authentic, and more analog */ #define USE_CONVOLUTION 0 +#define USE_7_SAMPLE_KERNEL 0 +#define USE_6_SAMPLE_KERNEL 0 +#define USE_5_SAMPLE_KERNEL 1 #if USE_CONVOLUTION @@ -101,9 +104,23 @@ eqf(struct EQF *f, int s) h[i] = h[i - 1]; } h[0] = s; +#if USE_7_SAMPLE + /* index : 0 1 2 3 4 5 6 */ + /* weight: 1 4 7 8 7 4 1 */ + return (s + h[6] + ((h[1] + h[5]) * 4) + ((h[2] + h[4]) * 7) + (h[3] * 8)) >> 5; +#elseif USE_6_SAMPLE + /* index : 0 1 2 3 4 5 */ + /* weight: 1 3 4 4 3 1 */ + return (s + h[5] + 3 * (h[1] + h[4]) + 4 * (h[2] + h[3])) >> 4; +#elseif USE_5_SAMPLE /* index : 0 1 2 3 4 */ /* weight: 1 2 2 2 1 */ return (s + h[4] + ((h[1] + h[2] + h[3]) << 1)) >> 3; +#else + /* index : 0 1 2 3 */ + /* weight: 1 1 1 1*/ + return (s + h[3] + h[1] + h[2]) >> 2; +#endif } #else diff --git a/crt_nes.c b/crt_nes.c index 8b90130..fd9c689 100644 --- a/crt_nes.c +++ b/crt_nes.c @@ -17,6 +17,62 @@ #include #include +// Precalculate the low and high signal chosen for each 64 base colors +// with their respective attenuated values +// https://www.nesdev.org/wiki/NTSC_video#Brightness_Levels +const int8_t IRE_levels[2][2][0x40]{ + // waveform low + { + // normal + { + // 0x + 43, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, -12, 0, 0, + // 1x + 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // 2x + 110, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, + // 3x + 110, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0 + }, + // attenuated + { + // 0x + 26 , -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, 0, 0, + // 1x + 51, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, 0, 0, + // 2x + 82, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, + // 3x + 82, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 0, 0 + } + }, + // waveform high + { + // normal + { + // 0x + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, -12, 0, 0, + // 1x + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 0, 0, 0, + // 2x + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 34, 0, 0, + // 3x + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 80, 0, 0 + }, + // attenuated + { + // 0x + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -17, 0, 0, + // 1x + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, -8, 0, 0, + // 2x + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 19, 0, 0, + // 3x + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 56, 0, 0 + } + } +}; + /* generate the square wave for a given 9-bit pixel and phase */ static int square_sample(int p, int phase) @@ -26,38 +82,17 @@ square_sample(int p, int phase) 0500, 0400, 0600, 0200 }; - int bri, hue, v; + int hue; + bool e, v; hue = (p & 0x0f); - - /* last two columns are black */ - if (hue >= 0x0e) { - return 0; - } - bri = ((p & 0x30) >> 4) * 300; - - switch (hue) { - case 0: - v = bri + 410; - break; - case 0x0d: - v = bri - 300; - break; - default: - v = (((hue + phase) % 12) < 6) ? (bri + 410) : (bri - 300); - break; - } + v = (((hue + phase) % 12) < 6); - if (v > 1024) { - v = 1024; - } /* red 0100, green 0200, blue 0400 */ - if ((p & 0700) & active[(phase >> 1) % 6]) { - return (v >> 1) + (v >> 2); - } + e = ((p & 0700) & active[(phase >> 1) % 6]); - return v; + return IRE_levels[v][e][p & 0x3F]; } #define NES_OPTIMIZED 0