123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- #include "qlumpy.h"
- typedef struct
- {
- short ofs, length;
- } row_t;
- typedef struct
- {
- int width, height;
- int widthbits, heightbits;
- unsigned char data[4];
- } qtex_t;
- typedef struct
- {
- int width, height;
- byte data[4]; // variably sized
- } qpic_t;
- #define SCRN(x,y) (*(byteimage+(y)*byteimagewidth+x))
- /*
- ==============
- GrabRaw
- filename RAW x y width height
- ==============
- */
- void GrabRaw (void)
- {
- int x,y,xl,yl,xh,yh,w,h;
- byte *screen_p;
- int linedelta;
- GetToken (false);
- xl = atoi (token);
- GetToken (false);
- yl = atoi (token);
- GetToken (false);
- w = atoi (token);
- GetToken (false);
- h = atoi (token);
- xh = xl+w;
- yh = yl+h;
- screen_p = byteimage + yl*byteimagewidth + xl;
- linedelta = byteimagewidth - w;
- for (y=yl ; y<yh ; y++)
- {
- for (x=xl ; x<xh ; x++)
- {
- *lump_p++ = *screen_p;
- *screen_p++ = 0;
- }
- screen_p += linedelta;
- }
- }
- /*
- ==============
- GrabPalette
- filename PALETTE [startcolor endcolor]
- ==============
- */
- void GrabPalette (void)
- {
- int start,end,length;
- if (TokenAvailable())
- {
- GetToken (false);
- start = atoi (token);
- GetToken (false);
- end = atoi (token);
- }
- else
- {
- start = 0;
- end = 255;
- }
- length = 3*(end-start+1);
- memcpy (lump_p, lbmpalette+start*3, length);
- lump_p += length;
- }
- /*
- ==============
- GrabPic
- filename qpic x y width height
- ==============
- */
- void GrabPic (void)
- {
- int x,y,xl,yl,xh,yh;
- int width;
- byte transcolor;
- qpic_t *header;
- GetToken (false);
- xl = atoi (token);
- GetToken (false);
- yl = atoi (token);
- GetToken (false);
- xh = xl-1+atoi (token);
- GetToken (false);
- yh = yl-1+atoi (token);
- if (xh<xl || yh<yl || xl < 0 || yl<0 || xh>319 || yh>199)
- Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,xh,yh);
- transcolor = 255;
- //
- // fill in header
- //
- header = (qpic_t *)lump_p;
- width = xh-xl+1;
- header->width = LittleLong(width);
- header->height = LittleLong(yh-yl+1);
- //
- // start grabbing posts
- //
- lump_p = (byte *)header->data;
- for (y=yl ; y<= yh ; y++)
- for (x=xl ; x<=xh ; x++)
- *lump_p++ = SCRN(x,y);
- }
- /*
- =============================================================================
- COLORMAP GRABBING
- =============================================================================
- */
- /*
- ===============
- BestColor
- ===============
- */
- byte BestColor (int r, int g, int b, int start, int stop)
- {
- int i;
- int dr, dg, db;
- int bestdistortion, distortion;
- int bestcolor;
- byte *pal;
- //
- // let any color go to 0 as a last resort
- //
- bestdistortion = ( (int)r*r + (int)g*g + (int)b*b )*2;
- bestcolor = 0;
- pal = lbmpalette + start*3;
- for (i=start ; i<= stop ; i++)
- {
- dr = r - (int)pal[0];
- dg = g - (int)pal[1];
- db = b - (int)pal[2];
- pal += 3;
- distortion = dr*dr + dg*dg + db*db;
- if (distortion < bestdistortion)
- {
- if (!distortion)
- return i; // perfect match
- bestdistortion = distortion;
- bestcolor = i;
- }
- }
- return bestcolor;
- }
- /*
- ==============
- GrabColormap
- filename COLORMAP levels fullbrights
- the first map is an identiy 0-255
- the final map is all black except for the fullbrights
- the remaining maps are evenly spread
- fullbright colors start at the top of the palette.
- ==============
- */
- void GrabColormap (void)
- {
- int levels, brights;
- int l, c;
- float frac, red, green, blue;
-
- GetToken (false);
- levels = atoi (token);
- GetToken (false);
- brights = atoi (token);
- // identity lump
- for (l=0 ; l<256 ; l++)
- *lump_p++ = l;
- // shaded levels
- for (l=1;l<levels;l++)
- {
- frac = 1.0 - (float)l/(levels-1);
- for (c=0 ; c<256-brights ; c++)
- {
- red = lbmpalette[c*3];
- green = lbmpalette[c*3+1];
- blue = lbmpalette[c*3+2];
- red = (int)(red*frac+0.5);
- green = (int)(green*frac+0.5);
- blue = (int)(blue*frac+0.5);
-
- //
- // note: 254 instead of 255 because 255 is the transparent color, and we
- // don't want anything remapping to that
- //
- *lump_p++ = BestColor(red,green,blue, 0, 254);
- }
- for ( ; c<256 ; c++)
- *lump_p++ = c;
- }
-
- *lump_p++ = brights;
- }
- /*
- ==============
- GrabColormap2
- experimental -- not used by quake
- filename COLORMAP2 range levels fullbrights
- fullbright colors start at the top of the palette.
- Range can be greater than 1 to allow overbright color tables.
- the first map is all 0
- the last (levels-1) map is at range
- ==============
- */
- void GrabColormap2 (void)
- {
- int levels, brights;
- int l, c;
- float frac, red, green, blue;
- float range;
-
- GetToken (false);
- range = atof (token);
- GetToken (false);
- levels = atoi (token);
- GetToken (false);
- brights = atoi (token);
- // shaded levels
- for (l=0;l<levels;l++)
- {
- frac = range - range*(float)l/(levels-1);
- for (c=0 ; c<256-brights ; c++)
- {
- red = lbmpalette[c*3];
- green = lbmpalette[c*3+1];
- blue = lbmpalette[c*3+2];
- red = (int)(red*frac+0.5);
- green = (int)(green*frac+0.5);
- blue = (int)(blue*frac+0.5);
-
- //
- // note: 254 instead of 255 because 255 is the transparent color, and we
- // don't want anything remapping to that
- //
- *lump_p++ = BestColor(red,green,blue, 0, 254);
- }
- // fullbrights allways stay the same
- for ( ; c<256 ; c++)
- *lump_p++ = c;
- }
-
- *lump_p++ = brights;
- }
- /*
- =============================================================================
- MIPTEX GRABBING
- =============================================================================
- */
- typedef struct
- {
- char name[16];
- unsigned width, height;
- unsigned offsets[4]; // four mip maps stored
- } miptex_t;
- byte pixdata[256];
- int d_red, d_green, d_blue;
- /*
- =============
- AveragePixels
- =============
- */
- byte AveragePixels (int count)
- {
- int r,g,b;
- int i;
- int vis;
- int pix;
- int dr, dg, db;
- int bestdistortion, distortion;
- int bestcolor;
- byte *pal;
- int fullbright;
- int e;
-
- vis = 0;
- r = g = b = 0;
- fullbright = 0;
- for (i=0 ; i<count ; i++)
- {
- pix = pixdata[i];
- if (pix == 255)
- fullbright = 2;
- else if (pix >= 240)
- {
- return pix;
- if (!fullbright)
- {
- fullbright = true;
- r = 0;
- g = 0;
- b = 0;
- }
- }
- else
- {
- if (fullbright)
- continue;
- }
-
- r += lbmpalette[pix*3];
- g += lbmpalette[pix*3+1];
- b += lbmpalette[pix*3+2];
- vis++;
- }
-
- if (fullbright == 2)
- return 255;
-
- r /= vis;
- g /= vis;
- b /= vis;
-
- if (!fullbright)
- {
- r += d_red;
- g += d_green;
- b += d_blue;
- }
-
- //
- // find the best color
- //
- bestdistortion = r*r + g*g + b*b;
- bestcolor = 0;
- if (fullbright)
- {
- i = 240;
- e = 255;
- }
- else
- {
- i = 0;
- e = 240;
- }
-
- for ( ; i< e ; i++)
- {
- pix = i; //pixdata[i];
- pal = lbmpalette + pix*3;
- dr = r - (int)pal[0];
- dg = g - (int)pal[1];
- db = b - (int)pal[2];
- distortion = dr*dr + dg*dg + db*db;
- if (distortion < bestdistortion)
- {
- if (!distortion)
- {
- d_red = d_green = d_blue = 0; // no distortion yet
- return pix; // perfect match
- }
- bestdistortion = distortion;
- bestcolor = pix;
- }
- }
- if (!fullbright)
- { // error diffusion
- pal = lbmpalette + bestcolor*3;
- d_red = r - (int)pal[0];
- d_green = g - (int)pal[1];
- d_blue = b - (int)pal[2];
- }
- return bestcolor;
- }
- /*
- ==============
- GrabMip
- filename MIP x y width height
- must be multiples of sixteen
- ==============
- */
- void GrabMip (void)
- {
- int x,y,xl,yl,xh,yh,w,h;
- byte *screen_p, *source;
- int linedelta;
- miptex_t *qtex;
- int miplevel, mipstep;
- int xx, yy, pix;
- int count;
-
- GetToken (false);
- xl = atoi (token);
- GetToken (false);
- yl = atoi (token);
- GetToken (false);
- w = atoi (token);
- GetToken (false);
- h = atoi (token);
- if ( (w & 15) || (h & 15) )
- Error ("line %i: miptex sizes must be multiples of 16", scriptline);
- xh = xl+w;
- yh = yl+h;
- qtex = (miptex_t *)lump_p;
- qtex->width = LittleLong(w);
- qtex->height = LittleLong(h);
- strcpy (qtex->name, lumpname);
-
- lump_p = (byte *)&qtex->offsets[4];
-
- screen_p = byteimage + yl*byteimagewidth + xl;
- linedelta = byteimagewidth - w;
- source = lump_p;
- qtex->offsets[0] = LittleLong(lump_p - (byte *)qtex);
- for (y=yl ; y<yh ; y++)
- {
- for (x=xl ; x<xh ; x++)
- {
- pix = *screen_p;
- *screen_p++ = 0;
- if (pix == 255)
- pix = 0;
- *lump_p++ = pix;
- }
- screen_p += linedelta;
- }
-
- //
- // subsample for greater mip levels
- //
- d_red = d_green = d_blue = 0; // no distortion yet
- for (miplevel = 1 ; miplevel<4 ; miplevel++)
- {
- qtex->offsets[miplevel] = LittleLong(lump_p - (byte *)qtex);
-
- mipstep = 1<<miplevel;
- for (y=0 ; y<h ; y+=mipstep)
- {
- for (x = 0 ; x<w ; x+= mipstep)
- {
- count = 0;
- for (yy=0 ; yy<mipstep ; yy++)
- for (xx=0 ; xx<mipstep ; xx++)
- {
- pixdata[count] = source[ (y+yy)*w + x + xx ];
- count++;
- }
- *lump_p++ = AveragePixels (count);
- }
- }
- }
- }
|