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