/*** * * Copyright (c) 1996-2002, Valve LLC. All rights reserved. * * This product contains software technology licensed from Id * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * All Rights Reserved. * ****/ #include "qlumpy.h" #include "math.h" #pragma warning (disable : 4244) 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; // Font stuff #define NUM_GLYPHS 256 const unsigned kFontMarker = 254; typedef struct { short startoffset; short charwidth; } charinfo; typedef struct { int width, height; int rowcount; int rowheight; charinfo fontinfo[ NUM_GLYPHS ]; byte data[4]; } qfont_t; extern qboolean fTransparent255; #define SCRN(x,y) (*(byteimage+(y)*byteimagewidth+x)) void GrabPalette16( void ); extern qboolean do16bit; /* ============== 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); if (xl == -1) { xl = yl = 0; w = byteimagewidth; h = byteimageheight; } xh = xl+w; yh = yl+h; screen_p = byteimage + yl*byteimagewidth + xl; linedelta = byteimagewidth - w; for (y=yl ; y319 || yh>239) Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,xh,yh); // // fill in header // header = (qpic_t *)lump_p; width = xh-xl; header->width = LittleLong(width); header->height = LittleLong(yh-yl); // // start grabbing posts // lump_p = (byte *)header->data; for (y=yl ; y< yh ; y++) for (x=xl ; x 1.0) r = 1.0; lbmpalette[i*3+0] = pow( r, 1.0 / 2.2) * 255; if (g < 0) g = 0.0; if (g > 1.0) g = 1.0; lbmpalette[i*3+1] = pow( g, 1.0 / 2.2) * 255; if (b < 0) b = 0.0; if (b > 1.0) b = 1.0; lbmpalette[i*3+2] = pow( b, 1.0 / 2.2) * 255; color_used[i] = 1; colors_used++; return i; } } return 0; } /* ============= AveragePixels ============= */ byte AveragePixels (int count) { float r,g,b; int i; int vis; int pix; float dr, dg, db; float bestdistortion, distortion; int bestcolor; byte *pal; vis = 0; r = g = b = 0; for (i=0 ; i 0.001 && colors_used < 255) { // printf("%f %f %f\n", r, g, b ); bestcolor = AddColor( r, g, b ); d_red = d_green = d_blue = 0; bestdistortion = 0; } else { // error diffusion d_red = r - linearpalette[bestcolor][0]; d_green = g - linearpalette[bestcolor][1]; d_blue = b - linearpalette[bestcolor][2]; } if (bestdistortion > maxdistortion) maxdistortion = bestdistortion; return bestcolor; } /* ============== GrabMip filename MIP x y width height must be multiples of sixteen ============== */ void GrabMip (void) { int i,j,x,y,xl,yl,xh,yh,w,h; byte *screen_p, *source, testpixel; 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 (xl == -1) { xl = yl = 0; w = byteimagewidth; h = byteimageheight; } 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 ; yoffsets[miplevel] = LittleLong(lump_p - (byte *)qtex); mipstep = 1<width = header->rowheight = atoi( token ); //mwh why does width equal rowheight? header->height = 1; lump_p = (byte *)header->data; pCur = (byte *)lump_p; memset( lump_p, 0xFF, 256 * 160); GetToken( false ); index = atoi( token ); while( index != -1 ) { // Get/Process source bitmap coordinates GetToken (false); xl = atoi (token); GetToken (false); yl = atoi (token); GetToken (false); xh = xl-1+atoi (token); GetToken (false); yh = atoi (token) - 1; if (xl == -1) { xl = yl = 0; xh = byteimagewidth; yh = byteimageheight; } if( xhrowheight+1 ) { // Make sure we're at a marker if( y != yl ) { for( y2=y-header->rowheight; y2= NUM_GLYPHS ) { printf( "GrabFont: Glyph out of range\n" ); goto getout; } // Fill in glyph info header->fontinfo[ index ].charwidth = x2 - x - 1; // update header // output glyph data iCurX += header->fontinfo[index].charwidth; // Will this glyph fit on this row? if (iCurX >= iMaxX) { // Nope -- move to next row pCur = (byte *)lump_p + 256 * header->rowheight * header->height; header->height++; iCurX = header->fontinfo[index].charwidth; } // copy over the glyph bytes pbuf = pCur; header->fontinfo[ index ].startoffset = pCur - (byte *) header->data; for(j = 1; j <= header->rowheight; j++) { byte *psrc = byteimage + (y + j) * byteimagewidth + (x + 1); for(i = x + 1; i < x2; i++) *pbuf++ = *psrc++; pbuf = pCur + j * 256; } // move the lump pointer to point at the next possible glyph pCur += header->fontinfo[index].charwidth; x = x2; index++; } } // Get next ASCII index getout: GetToken (false); index = atoi (token); } // advance the lump pointer so that the last row is saved. lump_p += (256 * header->rowheight) * header->height; // JAY: Round up to the next power of 2 for GL offset = header->height * header->rowheight; y = (offset>128)?256:(offset>64)?128:(offset>32)?64:(offset>16)?32:16; if ( offset != y ) { printf("Rounding font from 256x%d to 256x%d\n", offset, y ); lump_p += (256 * (y - offset)); } header->rowcount = header->height; header->height = y; if( do16bit ) GrabPalette16(); }