Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void PutPixel(unsigned px,unsigned py, unsigned pixel, int offset)
- {
- // The input value is a NES color index (with de-emphasis bits).
- // We need RGB values. To produce a RGB value, we emulate the NTSC circuitry.
- // For most part, this process is described at:
- // http://wiki.nesdev.com/w/index.php/NTSC_video
- // Incidentally, this code is shorter than a table of 64*8 RGB values.
- static unsigned palette[3][64][512], prev=~0u;
- if(prev==~0u)
- for(int o=0; o<3; ++o)
- for(int b=0; b<512; ++b)
- for(int q=b&~63, a=q; a < q+64; ++a)
- {
- // Calculate the luma and chroma by emulating the relevant circuits:
- auto s = "\372\273\32\305\35\311I\330D\357}\13D!}N";
- int y=0, i=0, q=0;
- for(int p=0; p<12; ++p) // 12 samples of NTSC signal constitute a color.
- {
- // Sample either the previous or the current pixel.
- int pixel = (p/4+1+o)%3 < 2 ? b : a; // Use pixel=b to disable running pixels.
- // Decode the color index.
- int c = pixel%16, l = c<0xE ? pixel/4 & 12 : 4, e=pixel/64;
- // NES NTSC modulator (square wave between up to four voltage levels):
- int b = 40 + s[(c > 12*((c+8+p)%12 < 6)) + 2*!(0451326 >> p/2*3 & e) + l];
- // Ideal TV NTSC demodulator (assuming no color bleeding):
- y += b;
- i += b * int(std::cos(M_PI * p / 6) * 5909);
- q += b * int(std::sin(M_PI * p / 6) * 5909);
- }
- // Convert the YIQ color into RGB
- auto gammafix = [=](float f) { return f <= 0.f ? 0.f : std::pow(f, 2.2f / 1.8f); };
- auto clamp = [](int v) { return v>255 ? 255 : v; };
- palette[o][a%64][b] =
- + 0x10000*clamp(255 * gammafix(y/1980.f + i* 0.947f/9e6f + q* 0.624f/9e6f))
- + 0x00100*clamp(255 * gammafix(y/1980.f + i*-0.275f/9e6f + q*-0.636f/9e6f))
- + 0x00001*clamp(255 * gammafix(y/1980.f + i*-1.109f/9e6f + q* 1.709f/9e6f));
- }
- // Store the RGB color into the frame buffer with subpixel RGB rendering.
- /**********
- * Three possible ways the pixels can be mixed:
- * prev current next
- * --------________--------
- * 0123456789ab0123456789ab <-p (p<4 || p>=8 ? current : prev) = palette[0][prev][current]
- * 89ab0123456789ab01234567 <-p (p>=4 ? current : prev) = palette[1][prev][current]
- * 456789ab0123456789ab0123 <-p (p<8 ? current : prev) = palette[2][prev][current]
- */
- ((u32*) s->pixels) [py*256+px] = palette[offset][prev%64][pixel];
- prev = pixel;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement