OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
StdColors.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // color calculation routines
17 
18 #ifndef INC_StdColors
19 #define INC_StdColors
20 
21 #include <math.h>
22 
23 // helper function
24 inline uint32_t RGBA(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
25 {
26  return ((a & 255) << 24) | ((r & 255) << 16) | ((g & 255) << 8) | (b & 255);
27 }
28 #define C4RGB(r, g, b) (((DWORD)(0xff)<<24)|(((DWORD)(r)&0xff)<<16)|(((DWORD)(g)&0xff)<<8)|((b)&0xff))
29 #define GetBlueValue(rgb) ((unsigned char)(rgb))
30 #define GetGreenValue(rgb) ((unsigned char)(((unsigned short)(rgb)) >> 8))
31 #define GetRedValue(rgb) ((unsigned char)((rgb)>>16))
32 
33 inline void BltAlpha(DWORD &dwDst, DWORD dwSrc)
34 {
35  // blit one color value w/alpha on another
36  if (dwDst>>24 == 0x00) { dwDst=dwSrc; return; }
37  BYTE byAlphaSrc=BYTE(dwSrc>>24); BYTE byAlphaDst=255-byAlphaSrc;
38  dwDst = std::min<uint32_t>(((dwDst & 0xff ) * byAlphaDst + (dwSrc & 0xff ) * byAlphaSrc) >>8, 0xff) | // blue
39  std::min<uint32_t>(((dwDst & 0xff00) * byAlphaDst + (dwSrc & 0xff00 ) * byAlphaSrc) >>8 & 0xff00, 0xff00) | // green
40  std::min<uint32_t>(((dwDst & 0xff0000) * byAlphaDst + (dwSrc & 0xff0000) * byAlphaSrc) >>8 & 0xff0000, 0xff0000) | // red
41  std::min<uint32_t>( (dwDst >> 24) + byAlphaSrc, 255) << 24; // alpha
42 }
43 
44 inline void BltAlphaAdd(DWORD &dwDst, DWORD dwSrc)
45 {
46  // blit one color value w/alpha on another in additive mode
47  if (dwDst>>24 == 0x00) { dwDst=dwSrc; return; }
48  BYTE byAlphaSrc=BYTE(dwSrc>>24);
49  dwDst = std::min<uint32_t>((dwDst & 0xff ) + ((int(dwSrc & 0xff ) * byAlphaSrc) >>8) , 0xff) | // blue
50  std::min<uint32_t>(((dwDst & 0xff00) + (int(dwSrc>>8 & 0xff ) * byAlphaSrc)) & 0x00ffff00, 0xff00) | // green
51  std::min<uint32_t>(((dwDst & 0xff0000) + (int(dwSrc>>8 & 0xff00) * byAlphaSrc)) & 0xffff0000, 0xff0000) | // red
52  std::min<uint32_t>( (dwDst >> 24) + byAlphaSrc, 255) << 24; // alpha
53 }
54 
55 inline void ModulateClr(DWORD &dwDst, DWORD dwMod) // modulate two color values
56 {
57  // modulate two color values
58  // get alpha
59  int iA1=dwDst>>24, iA2=dwMod>>24;
60  // modulate color values; mod alpha upwards
61  dwDst = ((dwDst & 0xff) * (dwMod & 0xff) / 0xff) | // blue
62  ((dwDst>> 8 & 0xff) * (dwMod>> 8 & 0xff) / 0xff) << 8 | // green
63  ((dwDst>>16 & 0xff) * (dwMod>>16 & 0xff) / 0xff) << 16| // red
64  std::min(iA1*iA2/0xff, 255) << 24; // alpha (TODO: We don't need std::min() here, do we?)
65 }
66 
67 inline void ModulateClrA(DWORD &dwDst, DWORD dwMod) // modulate two color values and add alpha value
68 {
69  // modulate two color values and add alpha value
70  dwDst = ((dwDst & 0xff) * (dwMod & 0xff) / 0xff) | // B
71  ((dwDst>> 8 & 0xff) * (dwMod>> 8 & 0xff) / 0xff) << 8 | // G
72  ((dwDst>>16 & 0xff) * (dwMod>>16 & 0xff) / 0xff) << 16| // R
73  (std::max<uint32_t>((dwDst>>24)+(dwMod>>24), 0xff) - 0xff)<<24;
74 }
75 inline void ModulateClrMOD2(DWORD &dwDst, DWORD dwMod) // clr1+clr2-0.5
76 {
77  // signed color addition
78  dwDst = (Clamp<int>(((int)(dwDst&0xff)+(dwMod&0xff)-0x7f)<<1,0,0xff)&0xff) | // B
79  (Clamp<int>(((int)(dwDst&0xff00)+(dwMod&0xff00)-0x7f00)<<1,0,0xff00)&0xff00) | // G
80  (Clamp<int>(((int)(dwDst&0xff0000)+(dwMod&0xff0000)-0x7f0000)<<1,0,0xff0000)&0xff0000) | // R
81  (std::max<uint32_t>((dwDst>>24)+(dwMod>>24), 0xff) - 0xff)<<24;
82 }
83 
84 inline DWORD LightenClrBy(DWORD &dwDst, int iBy) // enlight a color
85 {
86  // enlight a color
87  // quite a desaturating method...
88  dwDst = std::min<int>((dwDst & 0xff) + iBy, 255) | // blue
89  std::min<int>((dwDst>> 8 & 0xff) + iBy, 255) << 8 | // green
90  std::min<int>((dwDst>>16 & 0xff) + iBy, 255) << 16 | // red
91  (dwDst & 0xff000000); // alpha
92  return dwDst;
93 }
94 
95 inline DWORD DarkenClrBy(DWORD &dwDst, int iBy) // darken a color
96 {
97  // darken a color
98  // quite a desaturating method...
99  dwDst = std::max<int>(int(dwDst & 0xff) - iBy, 0) | // blue
100  std::max<int>(int(dwDst>> 8 & 0xff) - iBy, 0) << 8 | // green
101  std::max<int>(int(dwDst>>16 & 0xff) - iBy, 0) << 16 | // red
102  (dwDst & 0xff000000); // alpha
103  return dwDst;
104 }
105 
106 inline DWORD PlrClr2TxtClr(DWORD dwClr)
107 {
108  // convert player color to text color, lightening up when necessary
109  int lgt=std::max(std::max(GetRedValue(dwClr), GetGreenValue(dwClr)), GetBlueValue(dwClr));
110  if (lgt<0x8f) LightenClrBy(dwClr, 0x8f-lgt);
111  return dwClr|0xff000000;
112 }
113 
114 inline DWORD GetClrModulation(DWORD dwSrcClr, DWORD dwDstClr, DWORD &dwBack)
115 {
116  // get modulation that is necessary to transform dwSrcClr to dwDstClr
117  // does not support alpha values in dwSrcClr and dwDstClr
118  // get source color
119  BYTE sB=BYTE(dwSrcClr); dwSrcClr=dwSrcClr>>8;
120  BYTE sG=BYTE(dwSrcClr); dwSrcClr=dwSrcClr>>8;
121  BYTE sR=BYTE(dwSrcClr); dwSrcClr=dwSrcClr>>8;
122  // get dest color
123  BYTE dB=BYTE(dwDstClr); dwDstClr=dwDstClr>>8;
124  BYTE dG=BYTE(dwDstClr); dwDstClr=dwDstClr>>8;
125  BYTE dR=BYTE(dwDstClr); dwDstClr=dwDstClr>>8;
126  // get difference
127  int cR=(int) dR-sR;
128  int cG=(int) dG-sG;
129  int cB=(int) dB-sB;
130  // get max enlightment
131  int diffN=0;
132  if (cR>0) diffN=cR;
133  if (cG>0) diffN=std::max(diffN, cG);
134  if (cB>0) diffN=std::max(diffN, cB);
135  // is dest > src?
136  if (diffN)
137  {
138  // so a back mask must be used
139  int bR=sR+(cR*255)/diffN;
140  int bG=sG+(cG*255)/diffN;
141  int bB=sB+(cB*255)/diffN;
142  dwBack=RGBA(bR, bG, bB, 255);
143  }
144  if (!sR) sR=1; if (!sG) sG=1; if (!sB) sB=1;
145  return RGBA(std::min((int)dR*256/sR, 255), std::min((int)dG*256/sG, 255), std::min((int)dB*256/sB, 255), 255-diffN);
146 }
147 
148 inline bool rgb2xyY(double r, double g, double b, double *px, double *py, double *pY) // linear rgb to CIE xyY
149 {
150  double X = 0.412453*r + 0.357580*g + 0.180423*b;
151  double Y = 0.212671*r + 0.715160*g + 0.072169*b;
152  double Z = 0.019334*r + 0.119193*g + 0.950227*b;
153  double XYZ=X+Y+Z;
154  if (!XYZ)
155  {
156  *px=*py=0.3; // assume grey cromaticity for black
157  }
158  else
159  {
160  *px = X/XYZ; *py = Y/XYZ;
161  }
162  *pY = Y;
163  return true;
164 }
165 
166 inline bool xy2upvp(double x, double y, double *pu, double *pv) // CIE xy to u'v'
167 {
168  double n = -2.0*x+12.0*y+3.0;
169  if (!n) return false;
170  *pu = 4.0*x / n;
171  *pv = 9.0*y / n;
172  return true;
173 }
174 
175 inline bool RGB2rgb(int R, int G, int B, double *pr, double *pg, double *pb, double gamma=2.2) // monitor RGB (0 to 255) to linear rgb (0.0 to 1.0) assuming default gamma 2.2
176 {
177  *pr = pow((double) R / 255.0, 1.0/gamma);
178  *pg = pow((double) G / 255.0, 1.0/gamma);
179  *pb = pow((double) B / 255.0, 1.0/gamma);
180  return true;
181 }
182 
183 // a standard pal
185 {
186  DWORD Colors[256];
187 
189  { return Colors[byCol]; }
190 };
191 
192 #endif
DWORD GetClrModulation(DWORD dwSrcClr, DWORD dwDstClr, DWORD &dwBack)
Definition: StdColors.h:114
#define GetGreenValue(rgb)
Definition: StdColors.h:30
#define b
DWORD Colors[256]
Definition: StdColors.h:186
DWORD DarkenClrBy(DWORD &dwDst, int iBy)
Definition: StdColors.h:95
uint8_t BYTE
void ModulateClr(DWORD &dwDst, DWORD dwMod)
Definition: StdColors.h:55
#define a
#define GetRedValue(rgb)
Definition: StdColors.h:31
void ModulateClrMOD2(DWORD &dwDst, DWORD dwMod)
Definition: StdColors.h:75
DWORD GetClr(BYTE byCol)
Definition: StdColors.h:188
#define GetBlueValue(rgb)
Definition: StdColors.h:29
bool xy2upvp(double x, double y, double *pu, double *pv)
Definition: StdColors.h:166
DWORD LightenClrBy(DWORD &dwDst, int iBy)
Definition: StdColors.h:84
void BltAlpha(DWORD &dwDst, DWORD dwSrc)
Definition: StdColors.h:33
bool rgb2xyY(double r, double g, double b, double *px, double *py, double *pY)
Definition: StdColors.h:148
void BltAlphaAdd(DWORD &dwDst, DWORD dwSrc)
Definition: StdColors.h:44
#define X(sdl, oc)
uint32_t RGBA(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
Definition: StdColors.h:24
uint32_t DWORD
DWORD PlrClr2TxtClr(DWORD dwClr)
Definition: StdColors.h:106
bool RGB2rgb(int R, int G, int B, double *pr, double *pg, double *pb, double gamma=2.2)
Definition: StdColors.h:175
void ModulateClrA(DWORD &dwDst, DWORD dwMod)
Definition: StdColors.h:67