1 /*
2  * See Licensing and Copyright notice in naev.h
3  */
4 
5 /**
6  * @file colour.c
7  *
8  * @brief Predefined colours for use with Naev.
9  */
10 
11 
12 #include "colour.h"
13 
14 #include <math.h>
15 #include "nstring.h"
16 
17 #include "nmath.h"
18 #include "naev.h"
19 #include "log.h"
20 #include "ncompat.h"
21 #include "nstd.h"
22 
23 
24 /*
25  * default colours
26  */
27 /* grey */
28 const glColour cWhite      = { .r=1.00, .g=1.00, .b=1.00, .a=1. }; /**< White */
29 const glColour cGrey90     = { .r=0.90, .g=0.90, .b=0.90, .a=1. }; /**< Grey 90% */
30 const glColour cGrey80     = { .r=0.80, .g=0.80, .b=0.80, .a=1. }; /**< Grey 80% */
31 const glColour cGrey70     = { .r=0.70, .g=0.70, .b=0.70, .a=1. }; /**< Grey 70% */
32 const glColour cGrey60     = { .r=0.60, .g=0.60, .b=0.60, .a=1. }; /**< Grey 60% */
33 const glColour cGrey50     = { .r=0.50, .g=0.50, .b=0.50, .a=1. }; /**< Grey 50% */
34 const glColour cGrey40     = { .r=0.40, .g=0.40, .b=0.40, .a=1. }; /**< Grey 40% */
35 const glColour cGrey30     = { .r=0.30, .g=0.30, .b=0.30, .a=1. }; /**< Grey 30% */
36 const glColour cGrey20     = { .r=0.20, .g=0.20, .b=0.20, .a=1. }; /**< Grey 20% */
37 const glColour cGrey10     = { .r=0.10, .g=0.10, .b=0.10, .a=1. }; /**< Grey 10% */
38 const glColour cBlack      = { .r=0.00, .g=0.00, .b=0.00, .a=1. }; /**< Black */
39 
40 /* Greens. */
41 const glColour cGreen      = { .r=0.20, .g=0.80, .b=0.20, .a=1. }; /**< Green */
42 const glColour cPrimeGreen = { .r=0.00, .g=1.00, .b=0.00, .a=1. }; /**< Primary Green */
43 /* Reds. */
44 const glColour cDarkRed    = { .r=0.60, .g=0.10, .b=0.10, .a=1. }; /**< Dark Red */
45 const glColour cRed        = { .r=0.80, .g=0.20, .b=0.20, .a=1. }; /**< Red */
46 const glColour cPrimeRed   = { .r=1.00, .g=0.00, .b=0.00, .a=1. }; /**< Primary Red */
47 /* Oranges. */
48 const glColour cOrange     = { .r=0.90, .g=0.70, .b=0.10, .a=1. }; /**< Orange */
49 /* Yellows. */
50 const glColour cGold       = { .r=1.00, .g=0.84, .b=0.00, .a=1. }; /**< Gold */
51 const glColour cYellow     = { .r=0.80, .g=0.80, .b=0.00, .a=1. }; /**< Yellow */
52 /* Blues. */
53 const glColour cMidnightBlue = { .r=0.40, .g=0.4, .b=0.60, .a=1. }; /**< Midnight Blue. */
54 const glColour cDarkBlue   = { .r=0.10, .g=0.10, .b=0.60, .a=1. }; /**< Dark Blue */
55 const glColour cBlue       = { .r=0.20, .g=0.20, .b=0.80, .a=1. }; /**< Blue */
56 const glColour cLightBlue  = { .r=0.40, .g=0.40, .b=1.00, .a=1. }; /**< Light Blue */
57 const glColour cPrimeBlue  = { .r=0.00, .g=0.00, .b=1.00, .a=1. }; /**< Primary Blue */
58 const glColour cCyan       = { .r=0.00, .g=1.00, .b=1.00, .a=1. }; /* Cyan. */
59 /* Purples. */
60 const glColour cPurple     = { .r=0.90, .g=0.10, .b=0.90, .a=1. }; /**< Purple */
61 const glColour cDarkPurple = { .r=0.68, .g=0.18, .b=0.64, .a=1. }; /**< Dark Purple */
62 /* Browns. */
63 const glColour cBrown      = { .r=0.59, .g=0.28, .b=0.00, .a=1. }; /**< Brown */
64 /* Misc. */
65 const glColour cSilver     = { .r=0.75, .g=0.75, .b=0.75, .a=1. }; /**< Silver */
66 const glColour cAqua       = { .r=0.00, .g=0.75, .b=1.00, .a=1. }; /**< Aqua */
67 
68 
69 /*
70  * game specific
71  */
72 const glColour cBlackHilight  =  { .r = 0.0, .g = 0.0, .b = 0.0, .a = 0.4 }; /**< Hilight colour over black background. */
73 const glColour cConsole       =  { .r = 0.1, .g = 0.9, .b = 0.1, .a = 1.  }; /**< Console colour */
74 const glColour cDConsole      =  { .r = 0.0, .g = 0.7, .b = 0.0, .a = 1.  }; /**< Dark Console colour */
75 /* toolkit */
76 const glColour cHilight       =  { .r = 0.1, .g = 0.9, .b = 0.1, .a = 0.3 }; /**< Hilight colour */
77 /* objects */
78 const glColour cInert         =  { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1.  }; /**< Inert object colour */
79 const glColour cNeutral       =  { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1.  }; /**< Neutral object colour */
80 const glColour cMapNeutral    =  { .r = 0.3, .g = 0.3, .b = 0.3, .a = 1.  }; /**< Neutral object map screen text colour */
81 const glColour cFriend        =  { .r = 0.0, .g = 0.8, .b = 0.0, .a = 1.  }; /**< Friend object colour */
82 const glColour cHostile       =  { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1.  }; /**< Hostile object colour */
83 const glColour cRestricted    =  { .r = 1.0, .g = 0.6, .b = 0.0, .a = 1.  }; /**< Restricted object colour. */
84 const glColour cDRestricted   =  { .r = 0.7, .g = 0.3, .b = 0.0, .a = 1.  }; /**< Restricted object colour. Darkened for use on white. */
85 /* radar */
86 const glColour cRadar_player  =  { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1.  }; /**< Player colour on radar. */
87 const glColour cRadar_tPilot  =  { .r = 0.8, .g = 0.5, .b = 0.0, .a = 1.  }; /**< Targeted object colour on radar. */
88 const glColour cRadar_tPlanet =  { .r = 0.7, .g = 0.0, .b = 0.9, .a = 1.  }; /**< Targeted planet colour. */
89 const glColour cRadar_weap    =  { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1.  }; /**< Weapon colour on radar. */
90 const glColour cRadar_hilight =  { .r = 0.0, .g = 0.8, .b = 0.8, .a = 1.  }; /**< Radar hilighted object. */
91 /* health */
92 const glColour cShield        =  { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1.  }; /**< Shield bar colour. */
93 const glColour cArmour        =  { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1.  }; /**< Armour bar colour. */
94 const glColour cEnergy        =  { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1.  }; /**< Energy bar colour. */
95 const glColour cFuel          =  { .r = 0.9, .g = 0.1, .b = 0.4, .a = 1.  }; /**< Fuel bar colour. */
96 
97 /* Deiz's Super Font Palette */
98 
99 const glColour cFontRed       =  { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1.  }; /**< Red font colour. */
100 const glColour cFontGreen     =  { .r = 0.4, .g = 0.8, .b = 0.2, .a = 1.  }; /**< Green font colour. */
101 const glColour cFontBlue      =  { .r = 0.2, .g = 0.4, .b = 0.8, .a = 1.  }; /**< Blue font colour. */
102 const glColour cFontYellow    =  { .r = 0.9, .g = 0.8, .b = 0.0, .a = 1.  }; /**< Yellow font colour. */
103 const glColour cFontWhite     =  { .r = 0.8, .g = 0.8, .b = 0.8, .a = 1.  }; /**< White font colour. */
104 const glColour cFontPurple    =  { .r = 0.7, .g = 0.3, .b = 0.7, .a = 1.  }; /**< Purple font colour. */
105 const glColour cFontFriendly  =  { .r = 0.3, .g = 0.9, .b = 0.3, .a = 1.  }; /**< Friendly font colour. */
106 const glColour cFontHostile   =  { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1.  }; /**< Hostile font colour. */
107 const glColour cFontNeutral   =  { .r = 1.0, .g = 0.9, .b = 0.0, .a = 1.  }; /**< Neutral font colour. */
108 
109 
110 /**
111  * @brief Changes colour space from HSV to RGB.
112  *
113  * All values go from 0 to 1, except H which is 0-360.
114  *
115  *    @param[out] r Stores R.
116  *    @param[out] g Stores G.
117  *    @param[out] b Stores B.
118  *    @param h Hue to convert.
119  *    @param s Saturation to convert.
120  *    @param v Value to convert.
121  */
col_hsv2rgb(double * r,double * g,double * b,double h,double s,double v)122 void col_hsv2rgb( double *r, double *g, double *b, double h, double s, double v )
123 {
124    double var_h, var_i, var_1, var_2, var_3;
125 
126    if (v > 1)
127       v = 1;
128 
129    if (s == 0) {
130       *r = v;
131       *g = v;
132       *b = v;
133    }
134    else {
135       var_h = h * 6 / 360.;
136       var_i = floor(var_h);
137       var_1 = v * (1 - s);
138       var_2 = v * (1 - s * (var_h - var_i));
139       var_3 = v * (1 - s * (1 - (var_h - var_i)));
140 
141       if      (var_i == 0) { *r = v     ; *g = var_3 ; *b = var_1; }
142       else if (var_i == 1) { *r = var_2 ; *g = v     ; *b = var_1; }
143       else if (var_i == 2) { *r = var_1 ; *g = v     ; *b = var_3; }
144       else if (var_i == 3) { *r = var_1 ; *g = var_2 ; *b = v;     }
145       else if (var_i == 4) { *r = var_3 ; *g = var_1 ; *b = v;     }
146       else                 { *r = v     ; *g = var_1 ; *b = var_2; }
147    }
148 }
149 
150 
151 /**
152  * @brief Changes colour space from RGB to HSV.
153  *
154  * All values go from 0 to 1, except H which is 0-360.
155  *
156  * Taken from (GIFT) GNU Image Finding Tool.
157  *
158  *    @param[out] H Stores Hue.
159  *    @param[out] S Stores Saturation.
160  *    @param[out] V Stores Value.
161  *    @param R Red to convert.
162  *    @param G Green to convert.
163  *    @param B Blue to convert.
164  */
col_rgb2hsv(double * H,double * S,double * V,double R,double G,double B)165 void col_rgb2hsv( double *H, double *S, double *V, double R, double G, double B )
166 {
167    double H1, S1, V1;
168 #ifdef HSV_TRAVIS
169    double R1, G1, B1;
170 #endif /* HSV_TRAVIS */
171    double max, min, diff;
172 
173    max = max3( R, G, B );
174    min = min3( R, G, B );
175    diff = max - min;
176 
177    if (max == 0)
178       H1 = S1 = V1 = 0;
179    else {
180       V1 = max;
181       S1 = diff/max;
182       if (S1 == 0)
183          /* H1 is undefined, but give it a value anyway */
184          H1 = 0;
185       else {
186 #ifdef HSV_TRAVIS
187          R1 = (max - R)/diff;
188          G1 = (max - G)/diff;
189          B1 = (max - B)/diff;
190 
191          if ((R == max) && (G == min))
192             H1 = 5 + B1;
193          else {
194             if ((R == max) && (G != min))
195                H1 = 1 - G1;
196             else {
197                if ((G == max) && (B == min))
198                   H1 = 1 + R1;
199                else {
200                   if ((G == max) && (B != min))
201                      H1 = 3 - B1;
202                   else {
203                      if (R == max)
204                         H1 = 3 + G1;
205                      else
206                         H1 = 5 - R1;
207                   }
208                }
209             }
210          }
211 
212          H1 *= 60; /* convert to range [0, 360] degrees */
213 #else /* HSV_TRAVIS */
214          H1 = 0.; /* Shuts up Clang. */
215          /* assume Foley & VanDam HSV */
216          if (R == max)
217             H1 = (G - B)/diff;
218          if (G == max)
219             H1 = 2 + (B - R)/diff;
220          if (B == max)
221             H1 = 4 + (R - G)/diff;
222 
223          H1 *= 60; /* convert to range [0, 360] degrees */
224          if (H1 < 0)
225             H1 += 360;
226 #endif /* HSV_TRAVIS */
227       }
228    }
229    *H = H1;
230    *S = S1;
231    *V = V1;
232 }
233 
234 
235 /**
236  * @brief Blends two colours.
237  *
238  *    @param[out] blend Stores blended output colour.
239  *    @param fg Foreground colour.
240  *    @param bg Background colour.
241  *    @param alpha Alpha value to use (0 to 1).
242  */
col_blend(glColour * blend,const glColour * fg,const glColour * bg,double alpha)243 void col_blend( glColour *blend, const glColour *fg, const glColour *bg, double alpha )
244 {
245    blend->r = (1. - alpha) * bg->r + alpha * fg->r;
246    blend->g = (1. - alpha) * bg->g + alpha * fg->g;
247    blend->b = (1. - alpha) * bg->b + alpha * fg->b;
248    blend->a = (1. - alpha) * bg->a + alpha * fg->a;
249 }
250 
251 
252 #define CHECK_COLOUR(colour) \
253       if (STRCASECMP(name, #colour) == 0) return &c##colour /**< Checks the colour. */
254 /**
255  * @brief Returns a colour from its name
256  *
257  *    @param name Colour's name
258  *    @return the colour
259  */
col_fromName(const char * name)260 const glColour* col_fromName( const char* name )
261 {
262    if (name[0] == 'a' || name[0] == 'A') {
263       CHECK_COLOUR(Aqua);
264    }
265 
266    if (name[0] == 'b' || name[0] == 'B') {
267       CHECK_COLOUR(Blue);
268       CHECK_COLOUR(Black);
269       CHECK_COLOUR(Brown);
270    }
271 
272    if (name[0] == 'c' || name[0] == 'C') {
273       CHECK_COLOUR(Cyan);
274    }
275 
276    if (name[0] == 'd' || name[0] == 'D') {
277       CHECK_COLOUR(DarkRed);
278       CHECK_COLOUR(DarkBlue);
279       CHECK_COLOUR(DarkPurple);
280    }
281 
282    if (name[0] == 'g' || name[0] == 'G') {
283       CHECK_COLOUR(Gold);
284       CHECK_COLOUR(Green);
285       CHECK_COLOUR(Grey90);
286       CHECK_COLOUR(Grey80);
287       CHECK_COLOUR(Grey70);
288       CHECK_COLOUR(Grey60);
289       CHECK_COLOUR(Grey50);
290       CHECK_COLOUR(Grey40);
291       CHECK_COLOUR(Grey30);
292       CHECK_COLOUR(Grey20);
293       CHECK_COLOUR(Grey10);
294    }
295 
296    if (name[0] == 'l' || name[0] == 'L') {
297       CHECK_COLOUR(LightBlue);
298    }
299 
300    if (name[0] == 'o' || name[0] == 'O') {
301       CHECK_COLOUR(Orange);
302    }
303 
304    if (name[0] == 'p' || name[0] == 'P') {
305       CHECK_COLOUR(Purple);
306    }
307 
308    if (name[0] == 'r' || name[0] == 'R') {
309       CHECK_COLOUR(Red);
310    }
311 
312    if (name[0] == 's' || name[0] == 'S') {
313       CHECK_COLOUR(Silver);
314    }
315 
316    if (name[0] == 'w' || name[0] == 'W') {
317       CHECK_COLOUR(White);
318    }
319 
320    if (name[0] == 'y' || name[0] == 'Y') {
321       CHECK_COLOUR(Yellow);
322    }
323 
324    if (name[0] == 'm' || name[0] == 'M') {
325       CHECK_COLOUR(MidnightBlue);
326    }
327 
328 
329    WARN("Unknown colour %s", name);
330    return NULL;
331 }
332 #undef CHECK_COLOUR
333 
334