home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / r_surf.c.orig < prev    next >
Text File  |  2000-06-17  |  15KB  |  679 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // r_surf.c: surface-related refresh code
  21.  
  22. #include "quakedef.h"
  23. #include "r_local.h"
  24.  
  25. drawsurf_t  r_drawsurf;
  26.  
  27. int       lightleft, sourcesstep, blocksize, sourcetstep;
  28. int       lightdelta, lightdeltastep;
  29. int       lightright, lightleftstep, lightrightstep, blockdivshift;
  30. unsigned    blockdivmask;
  31. void      *prowdestbase;
  32. unsigned char *pbasesource;
  33. int       surfrowbytes; // used by ASM files
  34. unsigned    *r_lightptr;
  35. int       r_stepback;
  36. int       r_lightwidth;
  37. int       r_numhblocks, r_numvblocks;
  38. unsigned char *r_source, *r_sourcemax;
  39.  
  40. void R_DrawSurfaceBlock8_mip0 (void);
  41. void R_DrawSurfaceBlock8_mip1 (void);
  42. void R_DrawSurfaceBlock8_mip2 (void);
  43. void R_DrawSurfaceBlock8_mip3 (void);
  44.  
  45. static void (*surfmiptable[4])(void) = {
  46.   R_DrawSurfaceBlock8_mip0,
  47.   R_DrawSurfaceBlock8_mip1,
  48.   R_DrawSurfaceBlock8_mip2,
  49.   R_DrawSurfaceBlock8_mip3
  50. };
  51.  
  52.  
  53.  
  54. unsigned    blocklights[18*18];
  55.  
  56. /*
  57. ===============
  58. R_AddDynamicLights
  59. ===============
  60. */
  61. void R_AddDynamicLights (void)
  62. {
  63.   msurface_t *surf;
  64.   int     lnum;
  65.   int     sd, td;
  66.   float   dist, rad, minlight;
  67.   vec3_t    impact, local;
  68.   int     s, t;
  69.   int     i;
  70.   int     smax, tmax;
  71.   mtexinfo_t  *tex;
  72.  
  73.   surf = r_drawsurf.surf;
  74.   smax = (surf->extents[0]>>4)+1;
  75.   tmax = (surf->extents[1]>>4)+1;
  76.   tex = surf->texinfo;
  77.  
  78.   for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
  79.   {
  80.     if ( !(surf->dlightbits & (1<<lnum) ) )
  81.       continue;   // not lit by this light
  82.  
  83.     rad = cl_dlights[lnum].radius;
  84.     dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) -
  85.         surf->plane->dist;
  86.     rad -= fabs(dist);
  87.     minlight = cl_dlights[lnum].minlight;
  88.     if (rad < minlight)
  89.       continue;
  90.     minlight = rad - minlight;
  91.  
  92.     for (i=0 ; i<3 ; i++)
  93.     {
  94.       impact[i] = cl_dlights[lnum].origin[i] -
  95.           surf->plane->normal[i]*dist;
  96.     }
  97.  
  98.     local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
  99.     local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
  100.  
  101.     local[0] -= surf->texturemins[0];
  102.     local[1] -= surf->texturemins[1];
  103.     
  104.     for (t = 0 ; t<tmax ; t++)
  105.     {
  106.       td = local[1] - t*16;
  107.       if (td < 0)
  108.         td = -td;
  109.       for (s=0 ; s<smax ; s++)
  110.       {
  111.         sd = local[0] - s*16;
  112.         if (sd < 0)
  113.           sd = -sd;
  114.         if (sd > td)
  115.           dist = sd + (td>>1);
  116.         else
  117.           dist = td + (sd>>1);
  118.         if (dist < minlight)
  119. #ifdef QUAKE2
  120.         {
  121.           unsigned temp;
  122.           temp = (rad - dist)*256;
  123.           i = t*smax + s;
  124.           if (!cl_dlights[lnum].dark)
  125.             blocklights[i] += temp;
  126.           else
  127.           {
  128.             if (blocklights[i] > temp)
  129.               blocklights[i] -= temp;
  130.             else
  131.               blocklights[i] = 0;
  132.           }
  133.         }
  134. #else
  135.           blocklights[t*smax + s] += (rad - dist)*256;
  136. #endif
  137.       }
  138.     }
  139.   }
  140. }
  141.  
  142. /*
  143. ===============
  144. R_BuildLightMap
  145.  
  146. Combine and scale multiple lightmaps into the 8.8 format in blocklights
  147. ===============
  148. */
  149. void R_BuildLightMap (void)
  150. {
  151.   int     smax, tmax;
  152.   int     t;
  153.   int     i, size;
  154.   byte    *lightmap;
  155.   unsigned  scale;
  156.   int     maps;
  157.   msurface_t  *surf;
  158.  
  159.   surf = r_drawsurf.surf;
  160.  
  161.   smax = (surf->extents[0]>>4)+1;
  162.   tmax = (surf->extents[1]>>4)+1;
  163.   size = smax*tmax;
  164.   lightmap = surf->samples;
  165.  
  166.   if (r_fullbright.value || !cl.worldmodel->lightdata)
  167.   {
  168.     for (i=0 ; i<size ; i++)
  169.       blocklights[i] = 0;
  170.     return;
  171.   }
  172.  
  173. // clear to ambient
  174.   for (i=0 ; i<size ; i++)
  175.     blocklights[i] = r_refdef.ambientlight<<8;
  176.  
  177.  
  178. // add all the lightmaps
  179.   if (lightmap)
  180.     for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
  181.        maps++)
  182.     {
  183.       scale = r_drawsurf.lightadj[maps];  // 8.8 fraction   
  184.       for (i=0 ; i<size ; i++)
  185.         blocklights[i] += lightmap[i] * scale;
  186.       lightmap += size; // skip to next lightmap
  187.     }
  188.  
  189. // add all the dynamic lights
  190.   if (surf->dlightframe == r_framecount)
  191.     R_AddDynamicLights ();
  192.  
  193. // bound, invert, and shift
  194.   for (i=0 ; i<size ; i++)
  195.   {
  196.     t = (255*256 - (int)blocklights[i]) >> (8 - VID_CBITS);
  197.  
  198.     if (t < (1 << 6))
  199.       t = (1 << 6);
  200.  
  201.     blocklights[i] = t;
  202.   }
  203. }
  204.  
  205.  
  206. /*
  207. ===============
  208. R_TextureAnimation
  209.  
  210. Returns the proper texture for a given time and base texture
  211. ===============
  212. */
  213. texture_t *R_TextureAnimation (texture_t *base)
  214. {
  215.   int   reletive;
  216.   int   count;
  217.  
  218.   if (currententity->frame)
  219.   {
  220.     if (base->alternate_anims)
  221.       base = base->alternate_anims;
  222.   }
  223.   
  224.   if (!base->anim_total)
  225.     return base;
  226.  
  227.   reletive = (int)(cl.time*10) % base->anim_total;
  228.  
  229.   count = 0;  
  230.   while (base->anim_min > reletive || base->anim_max <= reletive)
  231.   {
  232.     base = base->anim_next;
  233.     if (!base)
  234.       Sys_Error ("R_TextureAnimation: broken cycle");
  235.     if (++count > 100)
  236.       Sys_Error ("R_TextureAnimation: infinite cycle");
  237.   }
  238.  
  239.   return base;
  240. }
  241.  
  242.  
  243. /*
  244. ===============
  245. R_DrawSurface
  246. ===============
  247. */
  248. void R_DrawSurface (void)
  249. {
  250.   unsigned char *basetptr;
  251.   int       smax, tmax, twidth;
  252.   int       u;
  253.   int       soffset, basetoffset, texwidth;
  254.   int       horzblockstep;
  255.   unsigned char *pcolumndest;
  256.   void      (*pblockdrawer)(void);
  257.   texture_t   *mt;
  258.  
  259. // calculate the lightings
  260.   R_BuildLightMap ();
  261.   
  262.   surfrowbytes = r_drawsurf.rowbytes;
  263.  
  264.   mt = r_drawsurf.texture;
  265.   
  266.   r_source = (byte *)mt + mt->offsets[r_drawsurf.surfmip];
  267.   
  268. // the fractional light values should range from 0 to (VID_GRADES - 1) << 16
  269. // from a source range of 0 - 255
  270.   
  271.   texwidth = mt->width >> r_drawsurf.surfmip;
  272.  
  273.   blocksize = 16 >> r_drawsurf.surfmip;
  274.   blockdivshift = 4 - r_drawsurf.surfmip;
  275.   blockdivmask = (1 << blockdivshift) - 1;
  276.   
  277.   r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1;
  278.  
  279.   r_numhblocks = r_drawsurf.surfwidth >> blockdivshift;
  280.   r_numvblocks = r_drawsurf.surfheight >> blockdivshift;
  281.  
  282. //==============================
  283.  
  284.   if (r_pixbytes == 1)
  285.   {
  286.     pblockdrawer = surfmiptable[r_drawsurf.surfmip];
  287.   // TODO: only needs to be set when there is a display settings change
  288.     horzblockstep = blocksize;
  289.   }
  290.   else
  291.   {
  292.     pblockdrawer = R_DrawSurfaceBlock16;
  293.   // TODO: only needs to be set when there is a display settings change
  294.     horzblockstep = blocksize << 1;
  295.   }
  296.  
  297.   smax = mt->width >> r_drawsurf.surfmip;
  298.   twidth = texwidth;
  299.   tmax = mt->height >> r_drawsurf.surfmip;
  300.   sourcetstep = texwidth;
  301.   r_stepback = tmax * twidth;
  302.  
  303.   r_sourcemax = r_source + (tmax * smax);
  304.  
  305.   soffset = r_drawsurf.surf->texturemins[0];
  306.   basetoffset = r_drawsurf.surf->texturemins[1];
  307.  
  308. // << 16 components are to guarantee positive values for %
  309.   soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax;
  310.   basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip) 
  311.     + (tmax << 16)) % tmax) * twidth)];
  312.  
  313.   pcolumndest = r_drawsurf.surfdat;
  314.  
  315.   for (u=0 ; u<r_numhblocks; u++)
  316.   {
  317.     r_lightptr = blocklights + u;
  318.  
  319.     prowdestbase = pcolumndest;
  320.  
  321.     pbasesource = basetptr + soffset;
  322.  
  323.     (*pblockdrawer)();
  324.  
  325.     soffset = soffset + blocksize;
  326.     if (soffset >= smax)
  327.       soffset = 0;
  328.  
  329.     pcolumndest += horzblockstep;
  330.   }
  331. }
  332.  
  333.  
  334. //=============================================================================
  335.  
  336. #if !id386
  337.  
  338. /*
  339. ================
  340. R_DrawSurfaceBlock8_mip0
  341. ================
  342. */
  343. void R_DrawSurfaceBlock8_mip0 (void)
  344. {
  345.   int       v, i, b, lightstep, lighttemp, light;
  346.   unsigned char pix, *psource, *prowdest;
  347.  
  348.   psource = pbasesource;
  349.   prowdest = prowdestbase;
  350.  
  351.   for (v=0 ; v<r_numvblocks ; v++)
  352.   {
  353.   // FIXME: make these locals?
  354.   // FIXME: use delta rather than both right and left, like ASM?
  355.     lightleft = r_lightptr[0];
  356.     lightright = r_lightptr[1];
  357.     r_lightptr += r_lightwidth;
  358.     lightleftstep = (r_lightptr[0] - lightleft) >> 4;
  359.     lightrightstep = (r_lightptr[1] - lightright) >> 4;
  360.  
  361.     for (i=0 ; i<16 ; i++)
  362.     {
  363.       lighttemp = lightleft - lightright;
  364.       lightstep = lighttemp >> 4;
  365.  
  366.       light = lightright;
  367.  
  368.       for (b=15; b>=0; b--)
  369.       {
  370.         pix = psource[b];
  371.         prowdest[b] = ((unsigned char *)vid.colormap)
  372.             [(light & 0xFF00) + pix];
  373.         light += lightstep;
  374.       }
  375.   
  376.       psource += sourcetstep;
  377.       lightright += lightrightstep;
  378.       lightleft += lightleftstep;
  379.       prowdest += surfrowbytes;
  380.     }
  381.  
  382.     if (psource >= r_sourcemax)
  383.       psource -= r_stepback;
  384.   }
  385. }
  386.  
  387.  
  388. /*
  389. ================
  390. R_DrawSurfaceBlock8_mip1
  391. ================
  392. */
  393. void R_DrawSurfaceBlock8_mip1 (void)
  394. {
  395.   int       v, i, b, lightstep, lighttemp, light;
  396.   unsigned char pix, *psource, *prowdest;
  397.  
  398.   psource = pbasesource;
  399.   prowdest = prowdestbase;
  400.  
  401.   for (v=0 ; v<r_numvblocks ; v++)
  402.   {
  403.   // FIXME: make these locals?
  404.   // FIXME: use delta rather than both right and left, like ASM?
  405.     lightleft = r_lightptr[0];
  406.     lightright = r_lightptr[1];
  407.     r_lightptr += r_lightwidth;
  408.     lightleftstep = (r_lightptr[0] - lightleft) >> 3;
  409.     lightrightstep = (r_lightptr[1] - lightright) >> 3;
  410.  
  411.     for (i=0 ; i<8 ; i++)
  412.     {
  413.       lighttemp = lightleft - lightright;
  414.       lightstep = lighttemp >> 3;
  415.  
  416.       light = lightright;
  417.  
  418.       for (b=7; b>=0; b--)
  419.       {
  420.         pix = psource[b];
  421.         prowdest[b] = ((unsigned char *)vid.colormap)
  422.             [(light & 0xFF00) + pix];
  423.         light += lightstep;
  424.       }
  425.   
  426.       psource += sourcetstep;
  427.       lightright += lightrightstep;
  428.       lightleft += lightleftstep;
  429.       prowdest += surfrowbytes;
  430.     }
  431.  
  432.     if (psource >= r_sourcemax)
  433.       psource -= r_stepback;
  434.   }
  435. }
  436.  
  437.  
  438. /*
  439. ================
  440. R_DrawSurfaceBlock8_mip2
  441. ================
  442. */
  443. void R_DrawSurfaceBlock8_mip2 (void)
  444. {
  445.   int       v, i, b, lightstep, lighttemp, light;
  446.   unsigned char pix, *psource, *prowdest;
  447.  
  448.   psource = pbasesource;
  449.   prowdest = prowdestbase;
  450.  
  451.   for (v=0 ; v<r_numvblocks ; v++)
  452.   {
  453.   // FIXME: make these locals?
  454.   // FIXME: use delta rather than both right and left, like ASM?
  455.     lightleft = r_lightptr[0];
  456.     lightright = r_lightptr[1];
  457.     r_lightptr += r_lightwidth;
  458.     lightleftstep = (r_lightptr[0] - lightleft) >> 2;
  459.     lightrightstep = (r_lightptr[1] - lightright) >> 2;
  460.  
  461.     for (i=0 ; i<4 ; i++)
  462.     {
  463.       lighttemp = lightleft - lightright;
  464.       lightstep = lighttemp >> 2;
  465.  
  466.       light = lightright;
  467.  
  468.       for (b=3; b>=0; b--)
  469.       {
  470.         pix = psource[b];
  471.         prowdest[b] = ((unsigned char *)vid.colormap)
  472.             [(light & 0xFF00) + pix];
  473.         light += lightstep;
  474.       }
  475.   
  476.       psource += sourcetstep;
  477.       lightright += lightrightstep;
  478.       lightleft += lightleftstep;
  479.       prowdest += surfrowbytes;
  480.     }
  481.  
  482.     if (psource >= r_sourcemax)
  483.       psource -= r_stepback;
  484.   }
  485. }
  486.  
  487.  
  488. /*
  489. ================
  490. R_DrawSurfaceBlock8_mip3
  491. ================
  492. */
  493. void R_DrawSurfaceBlock8_mip3 (void)
  494. {
  495.   int       v, i, b, lightstep, lighttemp, light;
  496.   unsigned char pix, *psource, *prowdest;
  497.  
  498.   psource = pbasesource;
  499.   prowdest = prowdestbase;
  500.  
  501.   for (v=0 ; v<r_numvblocks ; v++)
  502.   {
  503.   // FIXME: make these locals?
  504.   // FIXME: use delta rather than both right and left, like ASM?
  505.     lightleft = r_lightptr[0];
  506.     lightright = r_lightptr[1];
  507.     r_lightptr += r_lightwidth;
  508.     lightleftstep = (r_lightptr[0] - lightleft) >> 1;
  509.     lightrightstep = (r_lightptr[1] - lightright) >> 1;
  510.  
  511.     for (i=0 ; i<2 ; i++)
  512.     {
  513.       lighttemp = lightleft - lightright;
  514.       lightstep = lighttemp >> 1;
  515.  
  516.       light = lightright;
  517.  
  518.       for (b=1; b>=0; b--)
  519.       {
  520.         pix = psource[b];
  521.         prowdest[b] = ((unsigned char *)vid.colormap)
  522.             [(light & 0xFF00) + pix];
  523.         light += lightstep;
  524.       }
  525.   
  526.       psource += sourcetstep;
  527.       lightright += lightrightstep;
  528.       lightleft += lightleftstep;
  529.       prowdest += surfrowbytes;
  530.     }
  531.  
  532.     if (psource >= r_sourcemax)
  533.       psource -= r_stepback;
  534.   }
  535. }
  536.  
  537.  
  538. /*
  539. ================
  540. R_DrawSurfaceBlock16
  541.  
  542. FIXME: make this work
  543. ================
  544. */
  545. void R_DrawSurfaceBlock16 (void)
  546. {
  547.   int       k;
  548.   unsigned char *psource;
  549.   int       lighttemp, lightstep, light;
  550.   unsigned short  *prowdest;
  551.  
  552.   prowdest = (unsigned short *)prowdestbase;
  553.  
  554.   for (k=0 ; k<blocksize ; k++)
  555.   {
  556.     unsigned short  *pdest;
  557.     unsigned char pix;
  558.     int       b;
  559.  
  560.     psource = pbasesource;
  561.     lighttemp = lightright - lightleft;
  562.     lightstep = lighttemp >> blockdivshift;
  563.  
  564.     light = lightleft;
  565.     pdest = prowdest;
  566.  
  567.     for (b=0; b<blocksize; b++)
  568.     {
  569.       pix = *psource;
  570.       *pdest = vid.colormap16[(light & 0xFF00) + pix];
  571.       psource += sourcesstep;
  572.       pdest++;
  573.       light += lightstep;
  574.     }
  575.  
  576.     pbasesource += sourcetstep;
  577.     lightright += lightrightstep;
  578.     lightleft += lightleftstep;
  579.     prowdest = (unsigned short *)((long)prowdest + surfrowbytes);
  580.   }
  581.  
  582.   prowdestbase = prowdest;
  583. }
  584.  
  585. #endif
  586.  
  587.  
  588. //============================================================================
  589.  
  590. /*
  591. ================
  592. R_GenTurbTile
  593. ================
  594. */
  595. void R_GenTurbTile (pixel_t *pbasetex, void *pdest)
  596. {
  597.   int   *turb;
  598.   int   i, j, s, t;
  599.   byte  *pd;
  600.   
  601.   turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  602.   pd = (byte *)pdest;
  603.  
  604.   for (i=0 ; i<TILE_SIZE ; i++)
  605.   {
  606.     for (j=0 ; j<TILE_SIZE ; j++)
  607.     { 
  608.       s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
  609.       t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
  610.       *pd++ = *(pbasetex + (t<<6) + s);
  611.     }
  612.   }
  613. }
  614.  
  615.  
  616. /*
  617. ================
  618. R_GenTurbTile16
  619. ================
  620. */
  621. void R_GenTurbTile16 (pixel_t *pbasetex, void *pdest)
  622. {
  623.   int       *turb;
  624.   int       i, j, s, t;
  625.   unsigned short  *pd;
  626.  
  627.   turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  628.   pd = (unsigned short *)pdest;
  629.  
  630.   for (i=0 ; i<TILE_SIZE ; i++)
  631.   {
  632.     for (j=0 ; j<TILE_SIZE ; j++)
  633.     { 
  634.       s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
  635.       t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
  636.       *pd++ = d_8to16table[*(pbasetex + (t<<6) + s)];
  637.     }
  638.   }
  639. }
  640.  
  641.  
  642. /*
  643. ================
  644. R_GenTile
  645. ================
  646. */
  647. void R_GenTile (msurface_t *psurf, void *pdest)
  648. {
  649.   if (psurf->flags & SURF_DRAWTURB)
  650.   {
  651.     if (r_pixbytes == 1)
  652.     {
  653.       R_GenTurbTile ((pixel_t *)
  654.         ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
  655.     }
  656.     else
  657.     {
  658.       R_GenTurbTile16 ((pixel_t *)
  659.         ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
  660.     }
  661.   }
  662.   else if (psurf->flags & SURF_DRAWSKY)
  663.   {
  664.     if (r_pixbytes == 1)
  665.     {
  666.       R_GenSkyTile (pdest);
  667.     }
  668.     else
  669.     {
  670.       R_GenSkyTile16 (pdest);
  671.     }
  672.   }
  673.   else
  674.   {
  675.     Sys_Error ("Unknown tile type");
  676.   }
  677. }
  678.  
  679.