]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake3/q3data/images.c
eol style
[xonotic/netradiant.git] / tools / quake3 / q3data / images.c
1 #include "q3data.h"
2
3 byte                    *byteimage, *lbmpalette;
4 int                             byteimagewidth, byteimageheight;
5
6
7 char            mip_prefix[1024];               // directory to dump the textures in
8
9 qboolean        colormap_issued;
10 byte            colormap_palette[768];
11
12 /*
13 ==============
14 Cmd_Grab
15
16 $grab filename x y width height
17 ==============
18 */
19 void Cmd_Grab (void)
20 {
21         int             xl,yl,w,h,y;
22         byte                    *cropped;
23         char                    savename[1024];
24         char                    dest[1024];
25
26         GetToken (qfalse);
27
28         if (token[0] == '/' || token[0] == '\\')
29                 sprintf (savename, "%s%s.pcx", writedir, token+1);
30         else
31                 sprintf (savename, "%spics/%s.pcx", writedir, token);
32
33         if (g_release)
34         {
35                 if (token[0] == '/' || token[0] == '\\')
36                         sprintf (dest, "%s.pcx", token+1);
37                 else
38                         sprintf (dest, "pics/%s.pcx", token);
39
40                 ReleaseFile (dest);
41                 return;
42         }
43
44         GetToken (qfalse);
45         xl = atoi (token);
46         GetToken (qfalse);
47         yl = atoi (token);
48         GetToken (qfalse);
49         w = atoi (token);
50         GetToken (qfalse);
51         h = atoi (token);
52
53         if (xl<0 || yl<0 || w<0 || h<0 || xl+w>byteimagewidth || yl+h>byteimageheight)
54                 Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h);
55
56         // crop it to the proper size
57         cropped = malloc (w*h);
58         for (y=0 ; y<h ; y++)
59         {
60                 memcpy (cropped+y*w, byteimage+(y+yl)*byteimagewidth+xl, w);
61         }
62
63         // save off the new image
64         printf ("saving %s\n", savename);
65         CreatePath (savename);
66         WritePCXfile (savename, cropped, w,     h, lbmpalette);
67
68         free (cropped);
69 }
70
71 /*
72 ==============
73 Cmd_Raw
74
75 $grab filename x y width height
76 ==============
77 */
78 void Cmd_Raw (void)
79 {
80         int             xl,yl,w,h,y;
81         byte                    *cropped;
82         char                    savename[1024];
83         char                    dest[1024];
84
85         GetToken (qfalse);
86
87         sprintf (savename, "%s%s.lmp", writedir, token);
88
89         if (g_release)
90         {
91                 sprintf (dest, "%s.lmp", token);
92                 ReleaseFile (dest);
93                 return;
94         }
95
96         GetToken (qfalse);
97         xl = atoi (token);
98         GetToken (qfalse);
99         yl = atoi (token);
100         GetToken (qfalse);
101         w = atoi (token);
102         GetToken (qfalse);
103         h = atoi (token);
104
105         if (xl<0 || yl<0 || w<0 || h<0 || xl+w>byteimagewidth || yl+h>byteimageheight)
106                 Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h);
107
108         // crop it to the proper size
109         cropped = malloc (w*h);
110         for (y=0 ; y<h ; y++)
111         {
112                 memcpy (cropped+y*w, byteimage+(y+yl)*byteimagewidth+xl, w);
113         }
114
115         // save off the new image
116         printf ("saving %s\n", savename);
117         CreatePath (savename);
118
119         SaveFile (savename, cropped, w*h);
120
121         free (cropped);
122 }
123
124 /*
125 =============================================================================
126
127 COLORMAP GRABBING
128
129 =============================================================================
130 */
131
132 /*
133 ===============
134 BestColor
135 ===============
136 */
137 byte BestColor (int r, int g, int b, int start, int stop)
138 {
139         int     i;
140         int     dr, dg, db;
141         int     bestdistortion, distortion;
142         int     bestcolor;
143         byte    *pal;
144
145 //
146 // let any color go to 0 as a last resort
147 //
148         bestdistortion = 256*256*4;
149         bestcolor = 0;
150
151         pal = colormap_palette + start*3;
152         for (i=start ; i<= stop ; i++)
153         {
154                 dr = r - (int)pal[0];
155                 dg = g - (int)pal[1];
156                 db = b - (int)pal[2];
157                 pal += 3;
158                 distortion = dr*dr + dg*dg + db*db;
159                 if (distortion < bestdistortion)
160                 {
161                         if (!distortion)
162                                 return i;               // perfect match
163
164                         bestdistortion = distortion;
165                         bestcolor = i;
166                 }
167         }
168
169         return bestcolor;
170 }
171
172
173 /*
174 ==============
175 Cmd_Colormap
176
177 $colormap filename
178
179   the brightes colormap is first in the table (FIXME: reverse this now?)
180
181   64 rows of 256 : lightmaps
182   256 rows of 256 : translucency table
183 ==============
184 */
185 void Cmd_Colormap (void)
186 {
187         int             levels, brights;
188         int             l, c;
189         float   frac, red, green, blue;
190         float   range;
191         byte    *cropped, *lump_p;
192         char    savename[1024];
193         char    dest[1024];
194
195         colormap_issued = qtrue;
196         if (!g_release)
197                 memcpy (colormap_palette, lbmpalette, 768);
198
199         if (!TokenAvailable ())
200         {       // just setting colormap_issued
201                 return;
202         }
203
204         GetToken (qfalse);
205         sprintf (savename, "%spics/%s.pcx", writedir, token);
206
207         if (g_release)
208         {
209                 sprintf (dest, "pics/%s.pcx", token);
210                 ReleaseFile (dest);
211                 return;
212         }
213
214         range = 2;
215         levels = 64;
216         brights = 1;    // ignore 255 (transparent)
217
218         cropped = malloc((levels+256)*256);
219         lump_p = cropped;
220
221 // shaded levels
222         for (l=0;l<levels;l++)
223         {
224                 frac = range - range*(float)l/(levels-1);
225                 for (c=0 ; c<256-brights ; c++)
226                 {
227                         red = lbmpalette[c*3];
228                         green = lbmpalette[c*3+1];
229                         blue = lbmpalette[c*3+2];
230
231                         red = (int)(red*frac+0.5);
232                         green = (int)(green*frac+0.5);
233                         blue = (int)(blue*frac+0.5);
234                         
235 //
236 // note: 254 instead of 255 because 255 is the transparent color, and we
237 // don't want anything remapping to that
238 // don't use color 0, because NT can't remap that (or 255)
239 //
240                         *lump_p++ = BestColor(red,green,blue, 1, 254);
241                 }
242
243                 // fullbrights allways stay the same
244                 for ( ; c<256 ; c++)
245                         *lump_p++ = c;
246         }
247         
248 // 66% transparancy table
249         for (l=0;l<255;l++)
250         {
251                 for (c=0 ; c<255 ; c++)
252                 {
253                         red = lbmpalette[c*3]*0.33 + lbmpalette[l*3]*0.66;
254                         green = lbmpalette[c*3+1]*0.33 + lbmpalette[l*3+1]*0.66;
255                         blue = lbmpalette[c*3+2]*0.33 + lbmpalette[l*3+2]*0.66;
256
257                         *lump_p++ = BestColor(red,green,blue, 1, 254);
258                 }
259                 *lump_p++ = 255;
260         }
261         for (c=0 ; c<256 ; c++)
262                 *lump_p++ = 255;
263         
264         // save off the new image
265         printf ("saving %s\n", savename);
266         CreatePath (savename);
267         WritePCXfile (savename, cropped, 256, levels+256, lbmpalette);
268
269         free (cropped);
270 }
271
272 /*
273 =============================================================================
274
275 MIPTEX GRABBING
276
277 =============================================================================
278 */
279
280 byte    pixdata[256];
281
282 int             d_red, d_green, d_blue;
283
284 byte    palmap[32][32][32];
285 qboolean        palmap_built;
286
287 /*
288 =============
289 FindColor
290 =============
291 */
292 int FindColor (int r, int g, int b)
293 {
294         int             bestcolor;
295
296         if (r > 255)
297                 r = 255;
298         if (r < 0)
299                 r = 0;
300         if (g > 255)
301                 g = 255;
302         if (g < 0)
303                 g = 0;
304         if (b > 255)
305                 b = 255;
306         if (b < 0)
307                 b = 0;
308 #ifndef TABLECOLORS
309         bestcolor = BestColor (r, g, b, 0, 254);
310 #else
311         bestcolor = palmap[r>>3][g>>3][b>>3];
312 #endif
313
314         return bestcolor;
315 }
316
317
318 void BuildPalmap (void)
319 {
320 #ifdef TABLECOLORS
321         int             r, g, b;
322         int             bestcolor;
323
324         if (palmap_built)
325                 return;
326         palmap_built = qtrue;
327
328         for (r=4 ; r<256 ; r+=8)
329         {
330                 for (g=4 ; g<256 ; g+=8)
331                 {
332                         for (b=4 ; b<256 ; b+=8)
333                         {
334                                 bestcolor = BestColor (r, g, b, 1, 254);
335                                 palmap[r>>3][g>>3][b>>3] = bestcolor;
336                         }
337                 }
338         }
339 #endif
340
341         if (!colormap_issued)
342                 Error ("You must issue a $colormap command first");
343
344 }
345
346 /*
347 =============
348 AveragePixels
349 =============
350 */
351 byte AveragePixels (int count)
352 {
353         int             r,g,b;
354         int             i;
355         int             vis;
356         int             pix;
357         int             bestcolor;
358         byte    *pal;
359         int             fullbright;
360         
361         vis = 0;
362         r = g = b = 0;
363         fullbright = 0;
364         for (i=0 ; i<count ; i++)
365         {
366                 pix = pixdata[i];
367                 
368                 r += lbmpalette[pix*3];
369                 g += lbmpalette[pix*3+1];
370                 b += lbmpalette[pix*3+2];
371                 vis++;
372         }
373                 
374         r /= vis;
375         g /= vis;
376         b /= vis;
377
378         // error diffusion
379         r += d_red;
380         g += d_green;
381         b += d_blue;
382         
383 //
384 // find the best color
385 //
386         bestcolor = FindColor (r, g, b);
387
388         // error diffusion
389         pal = colormap_palette + bestcolor*3;
390         d_red = r - (int)pal[0];
391         d_green = g - (int)pal[1];
392         d_blue = b - (int)pal[2];
393
394         return bestcolor;
395 }
396
397
398
399 /*
400 =============================================================================
401
402 ENVIRONMENT MAP GRABBING
403
404 Creates six pcx files from tga files without any palette edge seams
405 also copies the tga files for GL rendering.
406 =============================================================================
407 */
408
409 // 3dstudio environment map suffixes
410 char    *suf[6] = {"rt", "ft", "lf", "bk", "up", "dn"};
411
412 /*
413 =================
414 Cmd_Environment
415 =================
416 */
417 void Cmd_Environment (void)
418 {
419         char    name[1024];
420         int             i, x, y;
421         byte    image[256*256];
422         byte    *tga;
423
424         GetToken (qfalse);
425
426         if (g_release)
427         {
428                 for (i=0 ; i<6 ; i++)
429                 {
430                         sprintf (name, "env/%s%s.pcx", token, suf[i]);
431                         ReleaseFile (name);
432                         sprintf (name, "env/%s%s.tga", token, suf[i]);
433                         ReleaseFile (name);
434                 }
435                 return;
436         }
437         // get the palette
438         BuildPalmap ();
439
440         sprintf (name, "%senv/", gamedir);
441         CreatePath (name);
442
443         // convert the images
444         for (i=0 ; i<6 ; i++)
445         {
446                 sprintf (name, "%senv/%s%s.tga", gamedir, token, suf[i]);
447                 printf ("loading %s...\n", name);
448                 LoadTGA (name, &tga, NULL, NULL);
449
450                 for (y=0 ; y<256 ; y++)
451                 {
452                         for (x=0 ; x<256 ; x++)
453                         {
454                                 image[y*256+x] = FindColor (tga[(y*256+x)*4+0],tga[(y*256+x)*4+1],tga[(y*256+x)*4+2]);
455                         }
456                 }
457                 free (tga);
458                 sprintf (name, "%senv/%s%s.pcx", writedir, token, suf[i]);
459                 if (FileTime (name) != -1)
460                         printf ("%s already exists, not overwriting.\n", name);
461                 else
462                         WritePCXfile (name, image, 256, 256, colormap_palette);
463         }
464 }
465