home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / d_scan.c < prev    next >
C/C++ Source or Header  |  2000-06-17  |  12KB  |  445 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_scan.c
  21. //
  22. // Portable C scan-level rasterization code, all pixel depths.
  23.  
  24. #include "quakedef.h"
  25. #include "r_local.h"
  26. #include "d_local.h"
  27.  
  28. unsigned char *r_turb_pbase, *r_turb_pdest;
  29. fixed16_t   r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
  30. int       *r_turb_turb;
  31. int       r_turb_spancount;
  32.  
  33. void D_DrawTurbulent8Span (void);
  34.  
  35.  
  36. #if !defined(M68KASM) && !defined(PPCASM)
  37. /*
  38. =============
  39. D_WarpScreen
  40.  
  41. // this performs a slight compression of the screen at the same time as
  42. // the sine warp, to keep the edges from wrapping
  43. =============
  44. */
  45. void D_WarpScreen (void)
  46. {
  47.   int   w, h;
  48.   int   u,v;
  49.   byte  *dest;
  50.   int   *turb;
  51.   int   *col;
  52.   byte  **row;
  53.   static byte  *rowptr[MAXHEIGHT+(AMP2*2)]; /*phx*/
  54.   static int   column[MAXWIDTH+(AMP2*2)];   /*phx*/
  55.   float wratio, hratio;
  56.  
  57.   w = r_refdef.vrect.width;
  58.   h = r_refdef.vrect.height;
  59.  
  60.   wratio = w / (float)scr_vrect.width;
  61.   hratio = h / (float)scr_vrect.height;
  62.  
  63.   for (v=0 ; v<scr_vrect.height+AMP2*2 ; v++)
  64.   {
  65.     rowptr[v] = d_viewbuffer + (r_refdef.vrect.y * screenwidth) +
  66.          (screenwidth * (int)((float)v * hratio * h / (h + AMP2 * 2)));
  67.   }
  68.  
  69.   for (u=0 ; u<scr_vrect.width+AMP2*2 ; u++)
  70.   {
  71.     column[u] = r_refdef.vrect.x +
  72.         (int)((float)u * wratio * w / (w + AMP2 * 2));
  73.   }
  74.  
  75.   turb = intsintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  76.   dest = vid.buffer + scr_vrect.y * vid.rowbytes + scr_vrect.x;
  77.  
  78.   for (v=0 ; v<scr_vrect.height ; v++, dest += vid.rowbytes)
  79.   {
  80.     col = &column[turb[v]];
  81.     row = &rowptr[v];
  82.  
  83.     for (u=0 ; u<scr_vrect.width ; u+=4)
  84.     {
  85.       dest[u+0] = row[turb[u+0]][col[u+0]];
  86.       dest[u+1] = row[turb[u+1]][col[u+1]];
  87.       dest[u+2] = row[turb[u+2]][col[u+2]];
  88.       dest[u+3] = row[turb[u+3]][col[u+3]];
  89.     }
  90.   }
  91. }
  92. #endif
  93.  
  94.  
  95. #if !id386 && !defined(M68KASM) && !defined(PPCASM)
  96. /*
  97. =============
  98. D_DrawTurbulent8Span
  99. =============
  100. */
  101. void D_DrawTurbulent8Span (void)
  102. {
  103.   int   sturb, tturb;
  104.  
  105.   do
  106.   {
  107.     sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
  108.     tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
  109.     *r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb);
  110.     r_turb_s += r_turb_sstep;
  111.     r_turb_t += r_turb_tstep;
  112.   } while (--r_turb_spancount > 0);
  113. }
  114. #endif  // !id386/!M68KASM/!PPCASM
  115.  
  116.  
  117. #if !defined(M68KASM) && !defined(PPCASM)
  118. /*
  119. =============
  120. Turbulent8
  121. =============
  122. */
  123. void Turbulent8 (espan_t *pspan)
  124. {
  125.   int       count;
  126.   fixed16_t   snext, tnext;
  127.   float     sdivz, tdivz, zi, z, du, dv, spancountminus1;
  128.   float     sdivz16stepu, tdivz16stepu, zi16stepu;
  129.   
  130.   r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1));
  131.  
  132.   r_turb_sstep = 0; // keep compiler happy
  133.   r_turb_tstep = 0; // ditto
  134.  
  135.   r_turb_pbase = (unsigned char *)cacheblock;
  136.  
  137.   sdivz16stepu = d_sdivzstepu * 16;
  138.   tdivz16stepu = d_tdivzstepu * 16;
  139.   zi16stepu = d_zistepu * 16;
  140.  
  141.   do
  142.   {
  143.     r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
  144.         (screenwidth * pspan->v) + pspan->u);
  145.  
  146.     count = pspan->count;
  147.  
  148.   // calculate the initial s/z, t/z, 1/z, s, and t and clamp
  149.     du = (float)pspan->u;
  150.     dv = (float)pspan->v;
  151.  
  152.     sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
  153.     tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
  154.     zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  155.     z = (float)0x10000 / zi;  // prescale to 16.16 fixed-point
  156.  
  157.     r_turb_s = (int)(sdivz * z) + sadjust;
  158.     if (r_turb_s > bbextents)
  159.       r_turb_s = bbextents;
  160.     else if (r_turb_s < 0)
  161.       r_turb_s = 0;
  162.  
  163.     r_turb_t = (int)(tdivz * z) + tadjust;
  164.     if (r_turb_t > bbextentt)
  165.       r_turb_t = bbextentt;
  166.     else if (r_turb_t < 0)
  167.       r_turb_t = 0;
  168.  
  169.     do
  170.     {
  171.     // calculate s and t at the far end of the span
  172.       if (count >= 16)
  173.         r_turb_spancount = 16;
  174.       else
  175.         r_turb_spancount = count;
  176.  
  177.       count -= r_turb_spancount;
  178.  
  179.       if (count)
  180.       {
  181.       // calculate s/z, t/z, zi->fixed s and t at far end of span,
  182.       // calculate s and t steps across span by shifting
  183.         sdivz += sdivz16stepu;
  184.         tdivz += tdivz16stepu;
  185.         zi += zi16stepu;
  186.         z = (float)0x10000 / zi;  // prescale to 16.16 fixed-point
  187.  
  188.         snext = (int)(sdivz * z) + sadjust;
  189.         if (snext > bbextents)
  190.           snext = bbextents;
  191.         else if (snext < 16)
  192.           snext = 16; // prevent round-off error on <0 steps from
  193.                 //  from causing overstepping & running off the
  194.                 //  edge of the texture
  195.  
  196.         tnext = (int)(tdivz * z) + tadjust;
  197.         if (tnext > bbextentt)
  198.           tnext = bbextentt;
  199.         else if (tnext < 16)
  200.           tnext = 16; // guard against round-off error on <0 steps
  201.  
  202.         r_turb_sstep = (snext - r_turb_s) >> 4;
  203.         r_turb_tstep = (tnext - r_turb_t) >> 4;
  204.       }
  205.       else
  206.       {
  207.       // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
  208.       // can't step off polygon), clamp, calculate s and t steps across
  209.       // span by division, biasing steps low so we don't run off the
  210.       // texture
  211.         spancountminus1 = (float)(r_turb_spancount - 1);
  212.         sdivz += d_sdivzstepu * spancountminus1;
  213.         tdivz += d_tdivzstepu * spancountminus1;
  214.         zi += d_zistepu * spancountminus1;
  215.         z = (float)0x10000 / zi;  // prescale to 16.16 fixed-point
  216.         snext = (int)(sdivz * z) + sadjust;
  217.         if (snext > bbextents)
  218.           snext = bbextents;
  219.         else if (snext < 16)
  220.           snext = 16; // prevent round-off error on <0 steps from
  221.                 //  from causing overstepping & running off the
  222.                 //  edge of the texture
  223.  
  224.         tnext = (int)(tdivz * z) + tadjust;
  225.         if (tnext > bbextentt)
  226.           tnext = bbextentt;
  227.         else if (tnext < 16)
  228.           tnext = 16; // guard against round-off error on <0 steps
  229.  
  230.         if (r_turb_spancount > 1)
  231.         {
  232.           r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
  233.           r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
  234.         }
  235.       }
  236.  
  237.       r_turb_s = r_turb_s & ((CYCLE<<16)-1);
  238.       r_turb_t = r_turb_t & ((CYCLE<<16)-1);
  239.  
  240.       D_DrawTurbulent8Span ();
  241.  
  242.       r_turb_s = snext;
  243.       r_turb_t = tnext;
  244.  
  245.     } while (count > 0);
  246.  
  247.   } while ((pspan = pspan->pnext) != NULL);
  248. }
  249. #endif
  250.  
  251.  
  252. #if !id386 && !defined(M68KASM) && !defined(PPCASM)
  253. /*
  254. =============
  255. D_DrawSpans8
  256. =============
  257. */
  258. void D_DrawSpans8 (espan_t *pspan)
  259. {
  260.   int       count, spancount;
  261.   unsigned char *pbase, *pdest;
  262.   fixed16_t   s, t, snext, tnext, sstep, tstep;
  263.   float     sdivz, tdivz, zi, z, du, dv, spancountminus1;
  264.   float     sdivz8stepu, tdivz8stepu, zi8stepu;
  265.  
  266.   sstep = 0;  // keep compiler happy
  267.   tstep = 0;  // ditto
  268.  
  269.   pbase = (unsigned char *)cacheblock;
  270.  
  271.   sdivz8stepu = d_sdivzstepu * 8;
  272.   tdivz8stepu = d_tdivzstepu * 8;
  273.   zi8stepu = d_zistepu * 8;
  274.  
  275.   do
  276.   {
  277.     pdest = (unsigned char *)((byte *)d_viewbuffer +
  278.         (screenwidth * pspan->v) + pspan->u);
  279.  
  280.     count = pspan->count;
  281.  
  282.   // calculate the initial s/z, t/z, 1/z, s, and t and clamp
  283.     du = (float)pspan->u;
  284.     dv = (float)pspan->v;
  285.  
  286.     sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
  287.     tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
  288.     zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  289.     z = (float)0x10000 / zi;  // prescale to 16.16 fixed-point
  290.  
  291.     s = (int)(sdivz * z) + sadjust;
  292.     if (s > bbextents)
  293.       s = bbextents;
  294.     else if (s < 0)
  295.       s = 0;
  296.  
  297.     t = (int)(tdivz * z) + tadjust;
  298.     if (t > bbextentt)
  299.       t = bbextentt;
  300.     else if (t < 0)
  301.       t = 0;
  302.  
  303.     do
  304.     {
  305.     // calculate s and t at the far end of the span
  306.       if (count >= 8)
  307.         spancount = 8;
  308.       else
  309.         spancount = count;
  310.  
  311.       count -= spancount;
  312.  
  313.       if (count)
  314.       {
  315.       // calculate s/z, t/z, zi->fixed s and t at far end of span,
  316.       // calculate s and t steps across span by shifting
  317.         sdivz += sdivz8stepu;
  318.         tdivz += tdivz8stepu;
  319.         zi += zi8stepu;
  320.         z = (float)0x10000 / zi;  // prescale to 16.16 fixed-point
  321.  
  322.         snext = (int)(sdivz * z) + sadjust;
  323.         if (snext > bbextents)
  324.           snext = bbextents;
  325.         else if (snext < 8)
  326.           snext = 8;  // prevent round-off error on <0 steps from
  327.                 //  from causing overstepping & running off the
  328.                 //  edge of the texture
  329.  
  330.         tnext = (int)(tdivz * z) + tadjust;
  331.         if (tnext > bbextentt)
  332.           tnext = bbextentt;
  333.         else if (tnext < 8)
  334.           tnext = 8;  // guard against round-off error on <0 steps
  335.  
  336.         sstep = (snext - s) >> 3;
  337.         tstep = (tnext - t) >> 3;
  338.       }
  339.       else
  340.       {
  341.       // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
  342.       // can't step off polygon), clamp, calculate s and t steps across
  343.       // span by division, biasing steps low so we don't run off the
  344.       // texture
  345.         spancountminus1 = (float)(spancount - 1);
  346.         sdivz += d_sdivzstepu * spancountminus1;
  347.         tdivz += d_tdivzstepu * spancountminus1;
  348.         zi += d_zistepu * spancountminus1;
  349.         z = (float)0x10000 / zi;  // prescale to 16.16 fixed-point
  350.         snext = (int)(sdivz * z) + sadjust;
  351.         if (snext > bbextents)
  352.           snext = bbextents;
  353.         else if (snext < 8)
  354.           snext = 8;  // prevent round-off error on <0 steps from
  355.                 //  from causing overstepping & running off the
  356.                 //  edge of the texture
  357.  
  358.         tnext = (int)(tdivz * z) + tadjust;
  359.         if (tnext > bbextentt)
  360.           tnext = bbextentt;
  361.         else if (tnext < 8)
  362.           tnext = 8;  // guard against round-off error on <0 steps
  363.  
  364.         if (spancount > 1)
  365.         {
  366.           sstep = (snext - s) / (spancount - 1);
  367.           tstep = (tnext - t) / (spancount - 1);
  368.         }
  369.       }
  370.  
  371.       do
  372.       {
  373.         *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
  374.         s += sstep;
  375.         t += tstep;
  376.       } while (--spancount > 0);
  377.  
  378.       s = snext;
  379.       t = tnext;
  380.  
  381.     } while (count > 0);
  382.  
  383.   } while ((pspan = pspan->pnext) != NULL);
  384. }
  385.  
  386.  
  387. /*
  388. =============
  389. D_DrawZSpans
  390. =============
  391. */
  392. void D_DrawZSpans (espan_t *pspan)
  393. {
  394.   int       count, doublecount, izistep;
  395.   int       izi;
  396.   short     *pdest;
  397.   unsigned    ltemp;
  398.   double      zi;
  399.   float     du, dv;
  400.  
  401. // FIXME: check for clamping/range problems
  402. // we count on FP exceptions being turned off to avoid range problems
  403.   izistep = (int)(d_zistepu * 0x8000 * 0x10000);
  404.  
  405.   do
  406.   {
  407.     pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
  408.  
  409.     count = pspan->count;
  410.  
  411.   // calculate the initial 1/z
  412.     du = (float)pspan->u;
  413.     dv = (float)pspan->v;
  414.  
  415.     zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
  416.   // we count on FP exceptions being turned off to avoid range problems
  417.     izi = (int)(zi * 0x8000 * 0x10000);
  418.  
  419.     if ((long)pdest & 0x02)
  420.     {
  421.       *pdest++ = (short)(izi >> 16);
  422.       izi += izistep;
  423.       count--;
  424.     }
  425.  
  426.     if ((doublecount = count >> 1) > 0)
  427.     {
  428.       do
  429.       {
  430.         ltemp = izi >> 16;
  431.         izi += izistep;
  432.         ltemp |= izi & 0xFFFF0000;
  433.         izi += izistep;
  434.         *(int *)pdest = ltemp;
  435.         pdest += 2;
  436.       } while (--doublecount > 0);
  437.     }
  438.  
  439.     if (count & 1)
  440.       *pdest = (short)(izi >> 16);
  441.  
  442.   } while ((pspan = pspan->pnext) != NULL);
  443. }
  444. #endif  // !id386/!M68KASM/!PPCASM
  445.