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
31 extern char *g_outputDir;
34 char mip_prefix[1024]; // directory to dump the textures in
36 qboolean colormap_issued;
37 byte colormap_palette[768];
41 unsigned total_textures = 0;
43 #define MAX_IMAGE_SIZE 512
50 Replaces all 0 bytes in an image with the closest palette entry.
51 This is because NT won't let us change index 0, so any palette
52 animation leaves those pixels untouched.
55 void RemapZero (byte *pixels, byte *palette, int width, int height)
63 for (i=1 ; i<255 ; i++)
65 value = palette[i*3+0]+palette[i*3+1]+palette[i*3+2];
82 // ********************************************************************
83 // ** Mip Map Pre-Processing Routines
84 // ********************************************************************
86 #define intensity_value 1
88 static unsigned image_pal[256];
92 long palette_r[256], palette_g[256], palette_b[256];
93 long last_r[MAX_LAST],last_g[MAX_LAST],last_b[MAX_LAST], last_i[MAX_LAST], last_place;
97 void PrepareConvert(unsigned *palette)
103 palette_r[i] = (palette[i] & 0x00ff0000) >> 16;
104 palette_g[i] = (palette[i] & 0x0000ff00) >> 8;
105 palette_b[i] = (palette[i] & 0x000000ff);
108 for(i=0;i<MAX_LAST;i++)
114 int ConvertTrueColorToPal(unsigned r, unsigned g, unsigned b)
120 long dr, dg, db, biggest_delta;
122 for(i=0;i<MAX_LAST;i++)
123 if (r == last_r[i] && g == last_g[i] && b == last_b[i])
129 min_dist = 256 * 256 + 256 * 256 + 256 * 256;
130 biggest_delta = 256*256;
135 dr = abs(palette_r[i] - r);
136 if (dr > biggest_delta)
138 dg = abs(palette_g[i] - g);
139 if (dg > biggest_delta)
141 db = abs(palette_b[i] - b);
142 if (db > biggest_delta)
145 dist = dr * dr + dg * dg + db * db;
150 if (min_dist == 0) break;
153 if (dg > dist) dist = dg;
154 if (db > dist) dist = db;
155 if (dist < biggest_delta)
156 biggest_delta = dist;
161 if (last_place >= MAX_LAST)
164 last_r[last_place] = r;
165 last_g[last_place] = g;
166 last_b[last_place] = b;
167 last_i[last_place] = min_index;
173 void GL_ResampleTexture8P (byte *in, int inwidth, int inheight, byte *out,
174 int outwidth, int outheight, palette_t *palette)
177 byte *inrow, *inrow2;
178 unsigned frac, fracstep;
179 unsigned p1[1024], p2[1024], *p1p, *p2p;
180 palette_t *c1,*c2,*c3,*c4;
183 fracstep = inwidth*0x10000/outwidth;
186 for (i=0 ; i<outwidth ; i++)
191 frac = 3*(fracstep>>2);
192 for (i=0 ; i<outwidth ; i++)
200 for (i=0 ; i<outheight ; i++)//, out += outwidth)
202 inrow = in + inwidth*(int)((i+0.25)*inheight/outheight);
203 inrow2 = in + inwidth*(int)((i+0.75)*inheight/outheight);
207 for (j=0 ; j<outwidth ; j++)
209 c1 = &palette[*((byte *)inrow + (*p1p))];
210 c2 = &palette[*((byte *)inrow + (*p2p))];
211 c3 = &palette[*((byte *)inrow2 + (*p1p++))];
212 c4 = &palette[*((byte *)inrow2 + (*p2p++))];
214 r = ((unsigned)c1->r + (unsigned)c2->r + (unsigned)c3->r + (unsigned)c4->r)>>2;
215 g = ((unsigned)c1->g + (unsigned)c2->g + (unsigned)c3->g + (unsigned)c4->g)>>2;
216 b = ((unsigned)c1->b + (unsigned)c2->b + (unsigned)c3->b + (unsigned)c4->b)>>2;
218 *out++ = ConvertTrueColorToPal(r,g,b);
223 void GL_MipMap8P(byte *out, byte *in, int width, int height, palette_t *palette)
226 palette_t *c1,*c2,*c3,*c4;
230 memset(out, 0, 256 * 256);
234 for (i = 0; i < height; i += 2, in += width)
236 for (j = 0; j < width; j += 2)
238 c1 = &palette[in[0]];
239 c3 = &palette[in[width]];
241 c2 = &palette[in[0]];
242 c4 = &palette[in[width]];
245 r = ((unsigned)c1->r + (unsigned)c2->r + (unsigned)c3->r + (unsigned)c4->r) >> 2;
246 g = ((unsigned)c1->g + (unsigned)c2->g + (unsigned)c3->g + (unsigned)c4->g) >> 2;
247 b = ((unsigned)c1->b + (unsigned)c2->b + (unsigned)c3->b + (unsigned)c4->b) >> 2;
249 *out++ = ConvertTrueColorToPal(r, g, b);
255 miptex_t *CreateMip(byte *data, unsigned width, unsigned height, byte *palette, int *FinalSize, qboolean mip)
257 int scaled_width, scaled_height;
259 byte intensitytable[256];
260 byte scaled[256*256];
267 for (i=0 ; i<256 ; i++)
269 j = i * intensity_value;
272 intensitytable[i] = j;
275 for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
277 if (1 && scaled_width > width && 1)
279 for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
281 if (1 && scaled_height > height && 1)
284 // don't ever bother with >256 textures
285 if (scaled_width > 256)
287 if (scaled_height > 256)
290 if (scaled_width < 1)
292 if (scaled_height < 1)
295 size = sizeof(*mp) + (scaled_width*scaled_height*3);
296 mp = (miptex_t *)SafeMalloc(size, "CreateMip");
299 mp->version = MIP_VERSION;
301 for(i=j=0;i<256;i++,j+=3)
303 mp->palette[i].r = r = intensitytable[palette[j]];
304 mp->palette[i].g = g = intensitytable[palette[j+1]];
305 mp->palette[i].b = b = intensitytable[palette[j+2]];
306 image_pal[i] = 0xff000000 | (r<<16) | (g<<8) | (b);
309 PrepareConvert(image_pal);
311 if (scaled_width == width && scaled_height == height)
313 memcpy (scaled, data, width*height);
316 GL_ResampleTexture8P (data, width, height, scaled, scaled_width, scaled_height, mp->palette);
318 pos = (byte *)(mp + 1);
321 while ((scaled_width >= 1 || scaled_height >= 1) && (miplevel <= MIPLEVELS-1) && (!miplevel || mip))
323 if (scaled_width < 1)
325 if (scaled_height < 1)
329 GL_MipMap8P(out, (byte *)scaled, scaled_width, scaled_height, mp->palette);
331 memcpy(out, scaled, 256 * 256);
333 mp->width[miplevel] = scaled_width;
334 mp->height[miplevel] = scaled_height;
335 mp->offsets[miplevel] = pos - ((byte *)(mp));
336 memcpy(pos, out, scaled_width * scaled_height);
337 memcpy(scaled, out, 256 * 256);
338 pos += scaled_width * scaled_height;
346 *FinalSize = pos - ((byte *)(mp));
352 void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight)
355 unsigned *inrow, *inrow2;
356 unsigned frac, fracstep;
357 unsigned p1[1024], p2[1024];
358 byte *pix1, *pix2, *pix3, *pix4;
360 fracstep = inwidth*0x10000/outwidth;
363 for (i=0 ; i<outwidth ; i++)
365 p1[i] = 4*(frac>>16);
368 frac = 3*(fracstep>>2);
369 for (i=0 ; i<outwidth ; i++)
371 p2[i] = 4*(frac>>16);
375 for (i=0 ; i<outheight ; i++, out += outwidth)
377 inrow = in + inwidth*(int)((i+0.25)*inheight/outheight);
378 inrow2 = in + inwidth*(int)((i+0.75)*inheight/outheight);
379 frac = fracstep >> 1;
380 for (j=0 ; j<outwidth ; j++)
382 pix1 = (byte *)inrow + p1[j];
383 pix2 = (byte *)inrow + p2[j];
384 pix3 = (byte *)inrow2 + p1[j];
385 pix4 = (byte *)inrow2 + p2[j];
386 ((byte *)(out+j))[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0])>>2;
387 ((byte *)(out+j))[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2;
388 ((byte *)(out+j))[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2;
389 ((byte *)(out+j))[3] = (pix1[3] + pix2[3] + pix3[3] + pix4[3])>>2;
394 void GL_MipMap (byte *out, byte *in, int width, int height)
400 for (i=0 ; i<height ; i++, in+=width)
402 for (j=0 ; j<width ; j+=8, out+=4, in+=8)
404 out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
405 out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
406 out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
407 out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
412 miptex32_t *CreateMip32(unsigned *data, unsigned width, unsigned height, int *FinalSize, qboolean mip)
414 int scaled_width, scaled_height;
415 unsigned scaled[MAX_IMAGE_SIZE*MAX_IMAGE_SIZE];
416 unsigned out[MAX_IMAGE_SIZE*MAX_IMAGE_SIZE];
423 for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
425 if (1 && scaled_width > width && 1)
427 for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
429 if (1 && scaled_height > height && 1)
432 // don't ever bother with >256 textures
433 if (scaled_width > MAX_IMAGE_SIZE)
434 scaled_width = MAX_IMAGE_SIZE;
435 if (scaled_height > MAX_IMAGE_SIZE)
436 scaled_height = MAX_IMAGE_SIZE;
438 if (scaled_width < 1)
440 if (scaled_height < 1)
443 size = sizeof(*mp) + (scaled_width*scaled_height*3*4);
444 mp = (miptex32_t *)SafeMalloc(size, "CreateMip");
447 mp->version = MIP32_VERSION;
450 test = (paletteRGBA_t *)data;
455 mp->flags |= LittleLong(SURF_ALPHA_TEXTURE);
463 if (scaled_width == width && scaled_height == height)
465 memcpy (scaled, data, width*height*4);
468 GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
470 pos = (byte *)(mp + 1);
473 while ((scaled_width >= 1 || scaled_height >= 1) && (miplevel <= MIPLEVELS-1) && (!miplevel || mip))
475 if (scaled_width < 1)
477 if (scaled_height < 1)
482 GL_MipMap((byte *)out, (byte *)scaled, scaled_width, scaled_height);
486 memcpy(out, scaled, MAX_IMAGE_SIZE * MAX_IMAGE_SIZE * 4);
489 mp->width[miplevel] = scaled_width;
490 mp->height[miplevel] = scaled_height;
491 mp->offsets[miplevel] = pos - ((byte *)(mp));
492 memcpy(pos, out, scaled_width * scaled_height * 4);
493 memcpy(scaled, out, MAX_IMAGE_SIZE * MAX_IMAGE_SIZE * 4);
494 pos += scaled_width * scaled_height * 4;
502 *FinalSize = pos - ((byte *)(mp));
511 $grab filename x y width height
521 GetScriptToken (false);
523 if (token[0] == '/' || token[0] == '\\')
524 sprintf (savename, "%s%s.pcx", gamedir, token+1);
526 sprintf (savename, "%spics/%s.pcx", gamedir, token);
530 if (token[0] == '/' || token[0] == '\\')
531 sprintf (dest, "%s.pcx", token+1);
533 sprintf (dest, "pics/%s.pcx", token);
539 GetScriptToken (false);
541 GetScriptToken (false);
543 GetScriptToken (false);
545 GetScriptToken (false);
548 if (xl<0 || yl<0 || w<0 || h<0 || xl+w>byteimagewidth || yl+h>byteimageheight)
549 Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h);
551 // crop it to the proper size
552 cropped = (byte *) SafeMalloc (w*h, "Cmd_Grab");
553 for (y=0 ; y<h ; y++)
555 memcpy (cropped+y*w, byteimage+(y+yl)*byteimagewidth+xl, w);
558 // save off the new image
559 printf ("saving %s\n", savename);
560 CreatePath (savename);
561 WritePCXfile (savename, cropped, w, h, lbmpalette);
570 $grab filename x y width height
580 GetScriptToken (false);
582 sprintf (savename, "%s%s.lmp", gamedir, token);
586 sprintf (dest, "%s.lmp", token);
591 GetScriptToken (false);
593 GetScriptToken (false);
595 GetScriptToken (false);
597 GetScriptToken (false);
600 if (xl<0 || yl<0 || w<0 || h<0 || xl+w>byteimagewidth || yl+h>byteimageheight)
601 Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h);
603 // crop it to the proper size
604 cropped = (byte *) SafeMalloc (w*h, "Cmd_Raw");
605 for (y=0 ; y<h ; y++)
607 memcpy (cropped+y*w, byteimage+(y+yl)*byteimagewidth+xl, w);
610 // save off the new image
611 printf ("saving %s\n", savename);
612 CreatePath (savename);
614 SaveFile (savename, cropped, w*h);
620 =============================================================================
624 =============================================================================
632 byte BestColor (int r, int g, int b, int start, int stop)
636 int bestdistortion, distortion;
641 // let any color go to 0 as a last resort
643 bestdistortion = 256*256*4;
646 pal = colormap_palette + start*3;
647 for (i=start ; i<= stop ; i++)
649 dr = r - (int)pal[0];
650 dg = g - (int)pal[1];
651 db = b - (int)pal[2];
653 distortion = dr*dr + dg*dg + db*db;
654 if (distortion < bestdistortion)
657 return i; // perfect match
659 bestdistortion = distortion;
674 the brightes colormap is first in the table (FIXME: reverse this now?)
676 64 rows of 256 : lightmaps
677 256 rows of 256 : translucency table
680 void Cmd_Colormap (void)
684 float frac, red, green, blue;
686 byte *cropped, *lump_p;
690 colormap_issued = true;
692 memcpy (colormap_palette, lbmpalette, 768);
694 if (!ScriptTokenAvailable ())
695 { // just setting colormap_issued
699 GetScriptToken (false);
700 sprintf (savename, "%spics/%s.pcx", gamedir, token);
704 sprintf (dest, "pics/%s.pcx", token);
711 brights = 1; // ignore 255 (transparent)
713 cropped = (byte *) SafeMalloc((levels+256)*256, "Cmd_ColorMap");
717 for (l=0;l<levels;l++)
719 frac = range - range*(float)l/(levels-1);
720 for (c=0 ; c<256-brights ; c++)
722 red = lbmpalette[c*3];
723 green = lbmpalette[c*3+1];
724 blue = lbmpalette[c*3+2];
726 red = (int)(red*frac+0.5);
727 green = (int)(green*frac+0.5);
728 blue = (int)(blue*frac+0.5);
731 // note: 254 instead of 255 because 255 is the transparent color, and we
732 // don't want anything remapping to that
733 // don't use color 0, because NT can't remap that (or 255)
735 *lump_p++ = BestColor(red,green,blue, 1, 254);
738 // fullbrights allways stay the same
743 // 66% transparancy table
746 for (c=0 ; c<255 ; c++)
748 red = lbmpalette[c*3]*0.33 + lbmpalette[l*3]*0.66;
749 green = lbmpalette[c*3+1]*0.33 + lbmpalette[l*3+1]*0.66;
750 blue = lbmpalette[c*3+2]*0.33 + lbmpalette[l*3+2]*0.66;
752 *lump_p++ = BestColor(red,green,blue, 1, 254);
756 for (c=0 ; c<256 ; c++)
759 // save off the new image
760 printf ("saving %s\n", savename);
761 CreatePath (savename);
762 WritePCXfile (savename, cropped, 256, levels+256, lbmpalette);
768 =============================================================================
772 =============================================================================
777 int d_red, d_green, d_blue;
779 byte palmap[32][32][32];
780 qboolean palmap_built;
787 int FindColor (int r, int g, int b)
804 bestcolor = BestColor (r, g, b, 0, 254);
806 bestcolor = palmap[r>>3][g>>3][b>>3];
813 void BuildPalmap (void)
823 for (r=4 ; r<256 ; r+=8)
825 for (g=4 ; g<256 ; g+=8)
827 for (b=4 ; b<256 ; b+=8)
829 bestcolor = BestColor (r, g, b, 1, 254);
830 palmap[r>>3][g>>3][b>>3] = bestcolor;
836 if (!colormap_issued)
837 Error ("You must issue a $colormap command first");
846 byte AveragePixels (int count)
859 for (i=0 ; i<count ; i++)
863 r += lbmpalette[pix*3];
864 g += lbmpalette[pix*3+1];
865 b += lbmpalette[pix*3+2];
879 // find the best color
881 bestcolor = FindColor (r, g, b);
884 pal = colormap_palette + bestcolor*3;
885 d_red = r - (int)pal[0];
886 d_green = g - (int)pal[1];
887 d_blue = b - (int)pal[2];
917 mipparm_t mipparms[] =
919 // utility content attributes
920 {"pushpull",CONTENTS_PUSHPULL, pt_contents},
921 {"water", CONTENTS_WATER, pt_contents},
922 {"slime", CONTENTS_SLIME, pt_contents}, // mildly damaging
923 {"lava", CONTENTS_LAVA, pt_contents}, // very damaging
924 {"window", CONTENTS_WINDOW, pt_contents}, // solid, but doesn't eat internal textures
925 {"mist", CONTENTS_MIST, pt_contents}, // non-solid window
926 {"origin", CONTENTS_ORIGIN, pt_contents}, // center of rotating brushes
927 {"playerclip", CONTENTS_PLAYERCLIP, pt_contents},
928 {"monsterclip", CONTENTS_MONSTERCLIP, pt_contents},
930 // utility surface attributes
931 {"hint", SURF_HINT, pt_flags},
932 {"skip", SURF_SKIP, pt_flags},
933 {"light", SURF_LIGHT, pt_flagvalue}, // value is the light quantity
935 {"animspeed",SURF_ANIMSPEED, pt_flagvalue}, // value will hold the anim speed in fps
938 {"anim", 0, pt_animvalue}, // animname is the next animation
939 {"alt", 0, pt_altnamevalue}, // altname is the alternate texture
940 {"damage", 0, pt_damagenamevalue}, // damagename is the damage texture
941 {"scale", 0, pt_scale}, // next two values are for scale
943 {"detail", 0, pt_detail},
945 {"GL_ZERO", GL_ZERO, pt_gl},
946 {"GL_ONE", GL_ONE, pt_gl},
947 {"GL_SRC_COLOR", GL_SRC_COLOR, pt_gl},
948 {"GL_ONE_MINUS_SRC_COLOR", GL_ONE_MINUS_SRC_COLOR, pt_gl},
949 {"GL_DST_COLOR", GL_DST_COLOR, pt_gl},
950 {"GL_ONE_MINUS_DST_COLOR", GL_ONE_MINUS_DST_COLOR, pt_gl},
951 {"GL_SRC_ALPHA", GL_SRC_ALPHA, pt_gl},
952 {"GL_ONE_MINUS_SRC_ALPHA", GL_ONE_MINUS_SRC_ALPHA, pt_gl},
953 {"GL_DST_ALPHA", GL_DST_ALPHA, pt_gl},
954 {"GL_ONE_MINUS_DST_ALPHA", GL_ONE_MINUS_DST_ALPHA, pt_gl},
955 {"GL_SRC_ALPHA_SATURATE", GL_SRC_ALPHA_SATURATE, pt_gl},
958 {"slick", SURF_SLICK, pt_flags},
960 // drawing attributes
961 {"sky", SURF_SKY, pt_flags},
962 {"warping", SURF_WARP, pt_flags}, // only valid with 64x64 textures
963 {"trans33", SURF_TRANS33, pt_flags}, // translucent should allso set fullbright
964 {"trans66", SURF_TRANS66, pt_flags},
965 {"flowing", SURF_FLOWING, pt_flags}, // flow direction towards angle 0
966 {"nodraw", SURF_NODRAW, pt_flags}, // for clip textures and trigger textures
967 {"alpha", SURF_ALPHA_TEXTURE, pt_flags},
968 {"undulate", SURF_UNDULATE, pt_flags}, // rock surface up and down...
969 {"skyreflect", SURF_SKYREFLECT, pt_flags}, // liquid will somewhat reflect the sky - not quite finished....
971 {"material", SURF_MATERIAL, pt_materialvalue},
972 {"metal", SURF_TYPE_METAL, pt_flags},
973 {"stone", SURF_TYPE_STONE, pt_flags},
974 {"wood", SURF_TYPE_WOOD, pt_flags},
976 {"m_nomip", 0, pt_nomip},
977 {"m_detail", 0, pt_detailer},
979 {NULL, 0, pt_contents}
986 $mip filename x y width height <OPTIONS>
987 must be multiples of sixteen
996 int flags, value, contents;
1001 char damagename[128];
1002 byte buffer[MAX_IMAGE_SIZE*MAX_IMAGE_SIZE];
1003 unsigned bufferl[MAX_IMAGE_SIZE*MAX_IMAGE_SIZE];
1004 materialtype_t *mat;
1005 char filename[1024];
1006 unsigned *destl, *sourcel;
1007 int linedelta, x, y;
1011 float scale_x, scale_y;
1015 float dt_scale_x, dt_scale_y;
1018 int dt_src_blend_mode, dt_dst_blend_mode;
1022 GetScriptToken (false);
1023 strcpy (lumpname, token);
1025 GetScriptToken (false);
1027 GetScriptToken (false);
1029 GetScriptToken (false);
1031 GetScriptToken (false);
1038 if ( (w & 15) || (h & 15) )
1039 Error ("line %i: miptex sizes must be multiples of 16", scriptline);
1047 altname[0] = animname[0] = damagename[0] = 0;
1049 scale_x = scale_y = 0.5;
1053 dt_scale_x = dt_scale_y = 0.0;
1056 dt_src_blend_mode = dt_dst_blend_mode = 0;
1058 // get optional flags and values
1059 while (ScriptTokenAvailable ())
1061 GetScriptToken (false);
1063 for (mp=mipparms ; mp->name ; mp++)
1065 if (!strcmp(mp->name, token))
1070 GetScriptToken (false); // specify the next animation frame
1071 strcpy (animname, token);
1073 case pt_altnamevalue:
1074 GetScriptToken (false); // specify the alternate texture
1075 strcpy (altname, token);
1077 case pt_damagenamevalue:
1078 GetScriptToken (false); // specify the damage texture
1079 strcpy (damagename, token);
1085 contents |= mp->flags;
1089 GetScriptToken (false); // specify the light value
1090 value = atoi(token);
1092 case pt_materialvalue:
1093 GetScriptToken(false);
1094 for (mat=materialtypes ; mat->name ; mat++)
1096 if (!strcmp(mat->name, token))
1098 // assumes SURF_MATERIAL is in top 8 bits
1099 flags = (flags & 0x0FFFFFF) | (mat->value << 24);
1105 GetScriptToken (false); // specify the x scale
1106 scale_x = atof(token);
1107 GetScriptToken (false); // specify the y scale
1108 scale_y = atof(token);
1116 flags2 |= MIP32_DETAILER_FLAG2;
1120 flags2 |= MIP32_NOMIP_FLAG2;
1124 GetScriptToken(false);
1125 strcpy(dt_name, token);
1126 GetScriptToken(false);
1127 dt_scale_x = atof(token);
1128 GetScriptToken(false);
1129 dt_scale_y = atof(token);
1130 GetScriptToken(false);
1132 GetScriptToken(false);
1134 GetScriptToken(false);
1135 dt_alpha = atof(token);
1136 GetScriptToken(false);
1137 for (mp=mipparms ; mp->name ; mp++)
1139 if (!strcmp(mp->name, token))
1141 if (mp->type == pt_gl)
1143 dt_src_blend_mode = mp->flags;
1150 Error ("line %i: invalid gl blend mode %s", scriptline, token);
1152 GetScriptToken (false);
1153 for (mp=mipparms ; mp->name ; mp++)
1155 if (!strcmp(mp->name, token))
1157 if (mp->type == pt_gl)
1159 dt_dst_blend_mode = mp->flags;
1166 Error ("line %i: invalid gl blend mode %s", scriptline, token);
1174 Error ("line %i: unknown parm %s", scriptline, token);
1178 return; // textures are only released by $maps
1182 if (xh*yh > MAX_IMAGE_SIZE*MAX_IMAGE_SIZE)
1184 Error("line %i image %s: image is too big!", scriptline, lumpname);
1189 if (xl >= longimagewidth || xh > longimagewidth ||
1190 yl >= longimageheight || yh > longimageheight)
1192 Error ("line %i image %s: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, lumpname, xl,yl,w,h,longimagewidth,longimageheight);
1195 sourcel = longimage + (yl*longimagewidth) + xl;
1197 linedelta = (longimagewidth - w);
1199 for (y=yl ; y<yh ; y++)
1201 for (x=xl ; x<xh ; x++)
1203 *destl++ = *sourcel++; // RGBA
1205 sourcel += linedelta;
1208 qtex32 = CreateMip32(bufferl, w, h, &size, true);
1210 qtex32->flags |= LittleLong(flags);
1211 qtex32->flags2 |= LittleLong(flags2);
1212 qtex32->contents = LittleLong(contents);
1213 qtex32->value = LittleLong(value);
1214 qtex32->scale_x = scale_x;
1215 qtex32->scale_y = scale_y;
1216 qtex32->mip_scale = mip_scale;
1217 sprintf (qtex32->name, "%s/%s", mip_prefix, lumpname);
1220 sprintf (qtex32->animname, "%s/%s", mip_prefix, animname);
1224 sprintf (qtex32->altname, "%s/%s", mip_prefix, altname);
1228 sprintf (qtex32->damagename, "%s/%s", mip_prefix, damagename);
1230 if (dt_name[0] & ((flags2 & MIP32_DETAILER_FLAG2) == 0))
1232 sprintf (qtex32->dt_name, "%s/%s", mip_prefix, dt_name);
1233 qtex32->dt_scale_x = dt_scale_x;
1234 qtex32->dt_scale_y = dt_scale_y;
1235 qtex32->dt_u = dt_u;
1236 qtex32->dt_v = dt_v;
1237 qtex32->dt_alpha = dt_alpha;
1238 qtex32->dt_src_blend_mode = dt_src_blend_mode;
1239 qtex32->dt_dst_blend_mode = dt_dst_blend_mode;
1245 sprintf (filename, "%stextures/%s/%s.m32", g_outputDir, mip_prefix, lumpname);
1246 if(qtex32->flags & (SURF_ALPHA_TEXTURE))
1247 printf ("writing %s with ALPHA\n", filename);
1249 printf ("writing %s\n", filename);
1250 SaveFile (filename, (byte *)qtex32, size);
1256 if (xl >= byteimagewidth || xh > byteimagewidth ||
1257 yl >= byteimageheight || yh > byteimageheight)
1259 Error ("line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight);
1262 source = byteimage + yl*byteimagewidth + xl;
1264 linedelta = byteimagewidth - w;
1266 for (y=yl ; y<yh ; y++)
1268 for (x=xl ; x<xh ; x++)
1270 *dest++ = *source++;
1272 source += linedelta;
1275 qtex = CreateMip(buffer, w, h, lbmpalette, &size, true);
1277 qtex->flags = LittleLong(flags);
1278 qtex->contents = LittleLong(contents);
1279 qtex->value = LittleLong(value);
1280 sprintf (qtex->name, "%s/%s", mip_prefix, lumpname);
1282 sprintf (qtex->animname, "%s/%s", mip_prefix, animname);
1287 sprintf (filename, "%stextures/%s/%s.m8", g_outputDir, mip_prefix, lumpname);
1288 printf ("writing %s\n", filename);
1289 SaveFile (filename, (byte *)qtex, size);
1300 void Cmd_Mippal (void)
1302 colormap_issued = true;
1306 memcpy (colormap_palette, lbmpalette, 768);
1317 void Cmd_Mipdir (void)
1319 char filename[1024];
1321 GetScriptToken (false);
1322 strcpy (mip_prefix, token);
1323 // create the directory if needed
1324 sprintf (filename, "%stextures", g_outputDir);
1326 sprintf (filename, "%stextures/%s", g_outputDir, mip_prefix);
1332 =============================================================================
1334 ENVIRONMENT MAP GRABBING
1336 Creates six pcx files from tga files without any palette edge seams
1337 also copies the tga files for GL rendering.
1338 =============================================================================
1341 // 3dstudio environment map suffixes
1342 char *suf[6] = {"rt", "ft", "lf", "bk", "up", "dn"};
1349 void Cmd_Environment (void)
1353 byte image[256*256];
1356 GetScriptToken (false);
1360 for (i=0 ; i<6 ; i++)
1362 sprintf (name, "env/%s%s.pcx", token, suf[i]);
1364 sprintf (name, "env/%s%s.tga", token, suf[i]);
1372 sprintf (name, "%senv/", gamedir);
1375 // convert the images
1376 for (i=0 ; i<6 ; i++)
1378 sprintf (name, "%senv/%s%s.tga", gamedir, token, suf[i]);
1379 printf ("loading %s...\n", name);
1380 LoadTGA (name, &tga, NULL, NULL);
1382 for (y=0 ; y<256 ; y++)
1384 for (x=0 ; x<256 ; x++)
1386 image[y*256+x] = FindColor (tga[(y*256+x)*4+0],tga[(y*256+x)*4+1],tga[(y*256+x)*4+2]);
1390 sprintf (name, "%senv/%s%s.pcx", gamedir, token, suf[i]);
1391 if (FileTime (name) != -1)
1392 printf ("%s already exists, not overwriting.\n", name);
1394 WritePCXfile (name, image, 256, 256, colormap_palette);