home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 December / PCWKCD1296.iso / sharewar / quake106 / utils / qlumpy / quakegrb.c < prev   
C/C++ Source or Header  |  1996-09-12  |  9KB  |  524 lines

  1. #include "qlumpy.h"
  2.  
  3. typedef struct
  4. {
  5.     short    ofs, length;
  6. } row_t;
  7.  
  8. typedef struct
  9. {
  10.     int        width, height;
  11.     int        widthbits, heightbits;
  12.     unsigned char    data[4];
  13. } qtex_t;
  14.  
  15. typedef struct
  16. {
  17.     int            width, height;
  18.     byte        data[4];            // variably sized
  19. } qpic_t;
  20.  
  21.  
  22. #define SCRN(x,y)       (*(byteimage+(y)*byteimagewidth+x))
  23.  
  24.  
  25. /*
  26. ==============
  27. GrabRaw
  28.  
  29. filename RAW x y width height
  30. ==============
  31. */
  32. void GrabRaw (void)
  33. {
  34.     int             x,y,xl,yl,xh,yh,w,h;
  35.     byte            *screen_p;
  36.     int             linedelta;
  37.  
  38.     GetToken (false);
  39.     xl = atoi (token);
  40.     GetToken (false);
  41.     yl = atoi (token);
  42.     GetToken (false);
  43.     w = atoi (token);
  44.     GetToken (false);
  45.     h = atoi (token);
  46.  
  47.     xh = xl+w;
  48.     yh = yl+h;
  49.  
  50.     screen_p = byteimage + yl*byteimagewidth + xl;
  51.     linedelta = byteimagewidth - w;
  52.  
  53.     for (y=yl ; y<yh ; y++)
  54.     {
  55.         for (x=xl ; x<xh ; x++)
  56.         {
  57.             *lump_p++ = *screen_p;
  58.             *screen_p++ = 0;
  59.         }
  60.         screen_p += linedelta;
  61.     }
  62. }
  63.  
  64.  
  65.  
  66. /*
  67. ==============
  68. GrabPalette
  69.  
  70. filename PALETTE [startcolor endcolor]
  71. ==============
  72. */
  73. void GrabPalette (void)
  74. {
  75.     int             start,end,length;
  76.  
  77.     if (TokenAvailable())
  78.     {
  79.         GetToken (false);
  80.         start = atoi (token);
  81.         GetToken (false);
  82.         end = atoi (token);
  83.     }
  84.     else
  85.     {
  86.         start = 0;
  87.         end = 255;
  88.     }
  89.  
  90.     length = 3*(end-start+1);
  91.     memcpy (lump_p, lbmpalette+start*3, length);
  92.     lump_p += length;
  93. }
  94.  
  95.  
  96. /*
  97. ==============
  98. GrabPic
  99.  
  100. filename qpic x y width height
  101. ==============
  102. */
  103. void GrabPic (void)
  104. {
  105.     int             x,y,xl,yl,xh,yh;
  106.     int             width;
  107.     byte            transcolor;
  108.     qpic_t             *header;
  109.  
  110.     GetToken (false);
  111.     xl = atoi (token);
  112.     GetToken (false);
  113.     yl = atoi (token);
  114.     GetToken (false);
  115.     xh = xl-1+atoi (token);
  116.     GetToken (false);
  117.     yh = yl-1+atoi (token);
  118.  
  119.     if (xh<xl || yh<yl || xl < 0 || yl<0 || xh>319 || yh>199)
  120.         Error ("GrabPic: Bad size: %i, %i, %i, %i",xl,yl,xh,yh);
  121.  
  122.     transcolor = 255;
  123.  
  124.  
  125. //
  126. // fill in header
  127. //
  128.     header = (qpic_t *)lump_p;
  129.     width = xh-xl+1;
  130.     header->width = LittleLong(width);
  131.     header->height = LittleLong(yh-yl+1);
  132.  
  133. //
  134. // start grabbing posts
  135. //
  136.     lump_p = (byte *)header->data;
  137.  
  138.     for (y=yl ; y<= yh ; y++)
  139.         for (x=xl ; x<=xh ; x++)
  140.             *lump_p++ = SCRN(x,y);
  141. }
  142.  
  143. /*
  144. =============================================================================
  145.  
  146. COLORMAP GRABBING
  147.  
  148. =============================================================================
  149. */
  150.  
  151. /*
  152. ===============
  153. BestColor
  154. ===============
  155. */
  156. byte BestColor (int r, int g, int b, int start, int stop)
  157. {
  158.     int    i;
  159.     int    dr, dg, db;
  160.     int    bestdistortion, distortion;
  161.     int    bestcolor;
  162.     byte    *pal;
  163.  
  164. //
  165. // let any color go to 0 as a last resort
  166. //
  167.     bestdistortion = ( (int)r*r + (int)g*g + (int)b*b )*2;
  168.     bestcolor = 0;
  169.  
  170.     pal = lbmpalette + start*3;
  171.     for (i=start ; i<= stop ; i++)
  172.     {
  173.         dr = r - (int)pal[0];
  174.         dg = g - (int)pal[1];
  175.         db = b - (int)pal[2];
  176.         pal += 3;
  177.         distortion = dr*dr + dg*dg + db*db;
  178.         if (distortion < bestdistortion)
  179.         {
  180.             if (!distortion)
  181.                 return i;        // perfect match
  182.  
  183.             bestdistortion = distortion;
  184.             bestcolor = i;
  185.         }
  186.     }
  187.  
  188.     return bestcolor;
  189. }
  190.  
  191.  
  192. /*
  193. ==============
  194. GrabColormap
  195.  
  196. filename COLORMAP levels fullbrights
  197. the first map is an identiy 0-255
  198. the final map is all black except for the fullbrights
  199. the remaining maps are evenly spread
  200. fullbright colors start at the top of the palette.
  201. ==============
  202. */
  203. void GrabColormap (void)
  204. {
  205.     int        levels, brights;
  206.     int        l, c;
  207.     float    frac, red, green, blue;
  208.         
  209.     GetToken (false);
  210.     levels = atoi (token);
  211.     GetToken (false);
  212.     brights = atoi (token);
  213.  
  214. // identity lump
  215.     for (l=0 ; l<256 ; l++)
  216.         *lump_p++ = l;
  217.  
  218. // shaded levels
  219.     for (l=1;l<levels;l++)
  220.     {
  221.         frac = 1.0 - (float)l/(levels-1);
  222.         for (c=0 ; c<256-brights ; c++)
  223.         {
  224.             red = lbmpalette[c*3];
  225.             green = lbmpalette[c*3+1];
  226.             blue = lbmpalette[c*3+2];
  227.  
  228.             red = (int)(red*frac+0.5);
  229.             green = (int)(green*frac+0.5);
  230.             blue = (int)(blue*frac+0.5);
  231.             
  232. //
  233. // note: 254 instead of 255 because 255 is the transparent color, and we
  234. // don't want anything remapping to that
  235. //
  236.             *lump_p++ = BestColor(red,green,blue, 0, 254);
  237.         }
  238.         for ( ; c<256 ; c++)
  239.             *lump_p++ = c;
  240.     }
  241.     
  242.     *lump_p++ = brights;
  243. }
  244.  
  245. /*
  246. ==============
  247. GrabColormap2
  248.  
  249. experimental -- not used by quake
  250.  
  251. filename COLORMAP2 range levels fullbrights
  252. fullbright colors start at the top of the palette.
  253. Range can be greater than 1 to allow overbright color tables.
  254.  
  255. the first map is all 0
  256. the last (levels-1) map is at range
  257. ==============
  258. */
  259. void GrabColormap2 (void)
  260. {
  261.     int        levels, brights;
  262.     int        l, c;
  263.     float    frac, red, green, blue;
  264.     float    range;
  265.     
  266.     GetToken (false);
  267.     range = atof (token);
  268.     GetToken (false);
  269.     levels = atoi (token);
  270.     GetToken (false);
  271.     brights = atoi (token);
  272.  
  273. // shaded levels
  274.     for (l=0;l<levels;l++)
  275.     {
  276.         frac = range - range*(float)l/(levels-1);
  277.         for (c=0 ; c<256-brights ; c++)
  278.         {
  279.             red = lbmpalette[c*3];
  280.             green = lbmpalette[c*3+1];
  281.             blue = lbmpalette[c*3+2];
  282.  
  283.             red = (int)(red*frac+0.5);
  284.             green = (int)(green*frac+0.5);
  285.             blue = (int)(blue*frac+0.5);
  286.             
  287. //
  288. // note: 254 instead of 255 because 255 is the transparent color, and we
  289. // don't want anything remapping to that
  290. //
  291.             *lump_p++ = BestColor(red,green,blue, 0, 254);
  292.         }
  293.  
  294.         // fullbrights allways stay the same
  295.         for ( ; c<256 ; c++)
  296.             *lump_p++ = c;
  297.     }
  298.     
  299.     *lump_p++ = brights;
  300. }
  301.  
  302. /*
  303. =============================================================================
  304.  
  305. MIPTEX GRABBING
  306.  
  307. =============================================================================
  308. */
  309.  
  310. typedef struct
  311. {
  312.     char        name[16];
  313.     unsigned    width, height;
  314.     unsigned    offsets[4];        // four mip maps stored
  315. } miptex_t;
  316.  
  317. byte    pixdata[256];
  318.  
  319. int        d_red, d_green, d_blue;
  320.  
  321. /*
  322. =============
  323. AveragePixels
  324. =============
  325. */
  326. byte AveragePixels (int count)
  327. {
  328.     int        r,g,b;
  329.     int        i;
  330.     int        vis;
  331.     int        pix;
  332.     int        dr, dg, db;
  333.     int        bestdistortion, distortion;
  334.     int        bestcolor;
  335.     byte    *pal;
  336.     int        fullbright;
  337.     int        e;
  338.     
  339.     vis = 0;
  340.     r = g = b = 0;
  341.     fullbright = 0;
  342.     for (i=0 ; i<count ; i++)
  343.     {
  344.         pix = pixdata[i];
  345.         if (pix == 255)
  346.             fullbright = 2;
  347.         else if (pix >= 240)
  348.         {
  349. return pix;
  350.             if (!fullbright)
  351.             {
  352.                 fullbright = true;
  353.                 r = 0;
  354.                 g = 0;
  355.                 b = 0;
  356.             }
  357.         }
  358.         else
  359.         {
  360.             if (fullbright)
  361.                 continue;
  362.         }
  363.         
  364.         r += lbmpalette[pix*3];
  365.         g += lbmpalette[pix*3+1];
  366.         b += lbmpalette[pix*3+2];
  367.         vis++;
  368.     }
  369.     
  370.     if (fullbright == 2)
  371.         return 255;
  372.         
  373.     r /= vis;
  374.     g /= vis;
  375.     b /= vis;
  376.     
  377.     if (!fullbright)
  378.     {
  379.         r += d_red;
  380.         g += d_green;
  381.         b += d_blue;
  382.     }
  383.     
  384. //
  385. // find the best color
  386. //
  387.     bestdistortion = r*r + g*g + b*b;
  388.     bestcolor = 0;
  389.     if (fullbright)
  390.     {
  391.         i = 240;
  392.         e = 255;
  393.     }
  394.     else
  395.     {
  396.         i = 0;
  397.         e = 240;
  398.     }
  399.     
  400.     for ( ; i< e ; i++)
  401.     {
  402.         pix = i;    //pixdata[i];
  403.  
  404.         pal = lbmpalette + pix*3;
  405.  
  406.         dr = r - (int)pal[0];
  407.         dg = g - (int)pal[1];
  408.         db = b - (int)pal[2];
  409.  
  410.         distortion = dr*dr + dg*dg + db*db;
  411.         if (distortion < bestdistortion)
  412.         {
  413.             if (!distortion)
  414.             {
  415.                 d_red = d_green = d_blue = 0;    // no distortion yet
  416.                 return pix;        // perfect match
  417.             }
  418.  
  419.             bestdistortion = distortion;
  420.             bestcolor = pix;
  421.         }
  422.     }
  423.  
  424.     if (!fullbright)
  425.     {    // error diffusion
  426.         pal = lbmpalette + bestcolor*3;
  427.         d_red = r - (int)pal[0];
  428.         d_green = g - (int)pal[1];
  429.         d_blue = b - (int)pal[2];
  430.     }
  431.  
  432.     return bestcolor;
  433. }
  434.  
  435.  
  436. /*
  437. ==============
  438. GrabMip
  439.  
  440. filename MIP x y width height
  441. must be multiples of sixteen
  442. ==============
  443. */
  444. void GrabMip (void)
  445. {
  446.     int             x,y,xl,yl,xh,yh,w,h;
  447.     byte            *screen_p, *source;
  448.     int             linedelta;
  449.     miptex_t        *qtex;
  450.     int                miplevel, mipstep;
  451.     int                xx, yy, pix;
  452.     int                count;
  453.     
  454.     GetToken (false);
  455.     xl = atoi (token);
  456.     GetToken (false);
  457.     yl = atoi (token);
  458.     GetToken (false);
  459.     w = atoi (token);
  460.     GetToken (false);
  461.     h = atoi (token);
  462.  
  463.     if ( (w & 15) || (h & 15) )
  464.         Error ("line %i: miptex sizes must be multiples of 16", scriptline);
  465.  
  466.     xh = xl+w;
  467.     yh = yl+h;
  468.  
  469.     qtex = (miptex_t *)lump_p;
  470.     qtex->width = LittleLong(w);
  471.     qtex->height = LittleLong(h);
  472.     strcpy (qtex->name, lumpname); 
  473.     
  474.     lump_p = (byte *)&qtex->offsets[4];
  475.     
  476.     screen_p = byteimage + yl*byteimagewidth + xl;
  477.     linedelta = byteimagewidth - w;
  478.  
  479.     source = lump_p;
  480.     qtex->offsets[0] = LittleLong(lump_p - (byte *)qtex);
  481.  
  482.     for (y=yl ; y<yh ; y++)
  483.     {
  484.         for (x=xl ; x<xh ; x++)
  485.         {
  486.             pix = *screen_p;
  487.             *screen_p++ = 0;
  488.             if (pix == 255)
  489.                 pix = 0;
  490.             *lump_p++ = pix;
  491.         }
  492.         screen_p += linedelta;
  493.     }
  494.     
  495. //
  496. // subsample for greater mip levels
  497. //
  498.     d_red = d_green = d_blue = 0;    // no distortion yet
  499.  
  500.     for (miplevel = 1 ; miplevel<4 ; miplevel++)
  501.     {
  502.         qtex->offsets[miplevel] = LittleLong(lump_p - (byte *)qtex);
  503.         
  504.         mipstep = 1<<miplevel;
  505.         for (y=0 ; y<h ; y+=mipstep)
  506.         {
  507.  
  508.             for (x = 0 ; x<w ; x+= mipstep)
  509.             {
  510.                 count = 0;
  511.                 for (yy=0 ; yy<mipstep ; yy++)
  512.                     for (xx=0 ; xx<mipstep ; xx++)
  513.                     {
  514.                         pixdata[count] = source[ (y+yy)*w + x + xx ];
  515.                         count++;
  516.                     }
  517.                 *lump_p++ = AveragePixels (count);
  518.             }    
  519.         }
  520.     }
  521.  
  522.  
  523. }
  524.