2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 char mip_prefix[1024]; // directory to dump the textures in
27 qboolean colormap_issued;
28 byte colormap_palette[768];
34 Replaces all 0 bytes in an image with the closest palette entry.
35 This is because NT won't let us change index 0, so any palette
36 animation leaves those pixels untouched.
39 void RemapZero (byte *pixels, byte *palette, int width, int height)
47 for (i=1 ; i<255 ; i++)
49 value = palette[i*3+0]+palette[i*3+1]+palette[i*3+2];
67 $grab filename x y width height
79 if (token[0] == '/' || token[0] == '\\')
80 sprintf (savename, "%s%s.pcx", gamedir, token+1);
82 sprintf (savename, "%spics/%s.pcx", gamedir, token);
86 if (token[0] == '/' || token[0] == '\\')
87 sprintf (dest, "%s.pcx", token+1);
89 sprintf (dest, "pics/%s.pcx", token);
104 if (xl<0 || yl<0 || w<0 || h<0 || xl+w>byteimagewidth || yl+h>byteimageheight)
105 Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h);
107 // crop it to the proper size
108 cropped = malloc (w*h);
109 for (y=0 ; y<h ; y++)
111 memcpy (cropped+y*w, byteimage+(y+yl)*byteimagewidth+xl, w);
114 // save off the new image
115 printf ("saving %s\n", savename);
116 CreatePath (savename);
117 WritePCXfile (savename, cropped, w, h, lbmpalette);
126 $grab filename x y width height
138 sprintf (savename, "%s%s.lmp", gamedir, token);
142 sprintf (dest, "%s.lmp", token);
156 if (xl<0 || yl<0 || w<0 || h<0 || xl+w>byteimagewidth || yl+h>byteimageheight)
157 Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h);
159 // crop it to the proper size
160 cropped = malloc (w*h);
161 for (y=0 ; y<h ; y++)
163 memcpy (cropped+y*w, byteimage+(y+yl)*byteimagewidth+xl, w);
166 // save off the new image
167 printf ("saving %s\n", savename);
168 CreatePath (savename);
170 SaveFile (savename, cropped, w*h);
176 =============================================================================
180 =============================================================================
188 byte BestColor (int r, int g, int b, int start, int stop)
192 int bestdistortion, distortion;
197 // let any color go to 0 as a last resort
199 bestdistortion = 256*256*4;
202 pal = colormap_palette + start*3;
203 for (i=start ; i<= stop ; i++)
205 dr = r - (int)pal[0];
206 dg = g - (int)pal[1];
207 db = b - (int)pal[2];
209 distortion = dr*dr + dg*dg + db*db;
210 if (distortion < bestdistortion)
213 return i; // perfect match
215 bestdistortion = distortion;
230 the brightes colormap is first in the table (FIXME: reverse this now?)
232 64 rows of 256 : lightmaps
233 256 rows of 256 : translucency table
236 void Cmd_Colormap (void)
240 float frac, red, green, blue;
242 byte *cropped, *lump_p;
246 colormap_issued = true;
248 memcpy (colormap_palette, lbmpalette, 768);
250 if (!TokenAvailable ())
251 { // just setting colormap_issued
256 sprintf (savename, "%spics/%s.pcx", gamedir, token);
260 sprintf (dest, "pics/%s.pcx", token);
267 brights = 1; // ignore 255 (transparent)
269 cropped = malloc((levels+256)*256);
273 for (l=0;l<levels;l++)
275 frac = range - range*(float)l/(levels-1);
276 for (c=0 ; c<256-brights ; c++)
278 red = lbmpalette[c*3];
279 green = lbmpalette[c*3+1];
280 blue = lbmpalette[c*3+2];
282 red = (int)(red*frac+0.5);
283 green = (int)(green*frac+0.5);
284 blue = (int)(blue*frac+0.5);
287 // note: 254 instead of 255 because 255 is the transparent color, and we
288 // don't want anything remapping to that
289 // don't use color 0, because NT can't remap that (or 255)
291 *lump_p++ = BestColor(red,green,blue, 1, 254);
294 // fullbrights allways stay the same
299 // 66% transparancy table
302 for (c=0 ; c<255 ; c++)
304 red = lbmpalette[c*3]*0.33 + lbmpalette[l*3]*0.66;
305 green = lbmpalette[c*3+1]*0.33 + lbmpalette[l*3+1]*0.66;
306 blue = lbmpalette[c*3+2]*0.33 + lbmpalette[l*3+2]*0.66;
308 *lump_p++ = BestColor(red,green,blue, 1, 254);
312 for (c=0 ; c<256 ; c++)
315 // save off the new image
316 printf ("saving %s\n", savename);
317 CreatePath (savename);
318 WritePCXfile (savename, cropped, 256, levels+256, lbmpalette);
324 =============================================================================
328 =============================================================================
333 int d_red, d_green, d_blue;
335 byte palmap[32][32][32];
336 qboolean palmap_built;
343 int FindColor (int r, int g, int b)
360 bestcolor = BestColor (r, g, b, 0, 254);
362 bestcolor = palmap[r>>3][g>>3][b>>3];
369 void BuildPalmap (void)
379 for (r=4 ; r<256 ; r+=8)
381 for (g=4 ; g<256 ; g+=8)
383 for (b=4 ; b<256 ; b+=8)
385 bestcolor = BestColor (r, g, b, 1, 254);
386 palmap[r>>3][g>>3][b>>3] = bestcolor;
392 if (!colormap_issued)
393 Error ("You must issue a $colormap command first");
402 byte AveragePixels (int count)
415 for (i=0 ; i<count ; i++)
419 r += lbmpalette[pix*3];
420 g += lbmpalette[pix*3+1];
421 b += lbmpalette[pix*3+2];
435 // find the best color
437 bestcolor = FindColor (r, g, b);
440 pal = colormap_palette + bestcolor*3;
441 d_red = r - (int)pal[0];
442 d_green = g - (int)pal[1];
443 d_blue = b - (int)pal[2];
464 mipparm_t mipparms[] =
466 // utility content attributes
467 {"water", CONTENTS_WATER, pt_contents},
468 {"slime", CONTENTS_SLIME, pt_contents}, // mildly damaging
469 {"lava", CONTENTS_LAVA, pt_contents}, // very damaging
470 {"window", CONTENTS_WINDOW, pt_contents}, // solid, but doesn't eat internal textures
471 {"mist", CONTENTS_MIST, pt_contents}, // non-solid window
472 {"origin", CONTENTS_ORIGIN, pt_contents}, // center of rotating brushes
473 {"playerclip", CONTENTS_PLAYERCLIP, pt_contents},
474 {"monsterclip", CONTENTS_MONSTERCLIP, pt_contents},
476 // utility surface attributes
477 {"hint", SURF_HINT, pt_flags},
478 {"skip", SURF_SKIP, pt_flags},
479 {"light", SURF_LIGHT, pt_flagvalue}, // value is the light quantity
482 {"anim", 0, pt_animvalue}, // value is the next animation
485 {"slick", SURF_SLICK, pt_flags},
487 // drawing attributes
488 {"sky", SURF_SKY, pt_flags},
489 {"warping", SURF_WARP, pt_flags}, // only valid with 64x64 textures
490 {"trans33", SURF_TRANS33, pt_flags}, // translucent should allso set fullbright
491 {"trans66", SURF_TRANS66, pt_flags},
492 {"flowing", SURF_FLOWING, pt_flags}, // flow direction towards angle 0
493 {"nodraw", SURF_NODRAW, pt_flags}, // for clip textures and trigger textures
495 {NULL, 0, pt_contents}
504 $mip filename x y width height <OPTIONS>
505 must be multiples of sixteen
511 int x,y,xl,yl,xh,yh,w,h;
512 byte *screen_p, *source;
515 int miplevel, mipstep;
518 int flags, value, contents;
526 strcpy (lumpname, token);
537 if ( (w & 15) || (h & 15) )
538 Error ("line %i: miptex sizes must be multiples of 16", scriptline);
546 // get optional flags and values
547 while (TokenAvailable ())
551 for (mp=mipparms ; mp->name ; mp++)
553 if (!strcmp(mp->name, token))
558 GetToken (false); // specify the next animation frame
559 strcpy (animname, token);
565 contents |= mp->flags;
569 GetToken (false); // specify the light value
577 Error ("line %i: unknown parm %s", scriptline, token);
580 sprintf (filename, "%stextures/%s/%s.wal", gamedir, mip_prefix, lumpname);
582 return; // textures are only released by $maps
587 qtex = malloc (sizeof(miptex_t) + w*h*2);
588 memset (qtex, 0, sizeof(miptex_t));
590 qtex->width = LittleLong(w);
591 qtex->height = LittleLong(h);
592 qtex->flags = LittleLong(flags);
593 qtex->contents = LittleLong(contents);
594 qtex->value = LittleLong(value);
595 sprintf (qtex->name, "%s/%s", mip_prefix, lumpname);
597 sprintf (qtex->animname, "%s/%s", mip_prefix, animname);
599 lump_p = (byte *)(&qtex->value+1);
601 screen_p = byteimage + yl*byteimagewidth + xl;
602 linedelta = byteimagewidth - w;
605 qtex->offsets[0] = LittleLong(lump_p - (byte *)qtex);
607 for (y=yl ; y<yh ; y++)
609 for (x=xl ; x<xh ; x++)
613 pix = 1; // should never happen
616 screen_p += linedelta;
620 // subsample for greater mip levels
622 d_red = d_green = d_blue = 0; // no distortion yet
624 for (miplevel = 1 ; miplevel<4 ; miplevel++)
626 qtex->offsets[miplevel] = LittleLong(lump_p - (byte *)qtex);
628 mipstep = 1<<miplevel;
629 for (y=0 ; y<h ; y+=mipstep)
632 for (x = 0 ; x<w ; x+= mipstep)
635 for (yy=0 ; yy<mipstep ; yy++)
636 for (xx=0 ; xx<mipstep ; xx++)
638 pixdata[count] = source[ (y+yy)*w + x + xx ];
641 *lump_p++ = AveragePixels (count);
647 // dword align the size
649 while ((int)lump_p&3)
655 printf ("writing %s\n", filename);
656 SaveFile (filename, (byte *)qtex, lump_p - (byte *)qtex);
666 void Cmd_Mippal (void)
668 colormap_issued = true;
672 memcpy (colormap_palette, lbmpalette, 768);
683 void Cmd_Mipdir (void)
688 strcpy (mip_prefix, token);
689 // create the directory if needed
690 sprintf (filename, "%stextures", gamedir, mip_prefix);
692 sprintf (filename, "%stextures/%s", gamedir, mip_prefix);
698 =============================================================================
700 ENVIRONMENT MAP GRABBING
702 Creates six pcx files from tga files without any palette edge seams
703 also copies the tga files for GL rendering.
704 =============================================================================
707 // 3dstudio environment map suffixes
708 char *suf[6] = {"rt", "ft", "lf", "bk", "up", "dn"};
715 void Cmd_Environment (void)
726 for (i=0 ; i<6 ; i++)
728 sprintf (name, "env/%s%s.pcx", token, suf[i]);
730 sprintf (name, "env/%s%s.tga", token, suf[i]);
738 sprintf (name, "%senv/", gamedir);
741 // convert the images
742 for (i=0 ; i<6 ; i++)
744 sprintf (name, "%senv/%s%s.tga", gamedir, token, suf[i]);
745 printf ("loading %s...\n", name);
746 LoadTGA (name, &tga, NULL, NULL);
748 for (y=0 ; y<256 ; y++)
750 for (x=0 ; x<256 ; x++)
752 image[y*256+x] = FindColor (tga[(y*256+x)*4+0],tga[(y*256+x)*4+1],tga[(y*256+x)*4+2]);
756 sprintf (name, "%senv/%s%s.pcx", gamedir, token, suf[i]);
757 if (FileTime (name) != -1)
758 printf ("%s already exists, not overwriting.\n", name);
760 WritePCXfile (name, image, 256, 256, colormap_palette);