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