home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / client / d_edge.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  8.3 KB  |  345 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. // d_edge.c
  21.  
  22. #include "quakedef.h"
  23. #include "d_local.h"
  24.  
  25. #if !defined(M68KASM) && !defined(PPCASM)
  26. static int miplevel;
  27. #else
  28. int miplevel;
  29. #endif
  30.  
  31. float   scale_for_mip;
  32. int     screenwidth;
  33. int     ubasestep, errorterm, erroradjustup, erroradjustdown;
  34. int     vstartscan;
  35.  
  36. // FIXME: should go away
  37. extern void     R_RotateBmodel (void);
  38. extern void     R_TransformFrustum (void);
  39. #if defined(M68KASM) || defined(PPCASM)
  40. extern void D_CalcGradients(msurface_t *);
  41. #endif
  42.  
  43. vec3_t    transformed_modelorg;
  44.  
  45. /*
  46. ==============
  47. D_DrawPoly
  48.  
  49. ==============
  50. */
  51. void D_DrawPoly (void)
  52. {
  53. // this driver takes spans, not polygons
  54. }
  55.  
  56.  
  57. /*
  58. =============
  59. D_MipLevelForScale
  60. =============
  61. */
  62. int D_MipLevelForScale (float scale)
  63. {
  64.   int   lmiplevel;
  65.  
  66.   if (scale >= d_scalemip[0] )
  67.     lmiplevel = 0;
  68.   else if (scale >= d_scalemip[1] )
  69.     lmiplevel = 1;
  70.   else if (scale >= d_scalemip[2] )
  71.     lmiplevel = 2;
  72.   else
  73.     lmiplevel = 3;
  74.  
  75.   if (lmiplevel < d_minmip)
  76.     lmiplevel = d_minmip;
  77.  
  78.   return lmiplevel;
  79. }
  80.  
  81.  
  82. /*
  83. ==============
  84. D_DrawSolidSurface
  85. ==============
  86. */
  87.  
  88. // FIXME: clean this up
  89.  
  90. void D_DrawSolidSurface (surf_t *surf, int color)
  91. {
  92.   espan_t *span;
  93.   byte  *pdest;
  94.   int   u, u2, pix;
  95.   
  96.   pix = (color<<24) | (color<<16) | (color<<8) | color;
  97.   for (span=surf->spans ; span ; span=span->pnext)
  98.   {
  99.     pdest = (byte *)d_viewbuffer + screenwidth*span->v;
  100.     u = span->u;
  101.     u2 = span->u + span->count - 1;
  102.     ((byte *)pdest)[u] = pix;
  103.  
  104.     if (u2 - u < 8)
  105.     {
  106.       for (u++ ; u <= u2 ; u++)
  107.         ((byte *)pdest)[u] = pix;
  108.     }
  109.     else
  110.     {
  111.       for (u++ ; u & 3 ; u++)
  112.         ((byte *)pdest)[u] = pix;
  113.  
  114.       u2 -= 4;
  115.       for ( ; u <= u2 ; u+=4)
  116.         *(int *)((byte *)pdest + u) = pix;
  117.       u2 += 4;
  118.       for ( ; u <= u2 ; u++)
  119.         ((byte *)pdest)[u] = pix;
  120.     }
  121.   }
  122. }
  123.  
  124.  
  125. #if !defined(M68KASM) && !defined(PPCASM)
  126. /*
  127. ==============
  128. D_CalcGradients
  129. ==============
  130. */
  131. void D_CalcGradients (msurface_t *pface)
  132. {
  133.   mplane_t  *pplane;
  134.   float   mipscale;
  135.   vec3_t    p_temp1;
  136.   vec3_t    p_saxis, p_taxis;
  137.   float   t;
  138.  
  139.   pplane = pface->plane;
  140.  
  141.   mipscale = 1.0 / (float)(1 << miplevel);
  142.  
  143.   TransformVector (pface->texinfo->vecs[0], p_saxis);
  144.   TransformVector (pface->texinfo->vecs[1], p_taxis);
  145.  
  146.   t = xscaleinv * mipscale;
  147.   d_sdivzstepu = p_saxis[0] * t;
  148.   d_tdivzstepu = p_taxis[0] * t;
  149.  
  150.   t = yscaleinv * mipscale;
  151.   d_sdivzstepv = -p_saxis[1] * t;
  152.   d_tdivzstepv = -p_taxis[1] * t;
  153.  
  154.   d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
  155.       ycenter * d_sdivzstepv;
  156.   d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
  157.       ycenter * d_tdivzstepv;
  158.  
  159.   VectorScale (transformed_modelorg, mipscale, p_temp1);
  160.  
  161.   t = 0x10000*mipscale;
  162.   sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
  163.       ((pface->texturemins[0] << 16) >> miplevel)
  164.       + pface->texinfo->vecs[0][3]*t;
  165.   tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
  166.       ((pface->texturemins[1] << 16) >> miplevel)
  167.       + pface->texinfo->vecs[1][3]*t;
  168.  
  169. //
  170. // -1 (-epsilon) so we never wander off the edge of the texture
  171. //
  172.   bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
  173.   bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
  174. }
  175.  
  176.  
  177. /*
  178. ==============
  179. D_DrawSurfaces
  180. ==============
  181. */
  182. void D_DrawSurfaces (void)
  183. {
  184.   surf_t      *s;
  185.   msurface_t    *pface;
  186.   surfcache_t   *pcurrentcache;
  187.   vec3_t      world_transformed_modelorg;
  188.   vec3_t      local_modelorg;
  189.  
  190.   currententity = &r_worldentity;
  191.   TransformVector (modelorg, transformed_modelorg);
  192.   VectorCopy (transformed_modelorg, world_transformed_modelorg);
  193.  
  194. // TODO: could preset a lot of this at mode set time
  195.   if (r_drawflat.value)
  196.   {
  197.     for (s = &surfaces[1] ; s<surface_p ; s++)
  198.     {
  199.       if (!s->spans)
  200.         continue;
  201.  
  202.       d_zistepu = s->d_zistepu;
  203.       d_zistepv = s->d_zistepv;
  204.       d_ziorigin = s->d_ziorigin;
  205.  
  206. #ifdef __alpha__
  207.       D_DrawSolidSurface (s, (int)((long)s->data & 0xFF));
  208. #else
  209.       D_DrawSolidSurface (s, (int)s->data & 0xFF);
  210. #endif
  211.       D_DrawZSpans (s->spans);
  212.     }
  213.   }
  214.   else
  215.   {
  216.     for (s = &surfaces[1] ; s<surface_p ; s++)
  217.     {
  218.       if (!s->spans)
  219.         continue;
  220.  
  221.       r_drawnpolycount++;
  222.  
  223.       d_zistepu = s->d_zistepu;
  224.       d_zistepv = s->d_zistepv;
  225.       d_ziorigin = s->d_ziorigin;
  226.  
  227.       if (s->flags & SURF_DRAWSKY)
  228.       {
  229.         if (!r_skymade)
  230.         {
  231.           R_MakeSky ();
  232.         }
  233.  
  234.         D_DrawSkyScans8 (s->spans);
  235.         D_DrawZSpans (s->spans);
  236.       }
  237.       else if (s->flags & SURF_DRAWBACKGROUND)
  238.       {
  239.       // set up a gradient for the background surface that places it
  240.       // effectively at infinity distance from the viewpoint
  241.         d_zistepu = 0;
  242.         d_zistepv = 0;
  243.         d_ziorigin = -0.9;
  244.  
  245.         D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
  246.         D_DrawZSpans (s->spans);
  247.       }
  248.       else if (s->flags & SURF_DRAWTURB)
  249.       {
  250.         pface = s->data;
  251.         miplevel = 0;
  252.         cacheblock = (pixel_t *)
  253.             ((byte *)pface->texinfo->texture +
  254.             pface->texinfo->texture->offsets[0]);
  255.         cachewidth = 64;
  256.  
  257.         if (s->insubmodel)
  258.         {
  259.         // FIXME: we don't want to do all this for every polygon!
  260.         // TODO: store once at start of frame
  261.           currententity = s->entity;  //FIXME: make this passed in to
  262.                         // R_RotateBmodel ()
  263.           VectorSubtract (r_origin, currententity->origin,
  264.               local_modelorg);
  265.           TransformVector (local_modelorg, transformed_modelorg);
  266.  
  267.           R_RotateBmodel ();  // FIXME: don't mess with the frustum,
  268.                     // make entity passed in
  269.         }
  270.  
  271.         D_CalcGradients (pface);
  272.  
  273.         Turbulent8 (s->spans);
  274.         D_DrawZSpans (s->spans);
  275.  
  276.         if (s->insubmodel)
  277.         {
  278.         //
  279.         // restore the old drawing state
  280.         // FIXME: we don't want to do this every time!
  281.         // TODO: speed up
  282.         //
  283.           currententity = &r_worldentity;
  284.           VectorCopy (world_transformed_modelorg,
  285.                 transformed_modelorg);
  286.           VectorCopy (base_vpn, vpn);
  287.           VectorCopy (base_vup, vup);
  288.           VectorCopy (base_vright, vright);
  289.           VectorCopy (base_modelorg, modelorg);
  290.           R_TransformFrustum ();
  291.         }
  292.       }
  293.       else
  294.       {
  295.         if (s->insubmodel)
  296.         {
  297.         // FIXME: we don't want to do all this for every polygon!
  298.         // TODO: store once at start of frame
  299.           currententity = s->entity;  //FIXME: make this passed in to
  300.                         // R_RotateBmodel ()
  301.           VectorSubtract (r_origin, currententity->origin, local_modelorg);
  302.           TransformVector (local_modelorg, transformed_modelorg);
  303.  
  304.           R_RotateBmodel ();  // FIXME: don't mess with the frustum,
  305.                     // make entity passed in
  306.         }
  307.  
  308.         pface = s->data;
  309.         miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
  310.         * pface->texinfo->mipadjust);
  311.  
  312.       // FIXME: make this passed in to D_CacheSurface
  313.         pcurrentcache = D_CacheSurface (pface, miplevel);
  314.  
  315.         cacheblock = (pixel_t *)pcurrentcache->data;
  316.         cachewidth = pcurrentcache->width;
  317.  
  318.         D_CalcGradients (pface);
  319.  
  320.         (*d_drawspans) (s->spans);
  321.  
  322.         D_DrawZSpans (s->spans);
  323.  
  324.         if (s->insubmodel)
  325.         {
  326.         //
  327.         // restore the old drawing state
  328.         // FIXME: we don't want to do this every time!
  329.         // TODO: speed up
  330.         //
  331.           VectorCopy (world_transformed_modelorg,
  332.                 transformed_modelorg);
  333.           VectorCopy (base_vpn, vpn);
  334.           VectorCopy (base_vup, vup);
  335.           VectorCopy (base_vright, vright);
  336.           VectorCopy (base_modelorg, modelorg);
  337.           R_TransformFrustum ();
  338.           currententity = &r_worldentity;
  339.         }
  340.       }
  341.     }
  342.   }
  343. }
  344. #endif
  345.