Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
color.qh
Go to the documentation of this file.
1#pragma once
2
3#include "string.qh"
4
5#define colormapPaletteColor(c, isPants) colormapPaletteColor_(c, isPants, time)
7vector colormapPaletteColor_(int c, bool isPants, float t)
8{
9 // these colors are defined in gfx/colormap_palette.pl
10 // to generate them run: perl gfx/colormap_palette.pl > gfx/colormap_palette.lmp
11 // it will save them to gfx/colormap_palette.lmp (in the lmp format)
12 // and prints the cases of the following switch so they can be copy-pasted here
13
14 switch (c)
15 {
16 // generated by gfx/colormap_palette.pl
17 case 0: return '1.000000 1.000000 1.000000';
18 case 1: return '1.000000 0.333333 0.000000';
19 case 2: return '0.000000 1.000000 0.501961';
20 case 3: return '0.000000 1.000000 0.000000';
21 case 4: return '1.000000 0.000000 0.000000';
22 case 5: return '0.000000 0.666667 1.000000';
23 case 6: return '0.000000 1.000000 1.000000';
24 case 7: return '0.501961 1.000000 0.000000';
25 case 8: return '0.501961 0.000000 1.000000';
26 case 9: return '1.000000 0.000000 1.000000';
27 case 10: return '1.000000 0.000000 0.501961';
28 case 11: return '0.000000 0.000000 1.000000';
29 case 12: return '1.000000 1.000000 0.000000';
30 case 13: return '0.000000 0.333333 1.000000';
31 case 14: return '1.000000 0.666667 0.000000';
32 case 15:
33 if (isPants)
34 return '1 0 0' * (0.502 + 0.498 * sin(t / M_E + 0))
35 + '0 1 0' * (0.502 + 0.498 * sin(t / M_E + M_PI * 2 / 3))
36 + '0 0 1' * (0.502 + 0.498 * sin(t / M_E + M_PI * 4 / 3));
37 else
38 return '1 0 0' * (0.502 + 0.498 * sin(t / M_PI + M_PI * 5 / 3))
39 + '0 1 0' * (0.502 + 0.498 * sin(t / M_PI + M_PI))
40 + '0 0 1' * (0.502 + 0.498 * sin(t / M_PI + M_PI * 1 / 3));
41 default: return '0.000 0.000 0.000';
42 }
43}
44
46float rgb_mi_ma_to_hue(vector rgb, float mi, float ma)
47{
48 if (mi == ma)
49 return 0;
50 else if (ma == rgb.x)
51 {
52 if (rgb.y >= rgb.z)
53 return (rgb.y - rgb.z) / (ma - mi);
54 else
55 return (rgb.y - rgb.z) / (ma - mi) + 6;
56 }
57 else if (ma == rgb.y)
58 return (rgb.z - rgb.x) / (ma - mi) + 2;
59 else //if (ma == rgb_z)
60 return (rgb.x - rgb.y) / (ma - mi) + 4;
61}
62
64vector hue_mi_ma_to_rgb(float hue, float mi, float ma)
65{
66 vector rgb;
67
68 hue -= 6 * floor(hue / 6);
69
70 //else if (ma == rgb_x)
71 // hue = 60 * (rgb_y - rgb_z) / (ma - mi);
72 if (hue <= 1)
73 {
74 rgb.x = ma;
75 rgb.y = hue * (ma - mi) + mi;
76 rgb.z = mi;
77 }
78 //else if (ma == rgb_y)
79 // hue = 60 * (rgb_z - rgb_x) / (ma - mi) + 120;
80 else if (hue <= 2)
81 {
82 rgb.x = (2 - hue) * (ma - mi) + mi;
83 rgb.y = ma;
84 rgb.z = mi;
85 }
86 else if (hue <= 3)
87 {
88 rgb.x = mi;
89 rgb.y = ma;
90 rgb.z = (hue - 2) * (ma - mi) + mi;
91 }
92 //else if (ma == rgb_z)
93 // hue = 60 * (rgb_x - rgb_y) / (ma - mi) + 240;
94 else if (hue <= 4)
95 {
96 rgb.x = mi;
97 rgb.y = (4 - hue) * (ma - mi) + mi;
98 rgb.z = ma;
99 }
100 else if (hue <= 5)
101 {
102 rgb.x = (hue - 4) * (ma - mi) + mi;
103 rgb.y = mi;
104 rgb.z = ma;
105 }
106 //else if (ma == rgb_x)
107 // hue = 60 * (rgb_y - rgb_z) / (ma - mi);
108 else //if (hue <= 6)
109 {
110 rgb.x = ma;
111 rgb.y = mi;
112 rgb.z = (6 - hue) * (ma - mi) + mi;
113 }
114
115 return rgb;
116}
117
120{
121 float mi = min(rgb.x, rgb.y, rgb.z);
122 float ma = max(rgb.x, rgb.y, rgb.z);
123
124 vector hsv;
125 hsv.x = rgb_mi_ma_to_hue(rgb, mi, ma);
126 hsv.z = ma;
127
128 hsv.y = (ma == 0)
129 ? 0
130 : 1 - mi / ma;
131
132 return hsv;
133}
134
137{
138 return hue_mi_ma_to_rgb(hsv.x, hsv.z * (1 - hsv.y), hsv.z);
139}
140
143{
144 float mi = min(rgb.x, rgb.y, rgb.z);
145 float ma = max(rgb.x, rgb.y, rgb.z);
146
147 vector hsl;
148 hsl.x = rgb_mi_ma_to_hue(rgb, mi, ma);
149 hsl.z = 0.5 * (mi + ma);
150
151 if (mi == ma)
152 hsl.y = 0;
153 else if (hsl.z <= 0.5)
154 hsl.y = (ma - mi) / (2 * hsl.z);
155 else //if (hsl_z > 0.5)
156 hsl.y = (ma - mi) / (2 - 2 * hsl.z);
157
158 return hsl;
159}
160
163{
164 float maminusmi = (hsl.z <= 0.5)
165 ? hsl.y * 2 * hsl.z
166 : hsl.y * (2 - 2 * hsl.z);
167
168 // hsl.z = 0.5 * mi + 0.5 * ma
169 // maminusmi = - mi + ma
170 float mi = hsl.z - 0.5 * maminusmi;
171 float ma = hsl.z + 0.5 * maminusmi;
172
173 return hue_mi_ma_to_rgb(hsl.x, mi, ma);
174}
175
178{
179 return strcat("^x",
180 DEC_TO_HEXDIGIT(floor(bound(0, rgb.x, 1) * 15 + 0.5)),
181 DEC_TO_HEXDIGIT(floor(bound(0, rgb.y, 1) * 15 + 0.5)),
182 DEC_TO_HEXDIGIT(floor(bound(0, rgb.z, 1) * 15 + 0.5))
183 );
184}
185
186// useful macro for the guide
187// prefer .message if available
188// TODO: use either .message or .m_name for everything. currently only Gametypes and Mutators use .message
189#define COLORED_NAME(this) strcat(rgb_to_hexcolor(this.m_color), (this.message ? this.message : this.m_name), "^7")
ERASEABLE string rgb_to_hexcolor(vector rgb)
Definition color.qh:177
ERASEABLE vector rgb_to_hsl(vector rgb)
Definition color.qh:142
ERASEABLE vector hue_mi_ma_to_rgb(float hue, float mi, float ma)
Definition color.qh:64
ERASEABLE vector hsl_to_rgb(vector hsl)
Definition color.qh:162
ERASEABLE vector rgb_to_hsv(vector rgb)
Definition color.qh:119
ERASEABLE float rgb_mi_ma_to_hue(vector rgb, float mi, float ma)
Definition color.qh:46
ERASEABLE vector hsv_to_rgb(vector hsv)
Definition color.qh:136
ERASEABLE vector colormapPaletteColor_(int c, bool isPants, float t)
Definition color.qh:7
#define ERASEABLE
Definition _all.inc:37
const float M_E
e
Definition mathlib.qh:105
#define M_PI
pi
Definition mathlib.qh:112
float bound(float min, float value, float max)
float sin(float f)
float min(float f,...)
float floor(float f)
float max(float f,...)
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
vector
Definition self.qh:96
#define DEC_TO_HEXDIGIT(d)
Definition string.qh:579