git-svn-id: http://bladebattles.com/kurok/SVN@11 20cd92bb-ff49-0410-b73e-96a06e42c3b9
[kurok.git] / d_polyse.c
blob2d8614e7d646672aaabe2c7aec819b1b8e322c7e
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // d_polyset.c: routines for drawing sets of polygons sharing the same
21 // texture (used for Alias models)
23 #include "quakedef.h"
24 #include "r_local.h"
25 #include "d_local.h"
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
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;
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;
53 int r_p0[6], r_p1[6], r_p2[6];
55 byte *d_pcolormap;
57 int d_aflatcolor;
58 int d_xdenom;
60 edgetable *pedgetable;
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},
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;
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;
96 typedef struct {
97 int quotient;
98 int remainder;
99 } adivtab_t;
101 static adivtab_t adivtab[32*32] = {
102 #include "adivtab.h"
105 byte *skintable[MAX_LBM_HEIGHT];
106 int skinwidth;
107 byte *skinstart;
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);
118 #if !id386
121 ================
122 D_PolysetDraw
123 ================
125 void D_PolysetDraw (void)
127 spanpackage_t spans[DPS_MAXSPANS + 1 +
128 ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1];
129 // one extra because of cache line pretouching
131 a_spans = (spanpackage_t *)
132 (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
134 if (r_affinetridesc.drawtype)
136 D_DrawSubdiv ();
138 else
140 D_DrawNonSubdiv ();
146 ================
147 D_PolysetDrawFinalVerts
148 ================
150 void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts)
152 int i, z;
153 short *zbuf;
155 for (i=0 ; i<numverts ; i++, fv++)
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))
162 z = fv->v[5]>>16;
163 zbuf = zspantable[fv->v[1]] + fv->v[0];
164 if (z >= *zbuf)
166 int pix;
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;
179 ================
180 D_DrawSubdiv
181 ================
183 void D_DrawSubdiv (void)
185 mtriangle_t *ptri;
186 finalvert_t *pfv, *index0, *index1, *index2;
187 int i;
188 int lnumtriangles;
190 pfv = r_affinetridesc.pfinalverts;
191 ptri = r_affinetridesc.ptriangles;
192 lnumtriangles = r_affinetridesc.numtriangles;
194 for (i=0 ; i<lnumtriangles ; i++)
196 index0 = pfv + ptri[i].vertindex[0];
197 index1 = pfv + ptri[i].vertindex[1];
198 index2 = pfv + ptri[i].vertindex[2];
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)
205 continue;
208 d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00];
210 if (ptri[i].facesfront)
212 D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
214 else
216 int s0, s1, s2;
218 s0 = index0->v[2];
219 s1 = index1->v[2];
220 s2 = index2->v[2];
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;
229 D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
231 index0->v[2] = s0;
232 index1->v[2] = s1;
233 index2->v[2] = s2;
240 ================
241 D_DrawNonSubdiv
242 ================
244 void D_DrawNonSubdiv (void)
246 mtriangle_t *ptri;
247 finalvert_t *pfv, *index0, *index1, *index2;
248 int i;
249 int lnumtriangles;
251 pfv = r_affinetridesc.pfinalverts;
252 ptri = r_affinetridesc.ptriangles;
253 lnumtriangles = r_affinetridesc.numtriangles;
255 for (i=0 ; i<lnumtriangles ; i++, ptri++)
257 index0 = pfv + ptri->vertindex[0];
258 index1 = pfv + ptri->vertindex[1];
259 index2 = pfv + ptri->vertindex[2];
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]);
265 if (d_xdenom >= 0)
267 continue;
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
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];
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];
291 if (!ptri->facesfront)
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;
301 D_PolysetSetEdgeTable ();
302 D_RasterizeAliasPolySmooth ();
308 ================
309 D_PolysetRecursiveTriangle
310 ================
312 void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3)
314 int *temp;
315 int d;
316 int new[6];
317 int z;
318 short *zbuf;
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;
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;
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)
340 split3:
341 temp = lp1;
342 lp1 = lp3;
343 lp3 = lp2;
344 lp2 = temp;
346 goto split;
349 return; // entire tri is filled
351 split2:
352 temp = lp1;
353 lp1 = lp2;
354 lp2 = lp3;
355 lp3 = temp;
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;
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;
372 z = new[5]>>16;
373 zbuf = zspantable[new[1]] + new[0];
374 if (z >= *zbuf)
376 int pix;
378 *zbuf = z;
379 pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]];
380 d_viewbuffer[d_scantable[new[1]] + new[0]] = pix;
383 nodraw:
384 // recursively continue
385 D_PolysetRecursiveTriangle (lp3, lp1, new);
386 D_PolysetRecursiveTriangle (lp3, new, lp2);
389 #endif // !id386
393 ================
394 D_PolysetUpdateTables
395 ================
397 void D_PolysetUpdateTables (void)
399 int i;
400 byte *s;
402 if (r_affinetridesc.skinwidth != skinwidth ||
403 r_affinetridesc.pskin != skinstart)
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;
414 #if !id386
417 ===================
418 D_PolysetScanLeftEdge
419 ====================
421 void D_PolysetScanLeftEdge (int height)
426 d_pedgespanpackage->pdest = d_pdest;
427 d_pedgespanpackage->pz = d_pz;
428 d_pedgespanpackage->count = d_aspancount;
429 d_pedgespanpackage->ptex = d_ptex;
431 d_pedgespanpackage->sfrac = d_sfrac;
432 d_pedgespanpackage->tfrac = d_tfrac;
434 // FIXME: need to clamp l, s, t, at both ends?
435 d_pedgespanpackage->light = d_light;
436 d_pedgespanpackage->zi = d_zi;
438 d_pedgespanpackage++;
440 errorterm += erroradjustup;
441 if (errorterm >= 0)
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;
450 d_sfrac &= 0xFFFF;
451 d_tfrac += d_tfracextrastep;
452 if (d_tfrac & 0x10000)
454 d_ptex += r_affinetridesc.skinwidth;
455 d_tfrac &= 0xFFFF;
457 d_light += d_lightextrastep;
458 d_zi += d_ziextrastep;
459 errorterm -= erroradjustdown;
461 else
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)
473 d_ptex += r_affinetridesc.skinwidth;
474 d_tfrac &= 0xFFFF;
476 d_light += d_lightbasestep;
477 d_zi += d_zibasestep;
479 } while (--height);
482 #endif // !id386
486 ===================
487 D_PolysetSetUpForLineScan
488 ====================
490 void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
491 fixed8_t endvertu, fixed8_t endvertv)
493 float dm, dn;
494 int tm, tn;
495 adivtab_t *ptemp;
497 // TODO: implement x86 version
499 errorterm = -1;
501 tm = endvertu - startvertu;
502 tn = endvertv - startvertv;
504 if (((tm <= 16) && (tm >= -15)) &&
505 ((tn <= 16) && (tn >= -15)))
507 ptemp = &adivtab[((tm+15) << 5) + (tn+15)];
508 ubasestep = ptemp->quotient;
509 erroradjustup = ptemp->remainder;
510 erroradjustdown = tn;
512 else
514 dm = (float)tm;
515 dn = (float)tn;
517 FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
519 erroradjustdown = dn;
524 #if !id386
527 ================
528 D_PolysetCalcGradients
529 ================
531 void D_PolysetCalcGradients (int skinwidth)
533 float xstepdenominv, ystepdenominv, t0, t1;
534 float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
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];
541 xstepdenominv = 1.0 / (float)d_xdenom;
543 ystepdenominv = -xstepdenominv;
545 // ceilf () 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 ceilf((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
552 r_lstepy = (int)
553 ceilf((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
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);
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);
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);
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
584 a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
587 #endif // !id386
590 #if 0
591 byte gelmap[256];
592 void InitGel (byte *palette)
594 int i;
595 int r;
597 for (i=0 ; i<256 ; i++)
599 // r = (palette[i*3]>>4);
600 r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3);
601 gelmap[i] = /* 64 */ 0 + r;
604 #endif
607 #if !id386
610 ================
611 D_PolysetDrawSpans8
612 ================
614 void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage)
616 int lcount;
617 byte *lpdest;
618 byte *lptex;
619 int lsfrac, ltfrac;
620 int llight;
621 int lzi;
622 short *lpz;
626 lcount = d_aspancount - pspanpackage->count;
628 errorterm += erroradjustup;
629 if (errorterm >= 0)
631 d_aspancount += d_countextrastep;
632 errorterm -= erroradjustdown;
634 else
636 d_aspancount += ubasestep;
639 if (lcount)
641 lpdest = pspanpackage->pdest;
642 lptex = pspanpackage->ptex;
643 lpz = pspanpackage->pz;
644 lsfrac = pspanpackage->sfrac;
645 ltfrac = pspanpackage->tfrac;
646 llight = pspanpackage->light;
647 lzi = pspanpackage->zi;
651 if ((lzi >> 16) >= *lpz)
653 *lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)];
654 // gel mapping *lpdest = gelmap[*lpdest];
655 *lpz = lzi >> 16;
657 lpdest++;
658 lzi += r_zistepx;
659 lpz++;
660 llight += r_lstepx;
661 lptex += a_ststepxwhole;
662 lsfrac += a_sstepxfrac;
663 lptex += lsfrac >> 16;
664 lsfrac &= 0xFFFF;
665 ltfrac += a_tstepxfrac;
666 if (ltfrac & 0x10000)
668 lptex += r_affinetridesc.skinwidth;
669 ltfrac &= 0xFFFF;
671 } while (--lcount);
674 pspanpackage++;
675 } while (pspanpackage->count != -999999);
677 #endif // !id386
681 ================
682 D_PolysetFillSpans8
683 ================
685 void D_PolysetFillSpans8 (spanpackage_t *pspanpackage)
687 int color;
689 // FIXME: do z buffering
691 color = d_aflatcolor++;
693 while (1)
695 int lcount;
696 byte *lpdest;
698 lcount = pspanpackage->count;
700 if (lcount == -1)
701 return;
703 if (lcount)
705 lpdest = pspanpackage->pdest;
709 *lpdest++ = color;
710 } while (--lcount);
713 pspanpackage++;
718 ================
719 D_RasterizeAliasPolySmooth
720 ================
722 void D_RasterizeAliasPolySmooth (void)
724 int initialleftheight, initialrightheight;
725 int *plefttop, *prighttop, *pleftbottom, *prightbottom;
726 int working_lstepx, originalcount;
728 plefttop = pedgetable->pleftedgevert0;
729 prighttop = pedgetable->prightedgevert0;
731 pleftbottom = pedgetable->pleftedgevert1;
732 prightbottom = pedgetable->prightedgevert1;
734 initialleftheight = pleftbottom[1] - plefttop[1];
735 initialrightheight = prightbottom[1] - prighttop[1];
738 // set the s, t, and light gradients, which are consistent across the triangle
739 // because being a triangle, things are affine
741 D_PolysetCalcGradients (r_affinetridesc.skinwidth);
744 // rasterize the polygon
748 // scan out the top (and possibly only) part of the left edge
750 d_pedgespanpackage = a_spans;
752 ystart = plefttop[1];
753 d_aspancount = plefttop[0] - prighttop[0];
755 d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
756 (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
757 #if id386
758 d_sfrac = (plefttop[2] & 0xFFFF) << 16;
759 d_tfrac = (plefttop[3] & 0xFFFF) << 16;
760 #else
761 d_sfrac = plefttop[2] & 0xFFFF;
762 d_tfrac = plefttop[3] & 0xFFFF;
763 #endif
764 d_light = plefttop[4];
765 d_zi = plefttop[5];
767 d_pdest = (byte *)d_viewbuffer +
768 ystart * screenwidth + plefttop[0];
769 d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
771 if (initialleftheight == 1)
773 d_pedgespanpackage->pdest = d_pdest;
774 d_pedgespanpackage->pz = d_pz;
775 d_pedgespanpackage->count = d_aspancount;
776 d_pedgespanpackage->ptex = d_ptex;
778 d_pedgespanpackage->sfrac = d_sfrac;
779 d_pedgespanpackage->tfrac = d_tfrac;
781 // FIXME: need to clamp l, s, t, at both ends?
782 d_pedgespanpackage->light = d_light;
783 d_pedgespanpackage->zi = d_zi;
785 d_pedgespanpackage++;
787 else
789 D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
790 pleftbottom[0], pleftbottom[1]);
792 #if id386
793 d_pzbasestep = (d_zwidth + ubasestep) << 1;
794 d_pzextrastep = d_pzbasestep + 2;
795 #else
796 d_pzbasestep = d_zwidth + ubasestep;
797 d_pzextrastep = d_pzbasestep + 1;
798 #endif
800 d_pdestbasestep = screenwidth + ubasestep;
801 d_pdestextrastep = d_pdestbasestep + 1;
803 // TODO: can reuse partial expressions here
805 // for negative steps in x along left edge, bias toward overflow rather than
806 // underflow (sort of turning the floor () we did in the gradient calcs into
807 // ceilf (), but plus a little bit)
808 if (ubasestep < 0)
809 working_lstepx = r_lstepx - 1;
810 else
811 working_lstepx = r_lstepx;
813 d_countextrastep = ubasestep + 1;
814 d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
815 ((r_tstepy + r_tstepx * ubasestep) >> 16) *
816 r_affinetridesc.skinwidth;
817 #if id386
818 d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
819 d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
820 #else
821 d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
822 d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
823 #endif
824 d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
825 d_zibasestep = r_zistepy + r_zistepx * ubasestep;
827 d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
828 ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
829 r_affinetridesc.skinwidth;
830 #if id386
831 d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16;
832 d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16;
833 #else
834 d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF;
835 d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF;
836 #endif
837 d_lightextrastep = d_lightbasestep + working_lstepx;
838 d_ziextrastep = d_zibasestep + r_zistepx;
840 D_PolysetScanLeftEdge (initialleftheight);
844 // scan out the bottom part of the left edge, if it exists
846 if (pedgetable->numleftedges == 2)
848 int height;
850 plefttop = pleftbottom;
851 pleftbottom = pedgetable->pleftedgevert2;
853 height = pleftbottom[1] - plefttop[1];
855 // TODO: make this a function; modularize this function in general
857 ystart = plefttop[1];
858 d_aspancount = plefttop[0] - prighttop[0];
859 d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
860 (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
861 d_sfrac = 0;
862 d_tfrac = 0;
863 d_light = plefttop[4];
864 d_zi = plefttop[5];
866 d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0];
867 d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
869 if (height == 1)
871 d_pedgespanpackage->pdest = d_pdest;
872 d_pedgespanpackage->pz = d_pz;
873 d_pedgespanpackage->count = d_aspancount;
874 d_pedgespanpackage->ptex = d_ptex;
876 d_pedgespanpackage->sfrac = d_sfrac;
877 d_pedgespanpackage->tfrac = d_tfrac;
879 // FIXME: need to clamp l, s, t, at both ends?
880 d_pedgespanpackage->light = d_light;
881 d_pedgespanpackage->zi = d_zi;
883 d_pedgespanpackage++;
885 else
887 D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
888 pleftbottom[0], pleftbottom[1]);
890 d_pdestbasestep = screenwidth + ubasestep;
891 d_pdestextrastep = d_pdestbasestep + 1;
893 #if id386
894 d_pzbasestep = (d_zwidth + ubasestep) << 1;
895 d_pzextrastep = d_pzbasestep + 2;
896 #else
897 d_pzbasestep = d_zwidth + ubasestep;
898 d_pzextrastep = d_pzbasestep + 1;
899 #endif
901 if (ubasestep < 0)
902 working_lstepx = r_lstepx - 1;
903 else
904 working_lstepx = r_lstepx;
906 d_countextrastep = ubasestep + 1;
907 d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
908 ((r_tstepy + r_tstepx * ubasestep) >> 16) *
909 r_affinetridesc.skinwidth;
910 #if id386
911 d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
912 d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
913 #else
914 d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
915 d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
916 #endif
917 d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
918 d_zibasestep = r_zistepy + r_zistepx * ubasestep;
920 d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
921 ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
922 r_affinetridesc.skinwidth;
923 #if id386
924 d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16;
925 d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16;
926 #else
927 d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF;
928 d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF;
929 #endif
930 d_lightextrastep = d_lightbasestep + working_lstepx;
931 d_ziextrastep = d_zibasestep + r_zistepx;
933 D_PolysetScanLeftEdge (height);
937 // scan out the top (and possibly only) part of the right edge, updating the
938 // count field
939 d_pedgespanpackage = a_spans;
941 D_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
942 prightbottom[0], prightbottom[1]);
943 d_aspancount = 0;
944 d_countextrastep = ubasestep + 1;
945 originalcount = a_spans[initialrightheight].count;
946 a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
947 D_PolysetDrawSpans8 (a_spans);
949 // scan out the bottom part of the right edge, if it exists
950 if (pedgetable->numrightedges == 2)
952 int height;
953 spanpackage_t *pstart;
955 pstart = a_spans + initialrightheight;
956 pstart->count = originalcount;
958 d_aspancount = prightbottom[0] - prighttop[0];
960 prighttop = prightbottom;
961 prightbottom = pedgetable->prightedgevert2;
963 height = prightbottom[1] - prighttop[1];
965 D_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
966 prightbottom[0], prightbottom[1]);
968 d_countextrastep = ubasestep + 1;
969 a_spans[initialrightheight + height].count = -999999;
970 // mark end of the spanpackages
971 D_PolysetDrawSpans8 (pstart);
977 ================
978 D_PolysetSetEdgeTable
979 ================
981 void D_PolysetSetEdgeTable (void)
983 int edgetableindex;
985 edgetableindex = 0; // assume the vertices are already in
986 // top to bottom order
989 // determine which edges are right & left, and the order in which
990 // to rasterize them
992 if (r_p0[1] >= r_p1[1])
994 if (r_p0[1] == r_p1[1])
996 if (r_p0[1] < r_p2[1])
997 pedgetable = &edgetables[2];
998 else
999 pedgetable = &edgetables[5];
1001 return;
1003 else
1005 edgetableindex = 1;
1009 if (r_p0[1] == r_p2[1])
1011 if (edgetableindex)
1012 pedgetable = &edgetables[8];
1013 else
1014 pedgetable = &edgetables[9];
1016 return;
1018 else if (r_p1[1] == r_p2[1])
1020 if (edgetableindex)
1021 pedgetable = &edgetables[10];
1022 else
1023 pedgetable = &edgetables[11];
1025 return;
1028 if (r_p0[1] > r_p2[1])
1029 edgetableindex += 2;
1031 if (r_p1[1] > r_p2[1])
1032 edgetableindex += 4;
1034 pedgetable = &edgetables[edgetableindex];
1038 #if 0
1040 void D_PolysetRecursiveDrawLine (int *lp1, int *lp2)
1042 int d;
1043 int new[6];
1044 int ofs;
1046 d = lp2[0] - lp1[0];
1047 if (d < -1 || d > 1)
1048 goto split;
1049 d = lp2[1] - lp1[1];
1050 if (d < -1 || d > 1)
1051 goto split;
1053 return; // line is completed
1055 split:
1056 // split this edge
1057 new[0] = (lp1[0] + lp2[0]) >> 1;
1058 new[1] = (lp1[1] + lp2[1]) >> 1;
1059 new[5] = (lp1[5] + lp2[5]) >> 1;
1060 new[2] = (lp1[2] + lp2[2]) >> 1;
1061 new[3] = (lp1[3] + lp2[3]) >> 1;
1062 new[4] = (lp1[4] + lp2[4]) >> 1;
1064 // draw the point
1065 ofs = d_scantable[new[1]] + new[0];
1066 if (new[5] > d_pzbuffer[ofs])
1068 int pix;
1070 d_pzbuffer[ofs] = new[5];
1071 pix = skintable[new[3]>>16][new[2]>>16];
1072 // pix = ((byte *)acolormap)[pix + (new[4] & 0xFF00)];
1073 d_viewbuffer[ofs] = pix;
1076 // recursively continue
1077 D_PolysetRecursiveDrawLine (lp1, new);
1078 D_PolysetRecursiveDrawLine (new, lp2);
1081 void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3)
1083 int d;
1084 int new[4];
1086 d = lp2[0] - lp1[0];
1087 if (d < -1 || d > 1)
1088 goto split;
1089 d = lp2[1] - lp1[1];
1090 if (d < -1 || d > 1)
1091 goto split;
1092 return;
1094 split:
1095 // split this edge
1096 new[0] = (lp1[0] + lp2[0]) >> 1;
1097 new[1] = (lp1[1] + lp2[1]) >> 1;
1098 new[5] = (lp1[5] + lp2[5]) >> 1;
1099 new[2] = (lp1[2] + lp2[2]) >> 1;
1100 new[3] = (lp1[3] + lp2[3]) >> 1;
1101 new[4] = (lp1[4] + lp2[4]) >> 1;
1103 D_PolysetRecursiveDrawLine (new, lp3);
1105 // recursively continue
1106 D_PolysetRecursiveTriangle (lp1, new, lp3);
1107 D_PolysetRecursiveTriangle (new, lp2, lp3);
1110 #endif