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