Annotation of quakeworld/client/d_polyse.c, revision 1.1.1.1

1.1       root        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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.