home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / client / r_surf.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  14.4 KB  |  662 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.           blocklights[t*smax + s] += (rad - dist)*256;
  120.       }
  121.     }
  122.   }
  123. }
  124.  
  125. /*
  126. ===============
  127. R_BuildLightMap
  128.  
  129. Combine and scale multiple lightmaps into the 8.8 format in blocklights
  130. ===============
  131. */
  132. void R_BuildLightMap (void)
  133. {
  134.   int     smax, tmax;
  135.   int     t;
  136.   int     i, size;
  137.   byte    *lightmap;
  138.   unsigned  scale;
  139.   int     maps;
  140.   msurface_t  *surf;
  141.  
  142.   surf = r_drawsurf.surf;
  143.  
  144.   smax = (surf->extents[0]>>4)+1;
  145.   tmax = (surf->extents[1]>>4)+1;
  146.   size = smax*tmax;
  147.   lightmap = surf->samples;
  148.  
  149.   if (/* r_fullbright.value || */ !cl.worldmodel->lightdata)
  150.   {
  151.     for (i=0 ; i<size ; i++)
  152.       blocklights[i] = 0;
  153.     return;
  154.   }
  155.  
  156. // clear to ambient
  157.   for (i=0 ; i<size ; i++)
  158.     blocklights[i] = r_refdef.ambientlight<<8;
  159.  
  160.  
  161. // add all the lightmaps
  162.   if (lightmap)
  163.     for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
  164.        maps++)
  165.     {
  166.       scale = r_drawsurf.lightadj[maps];  // 8.8 fraction   
  167.       for (i=0 ; i<size ; i++)
  168.         blocklights[i] += lightmap[i] * scale;
  169.       lightmap += size; // skip to next lightmap
  170.     }
  171.  
  172. // add all the dynamic lights
  173.   if (surf->dlightframe == r_framecount)
  174.     R_AddDynamicLights ();
  175.  
  176. // bound, invert, and shift
  177.   for (i=0 ; i<size ; i++)
  178.   {
  179.     t = (255*256 - (int)blocklights[i]) >> (8 - VID_CBITS);
  180.  
  181.     if (t < (1 << 6))
  182.       t = (1 << 6);
  183.  
  184.     blocklights[i] = t;
  185.   }
  186. }
  187.  
  188.  
  189. /*
  190. ===============
  191. R_TextureAnimation
  192.  
  193. Returns the proper texture for a given time and base texture
  194. ===============
  195. */
  196. texture_t *R_TextureAnimation (texture_t *base)
  197. {
  198.   int   reletive;
  199.   int   count;
  200.  
  201.   if (currententity->frame)
  202.   {
  203.     if (base->alternate_anims)
  204.       base = base->alternate_anims;
  205.   }
  206.   
  207.   if (!base->anim_total)
  208.     return base;
  209.  
  210.   reletive = (int)(cl.time*10) % base->anim_total;
  211.  
  212.   count = 0;  
  213.   while (base->anim_min > reletive || base->anim_max <= reletive)
  214.   {
  215.     base = base->anim_next;
  216.     if (!base)
  217.       Sys_Error ("R_TextureAnimation: broken cycle");
  218.     if (++count > 100)
  219.       Sys_Error ("R_TextureAnimation: infinite cycle");
  220.   }
  221.  
  222.   return base;
  223. }
  224.  
  225.  
  226. /*
  227. ===============
  228. R_DrawSurface
  229. ===============
  230. */
  231. void R_DrawSurface (void)
  232. {
  233.   unsigned char *basetptr;
  234.   int       smax, tmax, twidth;
  235.   int       u;
  236.   int       soffset, basetoffset, texwidth;
  237.   int       horzblockstep;
  238.   unsigned char *pcolumndest;
  239.   void      (*pblockdrawer)(void);
  240.   texture_t   *mt;
  241.  
  242. // calculate the lightings
  243.   R_BuildLightMap ();
  244.   
  245.   surfrowbytes = r_drawsurf.rowbytes;
  246.  
  247.   mt = r_drawsurf.texture;
  248.   
  249.   r_source = (byte *)mt + mt->offsets[r_drawsurf.surfmip];
  250.   
  251. // the fractional light values should range from 0 to (VID_GRADES - 1) << 16
  252. // from a source range of 0 - 255
  253.   
  254.   texwidth = mt->width >> r_drawsurf.surfmip;
  255.  
  256.   blocksize = 16 >> r_drawsurf.surfmip;
  257.   blockdivshift = 4 - r_drawsurf.surfmip;
  258.   blockdivmask = (1 << blockdivshift) - 1;
  259.   
  260.   r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1;
  261.  
  262.   r_numhblocks = r_drawsurf.surfwidth >> blockdivshift;
  263.   r_numvblocks = r_drawsurf.surfheight >> blockdivshift;
  264.  
  265. //==============================
  266.  
  267.   if (r_pixbytes == 1)
  268.   {
  269.     pblockdrawer = surfmiptable[r_drawsurf.surfmip];
  270.   // TODO: only needs to be set when there is a display settings change
  271.     horzblockstep = blocksize;
  272.   }
  273.   else
  274.   {
  275.     pblockdrawer = R_DrawSurfaceBlock16;
  276.   // TODO: only needs to be set when there is a display settings change
  277.     horzblockstep = blocksize << 1;
  278.   }
  279.  
  280.   smax = mt->width >> r_drawsurf.surfmip;
  281.   twidth = texwidth;
  282.   tmax = mt->height >> r_drawsurf.surfmip;
  283.   sourcetstep = texwidth;
  284.   r_stepback = tmax * twidth;
  285.  
  286.   r_sourcemax = r_source + (tmax * smax);
  287.  
  288.   soffset = r_drawsurf.surf->texturemins[0];
  289.   basetoffset = r_drawsurf.surf->texturemins[1];
  290.  
  291. // << 16 components are to guarantee positive values for %
  292.   soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax;
  293.   basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip) 
  294.     + (tmax << 16)) % tmax) * twidth)];
  295.  
  296.   pcolumndest = r_drawsurf.surfdat;
  297.  
  298.   for (u=0 ; u<r_numhblocks; u++)
  299.   {
  300.     r_lightptr = blocklights + u;
  301.  
  302.     prowdestbase = pcolumndest;
  303.  
  304.     pbasesource = basetptr + soffset;
  305.  
  306.     (*pblockdrawer)();
  307.  
  308.     soffset = soffset + blocksize;
  309.     if (soffset >= smax)
  310.       soffset = 0;
  311.  
  312.     pcolumndest += horzblockstep;
  313.   }
  314. }
  315.  
  316.  
  317. //=============================================================================
  318.  
  319. #if !id386 && !defined(M68KASM) && !defined(PPCASM)
  320. /*
  321. ================
  322. R_DrawSurfaceBlock8_mip0
  323. ================
  324. */
  325. void R_DrawSurfaceBlock8_mip0 (void)
  326. {
  327.   int       v, i, b, lightstep, lighttemp, light;
  328.   unsigned char pix, *psource, *prowdest;
  329.  
  330.   psource = pbasesource;
  331.   prowdest = prowdestbase;
  332.  
  333.   for (v=0 ; v<r_numvblocks ; v++)
  334.   {
  335.   // FIXME: make these locals?
  336.   // FIXME: use delta rather than both right and left, like ASM?
  337.     lightleft = r_lightptr[0];
  338.     lightright = r_lightptr[1];
  339.     r_lightptr += r_lightwidth;
  340.     lightleftstep = (r_lightptr[0] - lightleft) >> 4;
  341.     lightrightstep = (r_lightptr[1] - lightright) >> 4;
  342.  
  343.     for (i=0 ; i<16 ; i++)
  344.     {
  345.       lighttemp = lightleft - lightright;
  346.       lightstep = lighttemp >> 4;
  347.  
  348.       light = lightright;
  349.  
  350.       for (b=15; b>=0; b--)
  351.       {
  352.         pix = psource[b];
  353.         prowdest[b] = ((unsigned char *)vid.colormap)
  354.             [(light & 0xFF00) + pix];
  355.         light += lightstep;
  356.       }
  357.   
  358.       psource += sourcetstep;
  359.       lightright += lightrightstep;
  360.       lightleft += lightleftstep;
  361.       prowdest += surfrowbytes;
  362.     }
  363.  
  364.     if (psource >= r_sourcemax)
  365.       psource -= r_stepback;
  366.   }
  367. }
  368.  
  369.  
  370. /*
  371. ================
  372. R_DrawSurfaceBlock8_mip1
  373. ================
  374. */
  375. void R_DrawSurfaceBlock8_mip1 (void)
  376. {
  377.   int       v, i, b, lightstep, lighttemp, light;
  378.   unsigned char pix, *psource, *prowdest;
  379.  
  380.   psource = pbasesource;
  381.   prowdest = prowdestbase;
  382.  
  383.   for (v=0 ; v<r_numvblocks ; v++)
  384.   {
  385.   // FIXME: make these locals?
  386.   // FIXME: use delta rather than both right and left, like ASM?
  387.     lightleft = r_lightptr[0];
  388.     lightright = r_lightptr[1];
  389.     r_lightptr += r_lightwidth;
  390.     lightleftstep = (r_lightptr[0] - lightleft) >> 3;
  391.     lightrightstep = (r_lightptr[1] - lightright) >> 3;
  392.  
  393.     for (i=0 ; i<8 ; i++)
  394.     {
  395.       lighttemp = lightleft - lightright;
  396.       lightstep = lighttemp >> 3;
  397.  
  398.       light = lightright;
  399.  
  400.       for (b=7; b>=0; b--)
  401.       {
  402.         pix = psource[b];
  403.         prowdest[b] = ((unsigned char *)vid.colormap)
  404.             [(light & 0xFF00) + pix];
  405.         light += lightstep;
  406.       }
  407.   
  408.       psource += sourcetstep;
  409.       lightright += lightrightstep;
  410.       lightleft += lightleftstep;
  411.       prowdest += surfrowbytes;
  412.     }
  413.  
  414.     if (psource >= r_sourcemax)
  415.       psource -= r_stepback;
  416.   }
  417. }
  418.  
  419.  
  420. /*
  421. ================
  422. R_DrawSurfaceBlock8_mip2
  423. ================
  424. */
  425. void R_DrawSurfaceBlock8_mip2 (void)
  426. {
  427.   int       v, i, b, lightstep, lighttemp, light;
  428.   unsigned char pix, *psource, *prowdest;
  429.  
  430.   psource = pbasesource;
  431.   prowdest = prowdestbase;
  432.  
  433.   for (v=0 ; v<r_numvblocks ; v++)
  434.   {
  435.   // FIXME: make these locals?
  436.   // FIXME: use delta rather than both right and left, like ASM?
  437.     lightleft = r_lightptr[0];
  438.     lightright = r_lightptr[1];
  439.     r_lightptr += r_lightwidth;
  440.     lightleftstep = (r_lightptr[0] - lightleft) >> 2;
  441.     lightrightstep = (r_lightptr[1] - lightright) >> 2;
  442.  
  443.     for (i=0 ; i<4 ; i++)
  444.     {
  445.       lighttemp = lightleft - lightright;
  446.       lightstep = lighttemp >> 2;
  447.  
  448.       light = lightright;
  449.  
  450.       for (b=3; b>=0; b--)
  451.       {
  452.         pix = psource[b];
  453.         prowdest[b] = ((unsigned char *)vid.colormap)
  454.             [(light & 0xFF00) + pix];
  455.         light += lightstep;
  456.       }
  457.   
  458.       psource += sourcetstep;
  459.       lightright += lightrightstep;
  460.       lightleft += lightleftstep;
  461.       prowdest += surfrowbytes;
  462.     }
  463.  
  464.     if (psource >= r_sourcemax)
  465.       psource -= r_stepback;
  466.   }
  467. }
  468.  
  469.  
  470. /*
  471. ================
  472. R_DrawSurfaceBlock8_mip3
  473. ================
  474. */
  475. void R_DrawSurfaceBlock8_mip3 (void)
  476. {
  477.   int       v, i, b, lightstep, lighttemp, light;
  478.   unsigned char pix, *psource, *prowdest;
  479.  
  480.   psource = pbasesource;
  481.   prowdest = prowdestbase;
  482.  
  483.   for (v=0 ; v<r_numvblocks ; v++)
  484.   {
  485.   // FIXME: make these locals?
  486.   // FIXME: use delta rather than both right and left, like ASM?
  487.     lightleft = r_lightptr[0];
  488.     lightright = r_lightptr[1];
  489.     r_lightptr += r_lightwidth;
  490.     lightleftstep = (r_lightptr[0] - lightleft) >> 1;
  491.     lightrightstep = (r_lightptr[1] - lightright) >> 1;
  492.  
  493.     for (i=0 ; i<2 ; i++)
  494.     {
  495.       lighttemp = lightleft - lightright;
  496.       lightstep = lighttemp >> 1;
  497.  
  498.       light = lightright;
  499.  
  500.       for (b=1; b>=0; b--)
  501.       {
  502.         pix = psource[b];
  503.         prowdest[b] = ((unsigned char *)vid.colormap)
  504.             [(light & 0xFF00) + pix];
  505.         light += lightstep;
  506.       }
  507.   
  508.       psource += sourcetstep;
  509.       lightright += lightrightstep;
  510.       lightleft += lightleftstep;
  511.       prowdest += surfrowbytes;
  512.     }
  513.  
  514.     if (psource >= r_sourcemax)
  515.       psource -= r_stepback;
  516.   }
  517. }
  518. #endif
  519.  
  520.  
  521. #if !id386
  522. /*
  523. ================
  524. R_DrawSurfaceBlock16
  525.  
  526. FIXME: make this work
  527. ================
  528. */
  529. void R_DrawSurfaceBlock16 (void)
  530. {
  531.   int       k;
  532.   unsigned char *psource;
  533.   int       lighttemp, lightstep, light;
  534.   unsigned short  *prowdest;
  535.  
  536.   prowdest = (unsigned short *)prowdestbase;
  537.  
  538.   for (k=0 ; k<blocksize ; k++)
  539.   {
  540.     unsigned short  *pdest;
  541.     unsigned char pix;
  542.     int       b;
  543.  
  544.     psource = pbasesource;
  545.     lighttemp = lightright - lightleft;
  546.     lightstep = lighttemp >> blockdivshift;
  547.  
  548.     light = lightleft;
  549.     pdest = prowdest;
  550.  
  551.     for (b=0; b<blocksize; b++)
  552.     {
  553.       pix = *psource;
  554.       *pdest = vid.colormap16[(light & 0xFF00) + pix];
  555.       psource += sourcesstep;
  556.       pdest++;
  557.       light += lightstep;
  558.     }
  559.  
  560.     pbasesource += sourcetstep;
  561.     lightright += lightrightstep;
  562.     lightleft += lightleftstep;
  563.     prowdest = (unsigned short *)((long)prowdest + surfrowbytes);
  564.   }
  565.  
  566.   prowdestbase = prowdest;
  567. }
  568. #endif
  569.  
  570.  
  571. //============================================================================
  572.  
  573. /*
  574. ================
  575. R_GenTurbTile
  576. ================
  577. */
  578. void R_GenTurbTile (pixel_t *pbasetex, void *pdest)
  579. {
  580.   int   *turb;
  581.   int   i, j, s, t;
  582.   byte  *pd;
  583.   
  584.   turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  585.   pd = (byte *)pdest;
  586.  
  587.   for (i=0 ; i<TILE_SIZE ; i++)
  588.   {
  589.     for (j=0 ; j<TILE_SIZE ; j++)
  590.     { 
  591.       s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
  592.       t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
  593.       *pd++ = *(pbasetex + (t<<6) + s);
  594.     }
  595.   }
  596. }
  597.  
  598.  
  599. /*
  600. ================
  601. R_GenTurbTile16
  602. ================
  603. */
  604. void R_GenTurbTile16 (pixel_t *pbasetex, void *pdest)
  605. {
  606.   int       *turb;
  607.   int       i, j, s, t;
  608.   unsigned short  *pd;
  609.  
  610.   turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  611.   pd = (unsigned short *)pdest;
  612.  
  613.   for (i=0 ; i<TILE_SIZE ; i++)
  614.   {
  615.     for (j=0 ; j<TILE_SIZE ; j++)
  616.     { 
  617.       s = (((j << 16) + turb[i & (CYCLE-1)]) >> 16) & 63;
  618.       t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63;
  619.       *pd++ = d_8to16table[*(pbasetex + (t<<6) + s)];
  620.     }
  621.   }
  622. }
  623.  
  624.  
  625. /*
  626. ================
  627. R_GenTile
  628. ================
  629. */
  630. void R_GenTile (msurface_t *psurf, void *pdest)
  631. {
  632.   if (psurf->flags & SURF_DRAWTURB)
  633.   {
  634.     if (r_pixbytes == 1)
  635.     {
  636.       R_GenTurbTile ((pixel_t *)
  637.         ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
  638.     }
  639.     else
  640.     {
  641.       R_GenTurbTile16 ((pixel_t *)
  642.         ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest);
  643.     }
  644.   }
  645.   else if (psurf->flags & SURF_DRAWSKY)
  646.   {
  647.     if (r_pixbytes == 1)
  648.     {
  649.       R_GenSkyTile (pdest);
  650.     }
  651.     else
  652.     {
  653.       R_GenSkyTile16 (pdest);
  654.     }
  655.   }
  656.   else
  657.   {
  658.     Sys_Error ("Unknown tile type");
  659.   }
  660. }
  661.  
  662.