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