home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / client / d_polyset.c.orig < prev    next >
Encoding:
Text File  |  2000-06-17  |  24.9 KB  |  1,065 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_polyset.c: routines for drawing sets of polygons sharing the same
  21. // texture (used for Alias models)
  22.  
  23. #include "quakedef.h"
  24. #include "r_local.h"
  25. #include "d_local.h"
  26.  
  27. // TODO: put in span spilling to shrink list size
  28. // !!! if this is changed, it must be changed in d_polysa.s too !!!
  29. #define DPS_MAXSPANS      MAXHEIGHT+1 
  30.                   // 1 extra for spanpackage that marks end
  31.  
  32. // !!! if this is changed, it must be changed in asm_draw.h too !!!
  33. typedef struct {
  34.   void      *pdest;
  35.   short     *pz;
  36.   int       count;
  37.   byte      *ptex;
  38.   int       sfrac, tfrac, light, zi;
  39. } spanpackage_t;
  40.  
  41. typedef struct {
  42.   int   isflattop;
  43.   int   numleftedges;
  44.   int   *pleftedgevert0;
  45.   int   *pleftedgevert1;
  46.   int   *pleftedgevert2;
  47.   int   numrightedges;
  48.   int   *prightedgevert0;
  49.   int   *prightedgevert1;
  50.   int   *prightedgevert2;
  51. } edgetable;
  52.  
  53. int r_p0[6], r_p1[6], r_p2[6];
  54.  
  55. byte    *d_pcolormap;
  56.  
  57. int     d_aflatcolor;
  58. int     d_xdenom;
  59.  
  60. edgetable *pedgetable;
  61.  
  62. edgetable edgetables[12] = {
  63.   {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },
  64.   {0, 2, r_p1, r_p0, r_p2,   1, r_p1, r_p2, NULL},
  65.   {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
  66.   {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },
  67.   {0, 2, r_p0, r_p2, r_p1,   1, r_p0, r_p1, NULL},
  68.   {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
  69.   {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },
  70.   {0, 2, r_p2, r_p1, r_p0,   1, r_p2, r_p0, NULL},
  71.   {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
  72.   {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
  73.   {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
  74.   {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
  75. };
  76.  
  77. // FIXME: some of these can become statics
  78. int       a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
  79. int       r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
  80. int       r_zistepx, r_zistepy;
  81. int       d_aspancount, d_countextrastep;
  82.  
  83. spanpackage_t     *a_spans;
  84. spanpackage_t     *d_pedgespanpackage;
  85. static int        ystart;
  86. byte          *d_pdest, *d_ptex;
  87. short         *d_pz;
  88. int           d_sfrac, d_tfrac, d_light, d_zi;
  89. int           d_ptexextrastep, d_sfracextrastep;
  90. int           d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
  91. int           d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
  92. int           d_sfracbasestep, d_tfracbasestep;
  93. int           d_ziextrastep, d_zibasestep;
  94. int           d_pzextrastep, d_pzbasestep;
  95.  
  96. typedef struct {
  97.   int   quotient;
  98.   int   remainder;
  99. } adivtab_t;
  100.  
  101. static adivtab_t  adivtab[32*32] = {
  102. #include "adivtab.h"
  103. };
  104.  
  105. byte  *skintable[MAX_LBM_HEIGHT];
  106. int   skinwidth;
  107. byte  *skinstart;
  108.  
  109. void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage);
  110. void D_PolysetCalcGradients (int skinwidth);
  111. void D_DrawSubdiv (void);
  112. void D_DrawNonSubdiv (void);
  113. void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3);
  114. void D_PolysetSetEdgeTable (void);
  115. void D_RasterizeAliasPolySmooth (void);
  116. void D_PolysetScanLeftEdge (int height);
  117.  
  118. #if !id386
  119.  
  120. /*
  121. ================
  122. D_PolysetDraw
  123. ================
  124. */
  125. void D_PolysetDraw (void)
  126. {
  127.   spanpackage_t spans[DPS_MAXSPANS + 1 +
  128.       ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1];
  129.             // one extra because of cache line pretouching
  130.  
  131.   a_spans = (spanpackage_t *)
  132.       (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
  133.  
  134.   if (r_affinetridesc.drawtype)
  135.   {
  136.     D_DrawSubdiv ();
  137.   }
  138.   else
  139.   {
  140.     D_DrawNonSubdiv ();
  141.   }
  142. }
  143.  
  144.  
  145. /*
  146. ================
  147. D_PolysetDrawFinalVerts
  148. ================
  149. */
  150. void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts)
  151. {
  152.   int   i, z;
  153.   short *zbuf;
  154.  
  155.   for (i=0 ; i<numverts ; i++, fv++)
  156.   {
  157.   // valid triangle coordinates for filling can include the bottom and
  158.   // right clip edges, due to the fill rule; these shouldn't be drawn
  159.     if ((fv->v[0] < r_refdef.vrectright) &&
  160.       (fv->v[1] < r_refdef.vrectbottom))
  161.     {
  162.       z = fv->v[5]>>16;
  163.       zbuf = zspantable[fv->v[1]] + fv->v[0];
  164.       if (z >= *zbuf)
  165.       {
  166.         int   pix;
  167.         
  168.         *zbuf = z;
  169.         pix = skintable[fv->v[3]>>16][fv->v[2]>>16];
  170.         pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00) ];
  171.         d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix;
  172.       }
  173.     }
  174.   }
  175. }
  176.  
  177.  
  178. /*
  179. ================
  180. D_DrawSubdiv
  181. ================
  182. */
  183. void D_DrawSubdiv (void)
  184. {
  185.   mtriangle_t   *ptri;
  186.   finalvert_t   *pfv, *index0, *index1, *index2;
  187.   int       i;
  188.   int       lnumtriangles;
  189.  
  190.   pfv = r_affinetridesc.pfinalverts;
  191.   ptri = r_affinetridesc.ptriangles;
  192.   lnumtriangles = r_affinetridesc.numtriangles;
  193.  
  194.   for (i=0 ; i<lnumtriangles ; i++)
  195.   {
  196.     index0 = pfv + ptri[i].vertindex[0];
  197.     index1 = pfv + ptri[i].vertindex[1];
  198.     index2 = pfv + ptri[i].vertindex[2];
  199.  
  200.     if (((index0->v[1]-index1->v[1]) *
  201.        (index0->v[0]-index2->v[0]) -
  202.        (index0->v[0]-index1->v[0]) * 
  203.        (index0->v[1]-index2->v[1])) >= 0)
  204.     {
  205.       continue;
  206.     }
  207.  
  208.     d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00];
  209.  
  210.     if (ptri[i].facesfront)
  211.     {
  212.       D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
  213.     }
  214.     else
  215.     {
  216.       int   s0, s1, s2;
  217.  
  218.       s0 = index0->v[2];
  219.       s1 = index1->v[2];
  220.       s2 = index2->v[2];
  221.  
  222.       if (index0->flags & ALIAS_ONSEAM)
  223.         index0->v[2] += r_affinetridesc.seamfixupX16;
  224.       if (index1->flags & ALIAS_ONSEAM)
  225.         index1->v[2] += r_affinetridesc.seamfixupX16;
  226.       if (index2->flags & ALIAS_ONSEAM)
  227.         index2->v[2] += r_affinetridesc.seamfixupX16;
  228.  
  229.       D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
  230.  
  231.       index0->v[2] = s0;
  232.       index1->v[2] = s1;
  233.       index2->v[2] = s2;
  234.     }
  235.   }
  236. }
  237.  
  238.  
  239. /*
  240. ================
  241. D_DrawNonSubdiv
  242. ================
  243. */
  244. void D_DrawNonSubdiv (void)
  245. {
  246.   mtriangle_t   *ptri;
  247.   finalvert_t   *pfv, *index0, *index1, *index2;
  248.   int       i;
  249.   int       lnumtriangles;
  250.  
  251.   pfv = r_affinetridesc.pfinalverts;
  252.   ptri = r_affinetridesc.ptriangles;
  253.   lnumtriangles = r_affinetridesc.numtriangles;
  254.  
  255.   for (i=0 ; i<lnumtriangles ; i++, ptri++)
  256.   {
  257.     index0 = pfv + ptri->vertindex[0];
  258.     index1 = pfv + ptri->vertindex[1];
  259.     index2 = pfv + ptri->vertindex[2];
  260.  
  261.     d_xdenom = (index0->v[1]-index1->v[1]) *
  262.         (index0->v[0]-index2->v[0]) -
  263.         (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]);
  264.  
  265.     if (d_xdenom >= 0)
  266.     {
  267.       continue;
  268.     }
  269.  
  270.     r_p0[0] = index0->v[0];   // u
  271.     r_p0[1] = index0->v[1];   // v
  272.     r_p0[2] = index0->v[2];   // s
  273.     r_p0[3] = index0->v[3];   // t
  274.     r_p0[4] = index0->v[4];   // light
  275.     r_p0[5] = index0->v[5];   // iz
  276.  
  277.     r_p1[0] = index1->v[0];
  278.     r_p1[1] = index1->v[1];
  279.     r_p1[2] = index1->v[2];
  280.     r_p1[3] = index1->v[3];
  281.     r_p1[4] = index1->v[4];
  282.     r_p1[5] = index1->v[5];
  283.  
  284.     r_p2[0] = index2->v[0];
  285.     r_p2[1] = index2->v[1];
  286.     r_p2[2] = index2->v[2];
  287.     r_p2[3] = index2->v[3];
  288.     r_p2[4] = index2->v[4];
  289.     r_p2[5] = index2->v[5];
  290.  
  291.     if (!ptri->facesfront)
  292.     {
  293.       if (index0->flags & ALIAS_ONSEAM)
  294.         r_p0[2] += r_affinetridesc.seamfixupX16;
  295.       if (index1->flags & ALIAS_ONSEAM)
  296.         r_p1[2] += r_affinetridesc.seamfixupX16;
  297.       if (index2->flags & ALIAS_ONSEAM)
  298.         r_p2[2] += r_affinetridesc.seamfixupX16;
  299.     }
  300.  
  301.     D_PolysetSetEdgeTable ();
  302.     D_RasterizeAliasPolySmooth ();
  303.   }
  304. }
  305.  
  306.  
  307. /*
  308. ================
  309. D_PolysetRecursiveTriangle
  310. ================
  311. */
  312. void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3)
  313. {
  314.   int   *temp;
  315.   int   d;
  316.   int   new[6];
  317.   int   z;
  318.   short *zbuf;
  319.  
  320.   d = lp2[0] - lp1[0];
  321.   if (d < -1 || d > 1)
  322.     goto split;
  323.   d = lp2[1] - lp1[1];
  324.   if (d < -1 || d > 1)
  325.     goto split;
  326.  
  327.   d = lp3[0] - lp2[0];
  328.   if (d < -1 || d > 1)
  329.     goto split2;
  330.   d = lp3[1] - lp2[1];
  331.   if (d < -1 || d > 1)
  332.     goto split2;
  333.  
  334.   d = lp1[0] - lp3[0];
  335.   if (d < -1 || d > 1)
  336.     goto split3;
  337.   d = lp1[1] - lp3[1];
  338.   if (d < -1 || d > 1)
  339.   {
  340. split3:
  341.     temp = lp1;
  342.     lp1 = lp3;
  343.     lp3 = lp2;
  344.     lp2 = temp;
  345.  
  346.     goto split;
  347.   }
  348.  
  349.   return;     // entire tri is filled
  350.  
  351. split2:
  352.   temp = lp1;
  353.   lp1 = lp2;
  354.   lp2 = lp3;
  355.   lp3 = temp;
  356.  
  357. split:
  358. // split this edge
  359.   new[0] = (lp1[0] + lp2[0]) >> 1;
  360.   new[1] = (lp1[1] + lp2[1]) >> 1;
  361.   new[2] = (lp1[2] + lp2[2]) >> 1;
  362.   new[3] = (lp1[3] + lp2[3]) >> 1;
  363.   new[5] = (lp1[5] + lp2[5]) >> 1;
  364.  
  365. // draw the point if splitting a leading edge
  366.   if (lp2[1] > lp1[1])
  367.     goto nodraw;
  368.   if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
  369.     goto nodraw;
  370.  
  371.  
  372.   z = new[5]>>16;
  373.   zbuf = zspantable[new[1]] + new[0];
  374.   if (z >= *zbuf)
  375.   {
  376.     int   pix;
  377.     
  378.     *zbuf = z;
  379.     pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]];
  380.     d_viewbuffer[d_scantable[new[1]] + new[0]] = pix;
  381.   }
  382.  
  383. nodraw:
  384. // recursively continue
  385.   D_PolysetRecursiveTriangle (lp3, lp1, new);
  386.   D_PolysetRecursiveTriangle (lp3, new, lp2);
  387. }
  388.  
  389. #endif  // !id386
  390.  
  391.  
  392. /*
  393. ================
  394. D_PolysetUpdateTables
  395. ================
  396. */
  397. void D_PolysetUpdateTables (void)
  398. {
  399.   int   i;
  400.   byte  *s;
  401.   
  402.   if (r_affinetridesc.skinwidth != skinwidth ||
  403.     r_affinetridesc.pskin != skinstart)
  404.   {
  405.     skinwidth = r_affinetridesc.skinwidth;
  406.     skinstart = r_affinetridesc.pskin;
  407.     s = skinstart;
  408.     for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth)
  409.       skintable[i] = s;
  410.   }
  411. }
  412.  
  413.  
  414. #if !id386
  415.  
  416. /*
  417. ===================
  418. D_PolysetScanLeftEdge
  419. ====================
  420. */
  421. void D_PolysetScanLeftEdge (int height)
  422. {
  423.  
  424.   do
  425.   {
  426.     d_pedgespanpackage->pdest = d_pdest;
  427.     d_pedgespanpackage->pz = d_pz;
  428.     d_pedgespanpackage->count = d_aspancount;
  429.     d_pedgespanpackage->ptex = d_ptex;
  430.  
  431.     d_pedgespanpackage->sfrac = d_sfrac;
  432.     d_pedgespanpackage->tfrac = d_tfrac;
  433.  
  434.   // FIXME: need to clamp l, s, t, at both ends?
  435.     d_pedgespanpackage->light = d_light;
  436.     d_pedgespanpackage->zi = d_zi;
  437.  
  438.     d_pedgespanpackage++;
  439.  
  440.     errorterm += erroradjustup;
  441.     if (errorterm >= 0)
  442.     {
  443.       d_pdest += d_pdestextrastep;
  444.       d_pz += d_pzextrastep;
  445.       d_aspancount += d_countextrastep;
  446.       d_ptex += d_ptexextrastep;
  447.       d_sfrac += d_sfracextrastep;
  448.       d_ptex += d_sfrac >> 16;
  449.  
  450.       d_sfrac &= 0xFFFF;
  451.       d_tfrac += d_tfracextrastep;
  452.       if (d_tfrac & 0x10000)
  453.       {
  454.         d_ptex += r_affinetridesc.skinwidth;
  455.         d_tfrac &= 0xFFFF;
  456.       }
  457.       d_light += d_lightextrastep;
  458.       d_zi += d_ziextrastep;
  459.       errorterm -= erroradjustdown;
  460.     }
  461.     else
  462.     {
  463.       d_pdest += d_pdestbasestep;
  464.       d_pz += d_pzbasestep;
  465.       d_aspancount += ubasestep;
  466.       d_ptex += d_ptexbasestep;
  467.       d_sfrac += d_sfracbasestep;
  468.       d_ptex += d_sfrac >> 16;
  469.       d_sfrac &= 0xFFFF;
  470.       d_tfrac += d_tfracbasestep;
  471.       if (d_tfrac & 0x10000)
  472.       {
  473.         d_ptex += r_affinetridesc.skinwidth;
  474.         d_tfrac &= 0xFFFF;
  475.       }
  476.       d_light += d_lightbasestep;
  477.       d_zi += d_zibasestep;
  478.     }
  479.   } while (--height);
  480. }
  481.  
  482. #endif  // !id386
  483.  
  484.  
  485. /*
  486. ===================
  487. D_PolysetSetUpForLineScan
  488. ====================
  489. */
  490. void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
  491.     fixed8_t endvertu, fixed8_t endvertv)
  492. {
  493.   double    dm, dn;
  494.   int     tm, tn;
  495.   adivtab_t *ptemp;
  496.  
  497. // TODO: implement x86 version
  498.  
  499.   errorterm = -1;
  500.  
  501.   tm = endvertu - startvertu;
  502.   tn = endvertv - startvertv;
  503.  
  504.   if (((tm <= 16) && (tm >= -15)) &&
  505.     ((tn <= 16) && (tn >= -15)))
  506.   {
  507.     ptemp = &adivtab[((tm+15) << 5) + (tn+15)];
  508.     ubasestep = ptemp->quotient;
  509.     erroradjustup = ptemp->remainder;
  510.     erroradjustdown = tn;
  511.   }
  512.   else
  513.   {
  514.     dm = (double)tm;
  515.     dn = (double)tn;
  516.  
  517.     FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
  518.  
  519.     erroradjustdown = dn;
  520.   }
  521. }
  522.  
  523.  
  524. #if !id386
  525.  
  526. /*
  527. ================
  528. D_PolysetCalcGradients
  529. ================
  530. */
  531. void D_PolysetCalcGradients (int skinwidth)
  532. {
  533.   float xstepdenominv, ystepdenominv, t0, t1;
  534.   float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
  535.  
  536.   p00_minus_p20 = r_p0[0] - r_p2[0];
  537.   p01_minus_p21 = r_p0[1] - r_p2[1];
  538.   p10_minus_p20 = r_p1[0] - r_p2[0];
  539.   p11_minus_p21 = r_p1[1] - r_p2[1];
  540.  
  541.   xstepdenominv = 1.0 / (float)d_xdenom;
  542.  
  543.   ystepdenominv = -xstepdenominv;
  544.  
  545. // ceil () for light so positive steps are exaggerated, negative steps
  546. // diminished,  pushing us away from underflow toward overflow. Underflow is
  547. // very visible, overflow is very unlikely, because of ambient lighting
  548.   t0 = r_p0[4] - r_p2[4];
  549.   t1 = r_p1[4] - r_p2[4];
  550.   r_lstepx = (int)
  551.       ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
  552.   r_lstepy = (int)
  553.       ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
  554.  
  555.   t0 = r_p0[2] - r_p2[2];
  556.   t1 = r_p1[2] - r_p2[2];
  557.   r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  558.       xstepdenominv);
  559.   r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
  560.       ystepdenominv);
  561.  
  562.   t0 = r_p0[3] - r_p2[3];
  563.   t1 = r_p1[3] - r_p2[3];
  564.   r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  565.       xstepdenominv);
  566.   r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
  567.       ystepdenominv);
  568.  
  569.   t0 = r_p0[5] - r_p2[5];
  570.   t1 = r_p1[5] - r_p2[5];
  571.   r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  572.       xstepdenominv);
  573.   r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
  574.       ystepdenominv);
  575.  
  576. #if id386
  577.   a_sstepxfrac = r_sstepx << 16;
  578.   a_tstepxfrac = r_tstepx << 16;
  579. #else
  580.   a_sstepxfrac = r_sstepx & 0xFFFF;
  581.   a_tstepxfrac = r_tstepx & 0xFFFF;
  582. #endif
  583.  
  584.   a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
  585. }
  586.  
  587. #endif  // !id386
  588.  
  589.  
  590. byte gelmap[256];
  591. void InitGel (byte *palette)
  592. {
  593.   int   i;
  594.   int   r;
  595.  
  596.   for (i=0 ; i<256 ; i++)
  597.   {
  598. //    r = (palette[i*3]>>4);
  599.     r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3);
  600.     gelmap[i] = /* 64 */ 0 + r;
  601.   }
  602. }
  603.  
  604.  
  605. #if !id386
  606.  
  607. /*
  608. ================
  609. D_PolysetDrawSpans8
  610. ================
  611. */
  612. void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage)
  613. {
  614.   int   lcount;
  615.   byte  *lpdest;
  616.   byte  *lptex;
  617.   int   lsfrac, ltfrac;
  618.   int   llight;
  619.   int   lzi;
  620.   short *lpz;
  621.  
  622.   do
  623.   {
  624.     lcount = d_aspancount - pspanpackage->count;
  625.  
  626.     errorterm += erroradjustup;
  627.     if (errorterm >= 0)
  628.     {
  629.       d_aspancount += d_countextrastep;
  630.       errorterm -= erroradjustdown;
  631.     }
  632.     else
  633.     {
  634.       d_aspancount += ubasestep;
  635.     }
  636.  
  637.     if (lcount)
  638.     {
  639.       lpdest = pspanpackage->pdest;
  640.       lptex = pspanpackage->ptex;
  641.       lpz = pspanpackage->pz;
  642.       lsfrac = pspanpackage->sfrac;
  643.       ltfrac = pspanpackage->tfrac;
  644.       llight = pspanpackage->light;
  645.       lzi = pspanpackage->zi;
  646.  
  647.       do
  648.       {
  649.         if ((lzi >> 16) >= *lpz)
  650.         {
  651.           *lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)];
  652. // gel mapping          *lpdest = gelmap[*lpdest];
  653.           *lpz = lzi >> 16;
  654.         }
  655.         lpdest++;
  656.         lzi += r_zistepx;
  657.         lpz++;
  658.         llight += r_lstepx;
  659.         lptex += a_ststepxwhole;
  660.         lsfrac += a_sstepxfrac;
  661.         lptex += lsfrac >> 16;
  662.         lsfrac &= 0xFFFF;
  663.         ltfrac += a_tstepxfrac;
  664.         if (ltfrac & 0x10000)
  665.         {
  666.           lptex += r_affinetridesc.skinwidth;
  667.           ltfrac &= 0xFFFF;
  668.         }
  669.       } while (--lcount);
  670.     }
  671.  
  672.     pspanpackage++;
  673.   } while (pspanpackage->count != -999999);
  674. }
  675. #endif  // !id386
  676.  
  677.  
  678. /*
  679. ================
  680. D_PolysetFillSpans8
  681. ================
  682. */
  683. void D_PolysetFillSpans8 (spanpackage_t *pspanpackage)
  684. {
  685.   int       color;
  686.  
  687. // FIXME: do z buffering
  688.  
  689.   color = d_aflatcolor++;
  690.  
  691.   while (1)
  692.   {
  693.     int   lcount;
  694.     byte  *lpdest;
  695.  
  696.     lcount = pspanpackage->count;
  697.  
  698.     if (lcount == -1)
  699.       return;
  700.  
  701.     if (lcount)
  702.     {
  703.       lpdest = pspanpackage->pdest;
  704.  
  705.       do
  706.       {
  707.         *lpdest++ = color;
  708.       } while (--lcount);
  709.     }
  710.  
  711.     pspanpackage++;
  712.   }
  713. }
  714.  
  715. /*
  716. ================
  717. D_RasterizeAliasPolySmooth
  718. ================
  719. */
  720. void D_RasterizeAliasPolySmooth (void)
  721. {
  722.   int       initialleftheight, initialrightheight;
  723.   int       *plefttop, *prighttop, *pleftbottom, *prightbottom;
  724.   int       working_lstepx, originalcount;
  725.  
  726.   plefttop = pedgetable->pleftedgevert0;
  727.   prighttop = pedgetable->prightedgevert0;
  728.  
  729.   pleftbottom = pedgetable->pleftedgevert1;
  730.   prightbottom = pedgetable->prightedgevert1;
  731.  
  732.   initialleftheight = pleftbottom[1] - plefttop[1];
  733.   initialrightheight = prightbottom[1] - prighttop[1];
  734.  
  735. //
  736. // set the s, t, and light gradients, which are consistent across the triangle
  737. // because being a triangle, things are affine
  738. //
  739.   D_PolysetCalcGradients (r_affinetridesc.skinwidth);
  740.  
  741. //
  742. // rasterize the polygon
  743. //
  744.  
  745. //
  746. // scan out the top (and possibly only) part of the left edge
  747. //
  748.   D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
  749.               pleftbottom[0], pleftbottom[1]);
  750.  
  751.   d_pedgespanpackage = a_spans;
  752.  
  753.   ystart = plefttop[1];
  754.   d_aspancount = plefttop[0] - prighttop[0];
  755.  
  756.   d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
  757.       (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
  758. #if id386
  759.   d_sfrac = (plefttop[2] & 0xFFFF) << 16;
  760.   d_tfrac = (plefttop[3] & 0xFFFF) << 16;
  761.   d_pzbasestep = (d_zwidth + ubasestep) << 1;
  762.   d_pzextrastep = d_pzbasestep + 2;
  763. #else
  764.   d_sfrac = plefttop[2] & 0xFFFF;
  765.   d_tfrac = plefttop[3] & 0xFFFF;
  766.   d_pzbasestep = d_zwidth + ubasestep;
  767.   d_pzextrastep = d_pzbasestep + 1;
  768. #endif
  769.   d_light = plefttop[4];
  770.   d_zi = plefttop[5];
  771.  
  772.   d_pdestbasestep = screenwidth + ubasestep;
  773.   d_pdestextrastep = d_pdestbasestep + 1;
  774.   d_pdest = (byte *)d_viewbuffer +
  775.       ystart * screenwidth + plefttop[0];
  776.   d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
  777.  
  778. // TODO: can reuse partial expressions here
  779.  
  780. // for negative steps in x along left edge, bias toward overflow rather than
  781. // underflow (sort of turning the floor () we did in the gradient calcs into
  782. // ceil (), but plus a little bit)
  783.   if (ubasestep < 0)
  784.     working_lstepx = r_lstepx - 1;
  785.   else
  786.     working_lstepx = r_lstepx;
  787.  
  788.   d_countextrastep = ubasestep + 1;
  789.   d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
  790.       ((r_tstepy + r_tstepx * ubasestep) >> 16) *
  791.       r_affinetridesc.skinwidth;
  792. #if id386
  793.   d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
  794.   d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
  795. #else
  796.   d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
  797.   d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
  798. #endif
  799.   d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
  800.   d_zibasestep = r_zistepy + r_zistepx * ubasestep;
  801.  
  802.   d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
  803.       ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
  804.       r_affinetridesc.skinwidth;
  805. #if id386
  806.   d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16;
  807.   d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16;
  808. #else
  809.   d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF;
  810.   d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF;
  811. #endif
  812.   d_lightextrastep = d_lightbasestep + working_lstepx;
  813.   d_ziextrastep = d_zibasestep + r_zistepx;
  814.  
  815.   D_PolysetScanLeftEdge (initialleftheight);
  816.  
  817. //
  818. // scan out the bottom part of the left edge, if it exists
  819. //
  820.   if (pedgetable->numleftedges == 2)
  821.   {
  822.     int   height;
  823.  
  824.     plefttop = pleftbottom;
  825.     pleftbottom = pedgetable->pleftedgevert2;
  826.  
  827.     D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
  828.                 pleftbottom[0], pleftbottom[1]);
  829.  
  830.     height = pleftbottom[1] - plefttop[1];
  831.  
  832. // TODO: make this a function; modularize this function in general
  833.  
  834.     ystart = plefttop[1];
  835.     d_aspancount = plefttop[0] - prighttop[0];
  836.     d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
  837.         (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
  838.     d_sfrac = 0;
  839.     d_tfrac = 0;
  840.     d_light = plefttop[4];
  841.     d_zi = plefttop[5];
  842.  
  843.     d_pdestbasestep = screenwidth + ubasestep;
  844.     d_pdestextrastep = d_pdestbasestep + 1;
  845.     d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0];
  846. #if id386
  847.     d_pzbasestep = (d_zwidth + ubasestep) << 1;
  848.     d_pzextrastep = d_pzbasestep + 2;
  849. #else
  850.     d_pzbasestep = d_zwidth + ubasestep;
  851.     d_pzextrastep = d_pzbasestep + 1;
  852. #endif
  853.     d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
  854.  
  855.     if (ubasestep < 0)
  856.       working_lstepx = r_lstepx - 1;
  857.     else
  858.       working_lstepx = r_lstepx;
  859.  
  860.     d_countextrastep = ubasestep + 1;
  861.     d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
  862.         ((r_tstepy + r_tstepx * ubasestep) >> 16) *
  863.         r_affinetridesc.skinwidth;
  864. #if id386
  865.     d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
  866.     d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
  867. #else
  868.     d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
  869.     d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
  870. #endif
  871.     d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
  872.     d_zibasestep = r_zistepy + r_zistepx * ubasestep;
  873.  
  874.     d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
  875.         ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
  876.         r_affinetridesc.skinwidth;
  877. #if id386
  878.     d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16;
  879.     d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16;
  880. #else
  881.     d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF;
  882.     d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF;
  883. #endif
  884.     d_lightextrastep = d_lightbasestep + working_lstepx;
  885.     d_ziextrastep = d_zibasestep + r_zistepx;
  886.  
  887.     D_PolysetScanLeftEdge (height);
  888.   }
  889.  
  890. // scan out the top (and possibly only) part of the right edge, updating the
  891. // count field
  892.   d_pedgespanpackage = a_spans;
  893.  
  894.   D_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
  895.               prightbottom[0], prightbottom[1]);
  896.   d_aspancount = 0;
  897.   d_countextrastep = ubasestep + 1;
  898.   originalcount = a_spans[initialrightheight].count;
  899.   a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
  900.   D_PolysetDrawSpans8 (a_spans);
  901.  
  902. // scan out the bottom part of the right edge, if it exists
  903.   if (pedgetable->numrightedges == 2)
  904.   {
  905.     int       height;
  906.     spanpackage_t *pstart;
  907.  
  908.     pstart = a_spans + initialrightheight;
  909.     pstart->count = originalcount;
  910.  
  911.     d_aspancount = prightbottom[0] - prighttop[0];
  912.  
  913.     prighttop = prightbottom;
  914.     prightbottom = pedgetable->prightedgevert2;
  915.  
  916.     height = prightbottom[1] - prighttop[1];
  917.  
  918.     D_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
  919.                 prightbottom[0], prightbottom[1]);
  920.  
  921.     d_countextrastep = ubasestep + 1;
  922.     a_spans[initialrightheight + height].count = -999999;
  923.                       // mark end of the spanpackages
  924.     D_PolysetDrawSpans8 (pstart);
  925.   }
  926. }
  927.  
  928.  
  929. /*
  930. ================
  931. D_PolysetSetEdgeTable
  932. ================
  933. */
  934. void D_PolysetSetEdgeTable (void)
  935. {
  936.   int     edgetableindex;
  937.  
  938.   edgetableindex = 0; // assume the vertices are already in
  939.             //  top to bottom order
  940.  
  941. //
  942. // determine which edges are right & left, and the order in which
  943. // to rasterize them
  944. //
  945.   if (r_p0[1] >= r_p1[1])
  946.   {
  947.     if (r_p0[1] == r_p1[1])
  948.     {
  949.       if (r_p0[1] < r_p2[1])
  950.         pedgetable = &edgetables[2];
  951.       else
  952.         pedgetable = &edgetables[5];
  953.  
  954.       return;
  955.     }
  956.     else
  957.     {
  958.       edgetableindex = 1;
  959.     }
  960.   }
  961.  
  962.   if (r_p0[1] == r_p2[1])
  963.   {
  964.     if (edgetableindex)
  965.       pedgetable = &edgetables[8];
  966.     else
  967.       pedgetable = &edgetables[9];
  968.  
  969.     return;
  970.   }
  971.   else if (r_p1[1] == r_p2[1])
  972.   {
  973.     if (edgetableindex)
  974.       pedgetable = &edgetables[10];
  975.     else
  976.       pedgetable = &edgetables[11];
  977.  
  978.     return;
  979.   }
  980.  
  981.   if (r_p0[1] > r_p2[1])
  982.     edgetableindex += 2;
  983.  
  984.   if (r_p1[1] > r_p2[1])
  985.     edgetableindex += 4;
  986.  
  987.   pedgetable = &edgetables[edgetableindex];
  988. }
  989.  
  990.  
  991. #if 0
  992.  
  993. void D_PolysetRecursiveDrawLine (int *lp1, int *lp2)
  994. {
  995.   int   d;
  996.   int   new[6];
  997.   int   ofs;
  998.   
  999.   d = lp2[0] - lp1[0];
  1000.   if (d < -1 || d > 1)
  1001.     goto split;
  1002.   d = lp2[1] - lp1[1];
  1003.   if (d < -1 || d > 1)
  1004.     goto split;
  1005.  
  1006.   return; // line is completed
  1007.  
  1008. split:
  1009. // split this edge
  1010.   new[0] = (lp1[0] + lp2[0]) >> 1;
  1011.   new[1] = (lp1[1] + lp2[1]) >> 1;
  1012.   new[5] = (lp1[5] + lp2[5]) >> 1;
  1013.   new[2] = (lp1[2] + lp2[2]) >> 1;
  1014.   new[3] = (lp1[3] + lp2[3]) >> 1;
  1015.   new[4] = (lp1[4] + lp2[4]) >> 1;
  1016.  
  1017. // draw the point
  1018.   ofs = d_scantable[new[1]] + new[0];
  1019.   if (new[5] > d_pzbuffer[ofs])
  1020.   {
  1021.     int   pix;
  1022.     
  1023.     d_pzbuffer[ofs] = new[5];
  1024.     pix = skintable[new[3]>>16][new[2]>>16];
  1025. //    pix = ((byte *)acolormap)[pix + (new[4] & 0xFF00)];
  1026.     d_viewbuffer[ofs] = pix;
  1027.   }
  1028.  
  1029. // recursively continue
  1030.   D_PolysetRecursiveDrawLine (lp1, new);
  1031.   D_PolysetRecursiveDrawLine (new, lp2);
  1032. }
  1033.  
  1034. void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3)
  1035. {
  1036.   int   d;
  1037.   int   new[4];
  1038.   
  1039.   d = lp2[0] - lp1[0];
  1040.   if (d < -1 || d > 1)
  1041.     goto split;
  1042.   d = lp2[1] - lp1[1];
  1043.   if (d < -1 || d > 1)
  1044.     goto split;
  1045.   return;
  1046.  
  1047. split:
  1048. // split this edge
  1049.   new[0] = (lp1[0] + lp2[0]) >> 1;
  1050.   new[1] = (lp1[1] + lp2[1]) >> 1;
  1051.   new[5] = (lp1[5] + lp2[5]) >> 1;
  1052.   new[2] = (lp1[2] + lp2[2]) >> 1;
  1053.   new[3] = (lp1[3] + lp2[3]) >> 1;
  1054.   new[4] = (lp1[4] + lp2[4]) >> 1;
  1055.  
  1056.   D_PolysetRecursiveDrawLine (new, lp3);
  1057.  
  1058. // recursively continue
  1059.   D_PolysetRecursiveTriangle (lp1, new, lp3);
  1060.   D_PolysetRecursiveTriangle (new, lp2, lp3);
  1061. }
  1062.  
  1063. #endif
  1064.  
  1065.