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)
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 !!!
38 int sfrac
, tfrac
, light
, zi
;
53 int r_p0
[6], r_p1
[6], r_p2
[6];
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
;
86 byte
*d_pdest
, *d_ptex
;
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
;
101 static adivtab_t adivtab
[32*32] = {
105 byte
*skintable
[MAX_LBM_HEIGHT
];
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
);
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
)
147 D_PolysetDrawFinalVerts
150 void D_PolysetDrawFinalVerts (finalvert_t
*fv
, int numverts
)
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
))
163 zbuf
= zspantable
[fv
->v
[1]] + fv
->v
[0];
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
;
183 void D_DrawSubdiv (void)
186 finalvert_t
*pfv
, *index0
, *index1
, *index2
;
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)
208 d_pcolormap
= &((byte
*)acolormap
)[index0
->v
[4] & 0xFF00];
210 if (ptri
[i
].facesfront
)
212 D_PolysetRecursiveTriangle(index0
->v
, index1
->v
, index2
->v
);
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
);
244 void D_DrawNonSubdiv (void)
247 finalvert_t
*pfv
, *index0
, *index1
, *index2
;
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]);
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 ();
309 D_PolysetRecursiveTriangle
312 void D_PolysetRecursiveTriangle (int *lp1
, int *lp2
, int *lp3
)
349 return; // entire tri is filled
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
368 if ((lp2
[1] == lp1
[1]) && (lp2
[0] < lp1
[0]))
373 zbuf
= zspantable
[new[1]] + new[0];
379 pix
= d_pcolormap
[skintable
[new[3]>>16][new[2]>>16]];
380 d_viewbuffer
[d_scantable
[new[1]] + new[0]] = pix
;
384 // recursively continue
385 D_PolysetRecursiveTriangle (lp3
, lp1
, new);
386 D_PolysetRecursiveTriangle (lp3
, new, lp2
);
394 D_PolysetUpdateTables
397 void D_PolysetUpdateTables (void)
402 if (r_affinetridesc
.skinwidth
!= skinwidth
||
403 r_affinetridesc
.pskin
!= skinstart
)
405 skinwidth
= r_affinetridesc
.skinwidth
;
406 skinstart
= r_affinetridesc
.pskin
;
408 for (i
=0 ; i
<MAX_LBM_HEIGHT
; i
++, s
+=skinwidth
)
418 D_PolysetScanLeftEdge
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
;
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;
451 d_tfrac
+= d_tfracextrastep
;
452 if (d_tfrac
& 0x10000)
454 d_ptex
+= r_affinetridesc
.skinwidth
;
457 d_light
+= d_lightextrastep
;
458 d_zi
+= d_ziextrastep
;
459 errorterm
-= erroradjustdown
;
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;
470 d_tfrac
+= d_tfracbasestep
;
471 if (d_tfrac
& 0x10000)
473 d_ptex
+= r_affinetridesc
.skinwidth
;
476 d_light
+= d_lightbasestep
;
477 d_zi
+= d_zibasestep
;
487 D_PolysetSetUpForLineScan
490 void D_PolysetSetUpForLineScan(fixed8_t startvertu
, fixed8_t startvertv
,
491 fixed8_t endvertu
, fixed8_t endvertv
)
497 // TODO: implement x86 version
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
;
517 FloorDivMod (dm
, dn
, &ubasestep
, &erroradjustup
);
519 erroradjustdown
= dn
;
528 D_PolysetCalcGradients
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];
551 ceilf((t1
* p01_minus_p21
- t0
* p11_minus_p21
) * xstepdenominv
);
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
) *
559 r_sstepy
= (int)((t1
* p00_minus_p20
- t0
* p10_minus_p20
) *
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
) *
566 r_tstepy
= (int)((t1
* p00_minus_p20
- t0
* p10_minus_p20
) *
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
) *
573 r_zistepy
= (int)((t1
* p00_minus_p20
- t0
* p10_minus_p20
) *
577 a_sstepxfrac
= r_sstepx
<< 16;
578 a_tstepxfrac
= r_tstepx
<< 16;
580 a_sstepxfrac
= r_sstepx
& 0xFFFF;
581 a_tstepxfrac
= r_tstepx
& 0xFFFF;
584 a_ststepxwhole
= skinwidth
* (r_tstepx
>> 16) + (r_sstepx
>> 16);
592 void InitGel (byte
*palette
)
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
;
614 void D_PolysetDrawSpans8 (spanpackage_t
*pspanpackage
)
626 lcount
= d_aspancount
- pspanpackage
->count
;
628 errorterm
+= erroradjustup
;
631 d_aspancount
+= d_countextrastep
;
632 errorterm
-= erroradjustdown
;
636 d_aspancount
+= ubasestep
;
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];
661 lptex
+= a_ststepxwhole
;
662 lsfrac
+= a_sstepxfrac
;
663 lptex
+= lsfrac
>> 16;
665 ltfrac
+= a_tstepxfrac
;
666 if (ltfrac
& 0x10000)
668 lptex
+= r_affinetridesc
.skinwidth
;
675 } while (pspanpackage
->count
!= -999999);
685 void D_PolysetFillSpans8 (spanpackage_t
*pspanpackage
)
689 // FIXME: do z buffering
691 color
= d_aflatcolor
++;
698 lcount
= pspanpackage
->count
;
705 lpdest
= pspanpackage
->pdest
;
719 D_RasterizeAliasPolySmooth
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
;
758 d_sfrac
= (plefttop
[2] & 0xFFFF) << 16;
759 d_tfrac
= (plefttop
[3] & 0xFFFF) << 16;
761 d_sfrac
= plefttop
[2] & 0xFFFF;
762 d_tfrac
= plefttop
[3] & 0xFFFF;
764 d_light
= plefttop
[4];
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
++;
789 D_PolysetSetUpForLineScan(plefttop
[0], plefttop
[1],
790 pleftbottom
[0], pleftbottom
[1]);
793 d_pzbasestep
= (d_zwidth
+ ubasestep
) << 1;
794 d_pzextrastep
= d_pzbasestep
+ 2;
796 d_pzbasestep
= d_zwidth
+ ubasestep
;
797 d_pzextrastep
= d_pzbasestep
+ 1;
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)
809 working_lstepx
= r_lstepx
- 1;
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
;
818 d_sfracbasestep
= (r_sstepy
+ r_sstepx
* ubasestep
) << 16;
819 d_tfracbasestep
= (r_tstepy
+ r_tstepx
* ubasestep
) << 16;
821 d_sfracbasestep
= (r_sstepy
+ r_sstepx
* ubasestep
) & 0xFFFF;
822 d_tfracbasestep
= (r_tstepy
+ r_tstepx
* ubasestep
) & 0xFFFF;
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
;
831 d_sfracextrastep
= (r_sstepy
+ r_sstepx
*d_countextrastep
) << 16;
832 d_tfracextrastep
= (r_tstepy
+ r_tstepx
*d_countextrastep
) << 16;
834 d_sfracextrastep
= (r_sstepy
+ r_sstepx
*d_countextrastep
) & 0xFFFF;
835 d_tfracextrastep
= (r_tstepy
+ r_tstepx
*d_countextrastep
) & 0xFFFF;
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)
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
;
863 d_light
= plefttop
[4];
866 d_pdest
= (byte
*)d_viewbuffer
+ ystart
* screenwidth
+ plefttop
[0];
867 d_pz
= d_pzbuffer
+ ystart
* d_zwidth
+ plefttop
[0];
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
++;
887 D_PolysetSetUpForLineScan(plefttop
[0], plefttop
[1],
888 pleftbottom
[0], pleftbottom
[1]);
890 d_pdestbasestep
= screenwidth
+ ubasestep
;
891 d_pdestextrastep
= d_pdestbasestep
+ 1;
894 d_pzbasestep
= (d_zwidth
+ ubasestep
) << 1;
895 d_pzextrastep
= d_pzbasestep
+ 2;
897 d_pzbasestep
= d_zwidth
+ ubasestep
;
898 d_pzextrastep
= d_pzbasestep
+ 1;
902 working_lstepx
= r_lstepx
- 1;
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
;
911 d_sfracbasestep
= (r_sstepy
+ r_sstepx
* ubasestep
) << 16;
912 d_tfracbasestep
= (r_tstepy
+ r_tstepx
* ubasestep
) << 16;
914 d_sfracbasestep
= (r_sstepy
+ r_sstepx
* ubasestep
) & 0xFFFF;
915 d_tfracbasestep
= (r_tstepy
+ r_tstepx
* ubasestep
) & 0xFFFF;
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
;
924 d_sfracextrastep
= ((r_sstepy
+r_sstepx
*d_countextrastep
) & 0xFFFF)<<16;
925 d_tfracextrastep
= ((r_tstepy
+r_tstepx
*d_countextrastep
) & 0xFFFF)<<16;
927 d_sfracextrastep
= (r_sstepy
+r_sstepx
*d_countextrastep
) & 0xFFFF;
928 d_tfracextrastep
= (r_tstepy
+r_tstepx
*d_countextrastep
) & 0xFFFF;
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
939 d_pedgespanpackage
= a_spans
;
941 D_PolysetSetUpForLineScan(prighttop
[0], prighttop
[1],
942 prightbottom
[0], prightbottom
[1]);
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)
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
);
978 D_PolysetSetEdgeTable
981 void D_PolysetSetEdgeTable (void)
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
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];
999 pedgetable
= &edgetables
[5];
1009 if (r_p0
[1] == r_p2
[1])
1012 pedgetable
= &edgetables
[8];
1014 pedgetable
= &edgetables
[9];
1018 else if (r_p1
[1] == r_p2
[1])
1021 pedgetable
= &edgetables
[10];
1023 pedgetable
= &edgetables
[11];
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
];
1040 void D_PolysetRecursiveDrawLine (int *lp1
, int *lp2
)
1046 d
= lp2
[0] - lp1
[0];
1047 if (d
< -1 || d
> 1)
1049 d
= lp2
[1] - lp1
[1];
1050 if (d
< -1 || d
> 1)
1053 return; // line is completed
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;
1065 ofs
= d_scantable
[new[1]] + new[0];
1066 if (new[5] > d_pzbuffer
[ofs
])
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
)
1086 d
= lp2
[0] - lp1
[0];
1087 if (d
< -1 || d
> 1)
1089 d
= lp2
[1] - lp1
[1];
1090 if (d
< -1 || d
> 1)
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
);