added -texgamma, -texcontrast, -texbrightness, these manipulate the palette (note...
[divverent/darkplaces.git] / palette.c
1
2 #include "quakedef.h"
3
4 unsigned int d_8to24table[256];
5 //qbyte d_15to8table[32768];
6 qbyte host_basepal[768];
7
8 cvar_t v_gamma = {CVAR_SAVE, "v_gamma", "1"};
9 cvar_t v_contrast = {CVAR_SAVE, "v_contrast", "1"};
10 cvar_t v_brightness = {CVAR_SAVE, "v_brightness", "0"};
11 cvar_t v_overbrightbits = {CVAR_SAVE, "v_overbrightbits", "0"};
12 cvar_t v_hwgamma = {0, "v_hwgamma", "1"};
13
14 void Palette_Setup8to24(void)
15 {
16         int i;
17         qbyte *in, *out;
18
19         in = host_basepal;
20         out = (qbyte *) d_8to24table; // d_8to24table is accessed as 32bit for speed reasons, but is created as 8bit bytes
21         for (i=0 ; i<255 ; i++)
22         {
23                 *out++ = *in++;
24                 *out++ = *in++;
25                 *out++ = *in++;
26                 *out++ = 255;
27         }
28         d_8to24table[255] = 0; // completely transparent black
29 }
30
31 /*
32 void    Palette_Setup15to8(void)
33 {
34         qbyte   *pal;
35         unsigned r,g,b;
36         unsigned v;
37         int     r1,g1,b1;
38         int             j,k,l;
39         unsigned short i;
40
41         for (i = 0;i < 32768;i++)
42         {
43                 r = ((i & 0x001F) << 3)+4;
44                 g = ((i & 0x03E0) >> 2)+4;
45                 b = ((i & 0x7C00) >> 7)+4;
46                 pal = (unsigned char *)d_8to24table;
47                 for (v = 0, k = 0, l = 1000000000;v < 256;v++, pal += 4)
48                 {
49                         r1 = r - pal[0];
50                         g1 = g - pal[1];
51                         b1 = b - pal[2];
52                         j = r1*r1+g1*g1+b1*b1;
53                         if (j < l)
54                         {
55                                 k = v;
56                                 l = j;
57                         }
58                 }
59                 d_15to8table[i] = k;
60         }
61 }
62 */
63
64 void BuildGammaTable8(float prescale, float gamma, float scale, float base, qbyte *out)
65 {
66         int i, adjusted;
67         double invgamma, d;
68
69         gamma = bound(0.1, gamma, 5.0);
70         if (gamma == 1) // LordHavoc: dodge the math
71         {
72                 for (i = 0;i < 256;i++)
73                 {
74                         adjusted = (int) (i * prescale * scale + base * 255.0);
75                         out[i] = bound(0, adjusted, 255);
76                 }
77         }
78         else
79         {
80                 invgamma = 1.0 / gamma;
81                 prescale /= 255.0f;
82                 for (i = 0;i < 256;i++)
83                 {
84                         d = pow((double) i * prescale, invgamma) * scale + base;
85                         adjusted = (int) (255.0 * d);
86                         out[i] = bound(0, adjusted, 255);
87                 }
88         }
89 }
90
91 void BuildGammaTable16(float prescale, float gamma, float scale, float base, unsigned short *out)
92 {
93         int i, adjusted;
94         double invgamma, d;
95
96         gamma = bound(0.1, gamma, 5.0);
97         if (gamma == 1) // LordHavoc: dodge the math
98         {
99                 for (i = 0;i < 256;i++)
100                 {
101                         adjusted = (int) (i * 256.0 * prescale * scale + base * 65535.0);
102                         out[i] = bound(0, adjusted, 65535);
103                 }
104         }
105         else
106         {
107                 invgamma = 1.0 / gamma;
108                 prescale /= 255.0f;
109                 for (i = 0;i < 256;i++)
110                 {
111                         d = pow((double) i * prescale, invgamma) * scale + base;
112                         adjusted = (int) (65535.0 * d);
113                         out[i] = bound(0, adjusted, 65535);
114                 }
115         }
116 }
117
118 qboolean hardwaregammasupported = false;
119 void VID_UpdateGamma(qboolean force)
120 {
121         static float cachegamma = -1, cachebrightness = -1, cachecontrast = -1;
122         static int cacheoverbrightbits = -1, cachehwgamma = -1;
123
124         // LordHavoc: don't mess with gamma tables if running dedicated
125         if (cls.state == ca_dedicated)
126                 return;
127
128         if (!force
129          && v_gamma.value == cachegamma
130          && v_contrast.value == cachecontrast
131          && v_brightness.value == cachebrightness
132          && v_overbrightbits.integer == cacheoverbrightbits
133          && v_hwgamma.value == cachehwgamma)
134                 return;
135
136         if (v_gamma.value < 0.1)
137                 Cvar_SetValue("v_gamma", 0.1);
138         if (v_gamma.value > 5.0)
139                 Cvar_SetValue("v_gamma", 5.0);
140
141         if (v_contrast.value < 0.5)
142                 Cvar_SetValue("v_contrast", 0.5);
143         if (v_contrast.value > 5.0)
144                 Cvar_SetValue("v_contrast", 5.0);
145
146         if (v_brightness.value < 0)
147                 Cvar_SetValue("v_brightness", 0);
148         if (v_brightness.value > 0.8)
149                 Cvar_SetValue("v_brightness", 0.8);
150
151         cachegamma = v_gamma.value;
152         cachecontrast = v_contrast.value;
153         cachebrightness = v_brightness.value;
154         cacheoverbrightbits = v_overbrightbits.integer;
155
156         hardwaregammasupported = VID_SetGamma((float) (1 << cacheoverbrightbits), cachegamma, cachecontrast, cachebrightness);
157         if (!hardwaregammasupported)
158         {
159                 Con_Printf("Hardware gamma not supported.\n");
160                 Cvar_SetValue("v_hwgamma", 0);
161         }
162         cachehwgamma = v_hwgamma.integer;
163 }
164
165 void Gamma_Init(void)
166 {
167         Cvar_RegisterVariable(&v_gamma);
168         Cvar_RegisterVariable(&v_brightness);
169         Cvar_RegisterVariable(&v_contrast);
170         Cvar_RegisterVariable(&v_hwgamma);
171         Cvar_RegisterVariable(&v_overbrightbits);
172 }
173
174 void Palette_Init(void)
175 {
176         int i;
177         float gamma, scale, base;
178         qbyte *pal;
179         qbyte temp[256];
180         pal = (qbyte *)COM_LoadFile ("gfx/palette.lmp", false);
181         if (!pal)
182                 Sys_Error ("Couldn't load gfx/palette.lmp");
183         memcpy(host_basepal, pal, 765);
184         Mem_Free(pal);
185         host_basepal[765] = host_basepal[766] = host_basepal[767] = 0; // LordHavoc: force the transparent color to black
186
187         gamma = 1;
188         scale = 1;
189         base = 0;
190         i = COM_CheckParm("-texgamma");
191         if (i)
192                 gamma = atof(com_argv[i + 1]);
193         i = COM_CheckParm("-texcontrast");
194         if (i)
195                 scale = atof(com_argv[i + 1]);
196         i = COM_CheckParm("-texbrightness");
197         if (i)
198                 base = atof(com_argv[i + 1]);
199         gamma = bound(0.01, gamma, 10.0);
200         scale = bound(0.01, scale, 10.0);
201         base = bound(0, base, 0.95);
202
203         BuildGammaTable8(1.0f, gamma, scale, base, temp);
204         for (i = 3;i < 765;i++)
205                 host_basepal[i] = temp[host_basepal[i]];
206
207         Palette_Setup8to24();
208 //      Palette_Setup15to8();
209 }