Advertisement
Bisqwit

NES palette functional, works

Mar 31st, 2013
466
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.61 KB | None | 0 0
  1. #include <cmath>
  2. #include <algorithm>
  3.  
  4. // Scaled signal levels (see Level() for comments).
  5. // At 12*8 are the original 8 signal levels.
  6. // The first 12*8 are the same, except multiplied by 1.7
  7. // for increased saturation, and multiplied by sin(phase).
  8. static constexpr unsigned char Levels[] =
  9.     "YYYYYYYY"             "TYgykx\206\206"       "PYq\221x\216\247\247"
  10.     "NYu\231}\227\263\263" "PYq\221x\216\247\247" "TYgykx\206\206"
  11.     "YYYYYYYY"             "^YK9G:,,"             "bYA!:#\013\013"
  12.     "cY=\0305\033\000\000"  "bYA!:#\013\013"       "^YK9G:,,"
  13.     "SYi n}\216\216";
  14. static const double mul = 53.04827*12, add = 88.900051*12;
  15.  
  16. // Determine the momentary signal level on NES PPU
  17. static constexpr unsigned char Level(unsigned pixel, unsigned phase, unsigned mode)
  18. {
  19.     // Voltage levels, relative to synch voltage:
  20.     // Signal lows:   0.350, 0.518, 0.962, 1.550
  21.     // Signal highs:  1.094, 1.506, 1.962, 1.962
  22.  
  23.     // Normalized:    -0.116, 0.00, 0.307, 0.715
  24.     //                0.399, 0.684, 1.000, 1.000
  25.  
  26.     // The "add", "mul" values are chosen in such manner that
  27.     // Levels[] produces the Normalized values divided by 12.
  28.  
  29.     return Levels[
  30.         mode*8
  31.       + ((pixel&0xF)<14 ? (pixel>>4)&3 : 1) // For colors 14..15, level 1 is forced.
  32.       + 4*((pixel&0xF) <= 12 * (((pixel&0xF) + phase)%12 < 6))];
  33. }
  34.  
  35. // Calculate the sum of parameters
  36. constexpr unsigned Sum() { return 0; }
  37. template<typename... T2> constexpr unsigned Sum(unsigned v, T2... values)
  38.     { return v + Sum(values...); }
  39.  
  40. // This gets the NTSC signal total (Y, I or Q) for given pixel color,
  41. // by summing the momentary signal values at given phases together.
  42. template<typename... T2>
  43. static constexpr unsigned GetC(unsigned mode, unsigned pixel, T2... phase)
  44. {
  45.     return Sum( Level(pixel, phase, mode<12 ? (mode+phase)%12 : mode)... );
  46. }
  47.  
  48. // YIQ components for each NES color:
  49. static constexpr unsigned Y(unsigned p) { return GetC(12, p, 0,1,2,3,4,5,6,7,8,9,10,11); }
  50. static constexpr unsigned I(unsigned p) { return GetC(0,  p, 0,1,2,3,4,5,6,7,8,9,10,11); }
  51. static constexpr unsigned Q(unsigned p) { return GetC(3,  p, 0,1,2,3,4,5,6,7,8,9,10,11); }
  52.  
  53. // YIQ to RGB matrix coefficients:
  54. static constexpr double RY = 1, RI =  0.946882, RQ =  0.623557;
  55. static constexpr double GY = 1, GI = -0.274788, GQ = -0.635691;
  56. static constexpr double BY = 1, BI = -1.108545, BQ =  1.709007;
  57.  
  58. // RGB translations of the YIQ value:
  59. static constexpr double R(unsigned p) { return (RY * Y(p) + RI * I(p) + RQ * Q(p) - add*(RY+RI+RQ)) / mul; }
  60. static constexpr double G(unsigned p) { return (GY * Y(p) + GI * I(p) + GQ * Q(p) - add*(GY+GI+GQ)) / mul; }
  61. static constexpr double B(unsigned p) { return (BY * Y(p) + BI * I(p) + BQ * Q(p) - add*(BY+BI+BQ)) / mul; }
  62.  
  63. // Utility functions for clamping
  64. static constexpr double Clamp01(double a) { return a<0 ? 0 : (a>1 ? 1 : a); }
  65.  
  66. // Get the linear RGB color (not gamma-corrected) for given NES pixel color
  67. constexpr unsigned MakeNEScolor(unsigned pixel)
  68. {
  69.     return 0x010000 * (int)(255 * Clamp01( R(pixel) ))
  70.          + 0x000100 * (int)(255 * Clamp01( G(pixel) ))
  71.          + 0x000001 * (int)(255 * Clamp01( B(pixel) ));
  72. }
  73.  
  74. #include <cstdio>
  75.  
  76. template<int... values>
  77. static void Colors()
  78. {
  79.     static const unsigned colors[sizeof...(values)] = { MakeNEScolor(values) ... };
  80.     for(auto c: colors)
  81.         std::printf("%06X\n", c);
  82. }
  83.  
  84. int main()
  85. {
  86.     Colors<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
  87.            32,33,34,35,36,37,38,38,39,40,41,42,43,44,45,46,47,48,49,
  88.            50,51,52,53,54,55,56,57,58,59,60,61,62,63>();
  89. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement