Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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