Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Color.h
Go to the documentation of this file.
1 /* Project nGenEx
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: nGenEx.lib
6  FILE: Color.h
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Universal Color Format class
13 */
14 
15 #ifndef Color_h
16 #define Color_h
17 
18 #include "Types.h"
19 
20 // +--------------------------------------------------------------------+
21 
22 class Video;
23 
24 // +--------------------------------------------------------------------+
25 
27 {
28  ColorFormat(int palsize)
29  : pal(palsize), bpp(8),
30  rdown(0), rshift(0), rmask(0),
31  gdown(0), gshift(0), gmask(0),
32  bdown(0), bshift(0), bmask(0),
33  adown(0), ashift(0), amask(0) { }
34 
35  ColorFormat(int size, BYTE r, BYTE rs, BYTE g, BYTE gs, BYTE b, BYTE bs, BYTE a=0, BYTE as=0)
36  : pal(0), bpp(size),
37  rdown(8-r), rshift(rs), rmask(((1<<r)-1)<<rs),
38  gdown(8-g), gshift(gs), gmask(((1<<g)-1)<<gs),
39  bdown(8-b), bshift(bs), bmask(((1<<b)-1)<<bs),
40  adown(8-a), ashift(as), amask(((1<<a)-1)<<as) { }
41 
42  int pal;
43  int bpp;
44  BYTE rdown, rshift;
45  BYTE gdown, gshift;
46  BYTE bdown, bshift;
47  BYTE adown, ashift;
48 
49  DWORD rmask;
50  DWORD gmask;
51  DWORD bmask;
52  DWORD amask;
53 };
54 
55 // +--------------------------------------------------------------------+
56 
57 class Color
58 {
59  friend class ColorIndex;
60  friend class ColorValue;
61 
62 public:
63  static const char* TYPENAME() { return "Color"; }
64 
65  enum Misc { SHADE_LEVELS = 64 }; // max 128!
66  enum Mask { RMask = 0x00ff0000,
67  GMask = 0x0000ff00,
68  BMask = 0x000000ff,
69  AMask = 0xff000000,
70  RGBMask = 0x00ffffff };
71  enum Shift { RShift = 16,
72  GShift = 8,
73  BShift = 0,
74  AShift = 24 };
75 
76  Color() : rgba(0) { }
77  Color(const Color& c) : rgba(c.rgba) { }
78  Color(BYTE r, BYTE g, BYTE b, BYTE a=255) {
79  rgba = (r<<RShift)|(g<<GShift)|(b<<BShift)|(a<<AShift); }
80 
81  Color(BYTE index);
82 
83  Color& operator= (const Color& c) { rgba = c.rgba; return *this; }
84  int operator==(const Color& c) const { return rgba == c.rgba; }
85  int operator!=(const Color& c) const { return rgba != c.rgba; }
86  Color& operator+=(const Color& c); // simple summation
87 
88  Color operator+(DWORD d) const;
89 
90  Color operator+(const Color& c) const; // color alpha blending
91  Color operator*(const Color& c) const; // color modulation
92  Color operator*(double scale) const;
93  Color dim(double scale) const;
94 
95  void Set(DWORD value) { rgba = value; }
96  void Set(BYTE r, BYTE g, BYTE b, BYTE a=255) {
97  rgba = (r<<RShift)|(g<<GShift)|(b<<BShift)|(a<<AShift); }
98 
99  DWORD Value() const { return rgba; }
100 
101  void SetRed(BYTE r) { rgba = (rgba & ~RMask) | (r << RShift); }
102  void SetGreen(BYTE g) { rgba = (rgba & ~GMask) | (g << GShift); }
103  void SetBlue(BYTE b) { rgba = (rgba & ~BMask) | (b << BShift); }
104  void SetAlpha(BYTE a) { rgba = (rgba & ~AMask) | (a << AShift); }
105 
106  DWORD Red() const { return (rgba & RMask) >> RShift; }
107  DWORD Green() const { return (rgba & GMask) >> GShift; }
108  DWORD Blue() const { return (rgba & BMask) >> BShift; }
109  DWORD Alpha() const { return (rgba & AMask) >> AShift; }
110 
111  float fRed() const { return (float)(Red() /255.0); }
112  float fGreen() const { return (float)(Green()/255.0); }
113  float fBlue() const { return (float)(Blue() /255.0); }
114  float fAlpha() const { return (float)(Alpha()/255.0); }
115 
116  BYTE Index() const { return table[((rgba&RMask)>>(RShift+3)<<10)|
117  ((rgba&GMask)>>(GShift+3)<< 5)|
118  ((rgba&BMask)>>(BShift+3))]; }
119 
120  inline BYTE IndexedBlend(BYTE dst) const;
121  static DWORD FormattedBlend(DWORD c1, DWORD c2);
122 
123  DWORD TextureFormat(int keep_alpha=0) const;
124  DWORD Formatted() const;
125  DWORD Unfaded() const;
126  Color ShadeColor(int shade) const;
127  DWORD Shaded(int shade) const;
128  Color Faded() const;
129 
130  // some useful colors
131  static Color White;
132  static Color Black;
133  static Color Gray;
134  static Color LightGray;
135  static Color DarkGray;
136  static Color BrightRed;
139  static Color DarkRed;
140  static Color DarkBlue;
141  static Color DarkGreen;
142  static Color Yellow;
143  static Color Cyan;
144  static Color Magenta;
145  static Color Tan;
146  static Color Brown;
147  static Color Violet;
148  static Color Orange;
149 
150  static void UseVideo(Video* v);
151  static void UseFormat(const ColorFormat& cf);
152  static void UseTextureFormat(const ColorFormat& cf, int alpha_level=0);
153  static void WithTextureFormat(int alpha_level=0);
154  static void SetPalette(PALETTEENTRY* pal, int palsize, BYTE* invpal=0);
155  static void SavePalette(const char* basename);
156  static void SetFade(double f, Color c=Black, int build_shade=false);
157 
158  static const ColorFormat& GetTextureFormat(int alpha_level=0) { return texture_format[alpha_level]; }
159  static const ColorFormat& GetScreenFormat() { return format; }
160 
161  // indexed color initialization:
162  static void BuildShadeTable();
163  static void SaveShadeTable(const char* basename);
164  static void BuildBlendTable();
165 
166  static double GetFade() { return fade; }
167  static Color GetFadeColor() { return fade_color; }
168 
169  static Color Scale(const Color& c1, const Color& c2, double scale);
170  static Color Unformat(DWORD formatted_color);
171 
172 private:
173  DWORD rgba;
174 
175  static bool standard_format;
176  static PALETTEENTRY palette[256];
177  static BYTE table[32768];
178  static ColorFormat format;
179  static int texture_alpha_level;
180  static ColorFormat texture_format[4];
181  static double fade;
182  static Color fade_color;
183  static Video* video;
184 };
185 
186 // +--------------------------------------------------------------------+
187 
189 {
190  friend class Color;
191 
192 public:
193  static const char* TYPENAME() { return "ColorValue"; }
194 
195  ColorValue() : r(0), g(0), b(0), a(0) { }
196  ColorValue(const ColorValue& c) : r(c.r), g(c.g), b(c.b), a(c.a) { }
197  ColorValue(const Color& c) : r( c.fRed() ),
198  g( c.fGreen() ),
199  b( c.fBlue() ),
200  a( c.fAlpha() ) { }
201  ColorValue(float ar,
202  float ag,
203  float ab,
204  float aa=1.0f) : r(ar), g(ag), b(ab), a(aa) { }
205 
206  int operator==(const ColorValue& c) const { return r==c.r && g==c.g && b==c.b && a==c.a; }
207  int operator!=(const ColorValue& c) const { return r!=c.r || g!=c.g || b!=c.b || a!=c.a; }
208  ColorValue& operator+=(const ColorValue& c); // simple summation
209 
210  ColorValue operator+(const ColorValue& c) const; // color alpha blending
211  ColorValue operator*(const ColorValue& c) const; // color modulation
212  ColorValue operator*(double scale) const;
213  ColorValue dim(double scale) const;
214 
215  void Set(float ar, float ag, float ab, float aa=1.0f) { r=ar; g=ag; b=ab; a=aa; }
216 
217  void SetRed(float ar) { r=ar; }
218  void SetGreen(float ag) { g=ag; }
219  void SetBlue(float ab) { b=ab; }
220  void SetAlpha(float aa) { a=aa; }
221 
222  float Red() const { return r; }
223  float Green() const { return g; }
224  float Blue() const { return b; }
225  float Alpha() const { return a; }
226 
227  Color ToColor() const;
228  DWORD TextureFormat(int keep_alpha=0) const { return ToColor().TextureFormat(keep_alpha); }
229  DWORD Formatted() const { return ToColor().Formatted(); }
230  DWORD Unfaded() const { return ToColor().Unfaded(); }
231  Color ShadeColor(int shade) const { return ToColor().ShadeColor(shade); }
232  DWORD Shaded(int shade) const { return ToColor().Shaded(shade); }
233  Color Faded() const { return ToColor().Faded(); }
234 
235 private:
236  float r, g, b, a;
237 };
238 
239 // +--------------------------------------------------------------------+
240 
242 {
243  friend class Color;
244 
245 public:
246  static const char* TYPENAME() { return "ColorIndex"; }
247 
248  ColorIndex() : index(0) { }
249  ColorIndex(const ColorIndex& c) : index(c.index) { }
250  ColorIndex(BYTE r, BYTE g, BYTE b) { index = Color(r,g,b).Index(); }
251  ColorIndex(BYTE i) : index(i) { }
252 
253  ColorIndex& operator= (const ColorIndex& c) { index = c.index; return *this; }
254  int operator==(const ColorIndex& c) const { return index == c.index; }
255  int operator!=(const ColorIndex& c) const { return index != c.index; }
256 
257  BYTE Index() const { return index; }
258 
259  DWORD Red() const { return Color::palette[index].peRed; }
260  DWORD Green() const { return Color::palette[index].peGreen; }
261  DWORD Blue() const { return Color::palette[index].peBlue; }
262 
263  float fRed() const { return (float)(Red() /255.0); }
264  float fGreen() const { return (float)(Green()/255.0); }
265  float fBlue() const { return (float)(Blue() /255.0); }
266 
267  DWORD TextureFormat() const { return texture_palette[index]; }
268  DWORD Unfaded() const { return unfaded_palette[index]; }
269  DWORD Formatted() const { return formatted_palette[index]; }
270  DWORD Shaded(int shade) const { return shade_table[shade*256+index]; }
271  ColorIndex Faded() const { return ColorIndex(index); }
272 
273  // note: this will only work in 8-bit color mode...
274  ColorIndex ShadeColor(int s) const { return ColorIndex((BYTE)(shade_table[s*256+index])); }
275 
276  // for poly shading optimization
277  static DWORD* ShadeTable() { return shade_table; }
278 
279  BYTE IndexedBlend(BYTE dst) const { return blend_table[dst*256+index]; }
280 
281 private:
282  BYTE index;
283 
284  static DWORD* texture_palette;
285  static DWORD texture_palettes[4][256];
286  static DWORD unfaded_palette[256];
287  static DWORD formatted_palette[256];
288  static DWORD shade_table[256*256];
289  static BYTE blend_table[256*256];
290 };
291 
292 inline BYTE Color::IndexedBlend(BYTE dst) const { return ColorIndex::blend_table[dst*256+Index()]; }
293 
294 #endif Color_h
295