summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/d_polyse.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/quake/d_polyse.c')
-rw-r--r--apps/plugins/sdl/progs/quake/d_polyse.c1111
1 files changed, 1111 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/d_polyse.c b/apps/plugins/sdl/progs/quake/d_polyse.c
new file mode 100644
index 0000000000..9acd34b102
--- /dev/null
+++ b/apps/plugins/sdl/progs/quake/d_polyse.c
@@ -0,0 +1,1111 @@
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 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 !!!
33typedef struct {
34 void *pdest;
35 short *pz;
36 int count;
37 byte *ptex;
38 int sfrac, tfrac, light, zi;
39} spanpackage_t;
40
41typedef 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
53int r_p0[6], r_p1[6], r_p2[6];
54
55byte *d_pcolormap;
56
57int d_aflatcolor;
58int d_xdenom;
59
60edgetable *pedgetable;
61
62edgetable 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
78int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
79int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
80int r_zistepx, r_zistepy;
81int d_aspancount, d_countextrastep;
82
83spanpackage_t *a_spans;
84spanpackage_t *d_pedgespanpackage;
85static int ystart;
86byte *d_pdest, *d_ptex;
87short *d_pz;
88int d_sfrac, d_tfrac, d_light, d_zi;
89int d_ptexextrastep, d_sfracextrastep;
90int d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
91int d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
92int d_sfracbasestep, d_tfracbasestep;
93int d_ziextrastep, d_zibasestep;
94int d_pzextrastep, d_pzbasestep;
95
96typedef struct {
97 int quotient;
98 int remainder;
99} adivtab_t;
100
101static adivtab_t adivtab[32*32] = {
102#include "adivtab.h"
103};
104
105byte *skintable[MAX_LBM_HEIGHT];
106int skinwidth;
107byte *skinstart;
108
109void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage);
110void D_PolysetCalcGradients (int skinwidth);
111void D_DrawSubdiv (void);
112void D_DrawNonSubdiv (void);
113void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3);
114void D_PolysetSetEdgeTable (void);
115void D_RasterizeAliasPolySmooth (void);
116void D_PolysetScanLeftEdge (int height);
117
118#if !id386
119
120/*
121================
122D_PolysetDraw
123================
124*/
125void 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================
147D_PolysetDrawFinalVerts
148================
149*/
150void 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================
180D_DrawSubdiv
181================
182*/
183void 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================
241D_DrawNonSubdiv
242================
243*/
244void 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================
309D_PolysetRecursiveTriangle
310================
311*/
312void 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 {
340split3:
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
351split2:
352 temp = lp1;
353 lp1 = lp2;
354 lp2 = lp3;
355 lp3 = temp;
356
357split:
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
383nodraw:
384// recursively continue
385 D_PolysetRecursiveTriangle (lp3, lp1, new);
386 D_PolysetRecursiveTriangle (lp3, new, lp2);
387}
388
389#endif // !id386
390
391
392/*
393================
394D_PolysetUpdateTables
395================
396*/
397void 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===================
418D_PolysetScanLeftEdge
419====================
420*/
421void 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===================
487D_PolysetSetUpForLineScan
488====================
489*/
490void 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================
528D_PolysetCalcGradients
529================
530*/
531void 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#if 0
591byte gelmap[256];
592void InitGel (byte *palette)
593{
594 int i;
595 int r;
596
597 for (i=0 ; i<256 ; i++)
598 {
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;
602 }
603}
604#endif
605
606
607#if !id386
608
609/*
610================
611D_PolysetDrawSpans8
612================
613*/
614void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage)
615{
616 int lcount;
617 byte *lpdest;
618 byte *lptex;
619 int lsfrac, ltfrac;
620 int llight;
621 int lzi;
622 short *lpz;
623
624 do
625 {
626 lcount = d_aspancount - pspanpackage->count;
627
628 errorterm += erroradjustup;
629 if (errorterm >= 0)
630 {
631 d_aspancount += d_countextrastep;
632 errorterm -= erroradjustdown;
633 }
634 else
635 {
636 d_aspancount += ubasestep;
637 }
638
639 if (lcount)
640 {
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;
648
649 do
650 {
651 if ((lzi >> 16) >= *lpz)
652 {
653 *lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)];
654// gel mapping *lpdest = gelmap[*lpdest];
655 *lpz = lzi >> 16;
656 }
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)
667 {
668 lptex += r_affinetridesc.skinwidth;
669 ltfrac &= 0xFFFF;
670 }
671 } while (--lcount);
672 }
673
674 pspanpackage++;
675 } while (pspanpackage->count != -999999);
676}
677#endif // !id386
678
679
680/*
681================
682D_PolysetFillSpans8
683================
684*/
685void D_PolysetFillSpans8 (spanpackage_t *pspanpackage)
686{
687 int color;
688
689// FIXME: do z buffering
690
691 color = d_aflatcolor++;
692
693 while (1)
694 {
695 int lcount;
696 byte *lpdest;
697
698 lcount = pspanpackage->count;
699
700 if (lcount == -1)
701 return;
702
703 if (lcount)
704 {
705 lpdest = pspanpackage->pdest;
706
707 do
708 {
709 *lpdest++ = color;
710 } while (--lcount);
711 }
712
713 pspanpackage++;
714 }
715}
716
717/*
718================
719D_RasterizeAliasPolySmooth
720================
721*/
722void D_RasterizeAliasPolySmooth (void)
723{
724 int initialleftheight, initialrightheight;
725 int *plefttop, *prighttop, *pleftbottom, *prightbottom;
726 int working_lstepx, originalcount;
727
728 plefttop = pedgetable->pleftedgevert0;
729 prighttop = pedgetable->prightedgevert0;
730
731 pleftbottom = pedgetable->pleftedgevert1;
732 prightbottom = pedgetable->prightedgevert1;
733
734 initialleftheight = pleftbottom[1] - plefttop[1];
735 initialrightheight = prightbottom[1] - prighttop[1];
736
737//
738// set the s, t, and light gradients, which are consistent across the triangle
739// because being a triangle, things are affine
740//
741 D_PolysetCalcGradients (r_affinetridesc.skinwidth);
742
743//
744// rasterize the polygon
745//
746
747//
748// scan out the top (and possibly only) part of the left edge
749//
750 d_pedgespanpackage = a_spans;
751
752 ystart = plefttop[1];
753 d_aspancount = plefttop[0] - prighttop[0];
754
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];
766
767 d_pdest = (byte *)d_viewbuffer +
768 ystart * screenwidth + plefttop[0];
769 d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
770
771 if (initialleftheight == 1)
772 {
773 d_pedgespanpackage->pdest = d_pdest;
774 d_pedgespanpackage->pz = d_pz;
775 d_pedgespanpackage->count = d_aspancount;
776 d_pedgespanpackage->ptex = d_ptex;
777
778 d_pedgespanpackage->sfrac = d_sfrac;
779 d_pedgespanpackage->tfrac = d_tfrac;
780
781 // FIXME: need to clamp l, s, t, at both ends?
782 d_pedgespanpackage->light = d_light;
783 d_pedgespanpackage->zi = d_zi;
784
785 d_pedgespanpackage++;
786 }
787 else
788 {
789 D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
790 pleftbottom[0], pleftbottom[1]);
791
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
799
800 d_pdestbasestep = screenwidth + ubasestep;
801 d_pdestextrastep = d_pdestbasestep + 1;
802
803 // TODO: can reuse partial expressions here
804
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 // ceil (), but plus a little bit)
808 if (ubasestep < 0)
809 working_lstepx = r_lstepx - 1;
810 else
811 working_lstepx = r_lstepx;
812
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;
826
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;
839
840 D_PolysetScanLeftEdge (initialleftheight);
841 }
842
843//
844// scan out the bottom part of the left edge, if it exists
845//
846 if (pedgetable->numleftedges == 2)
847 {
848 int height;
849
850 plefttop = pleftbottom;
851 pleftbottom = pedgetable->pleftedgevert2;
852
853 height = pleftbottom[1] - plefttop[1];
854
855// TODO: make this a function; modularize this function in general
856
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];
865
866 d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0];
867 d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
868
869 if (height == 1)
870 {
871 d_pedgespanpackage->pdest = d_pdest;
872 d_pedgespanpackage->pz = d_pz;
873 d_pedgespanpackage->count = d_aspancount;
874 d_pedgespanpackage->ptex = d_ptex;
875
876 d_pedgespanpackage->sfrac = d_sfrac;
877 d_pedgespanpackage->tfrac = d_tfrac;
878
879 // FIXME: need to clamp l, s, t, at both ends?
880 d_pedgespanpackage->light = d_light;
881 d_pedgespanpackage->zi = d_zi;
882
883 d_pedgespanpackage++;
884 }
885 else
886 {
887 D_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
888 pleftbottom[0], pleftbottom[1]);
889
890 d_pdestbasestep = screenwidth + ubasestep;
891 d_pdestextrastep = d_pdestbasestep + 1;
892
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
900
901 if (ubasestep < 0)
902 working_lstepx = r_lstepx - 1;
903 else
904 working_lstepx = r_lstepx;
905
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;
919
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;
932
933 D_PolysetScanLeftEdge (height);
934 }
935 }
936
937// scan out the top (and possibly only) part of the right edge, updating the
938// count field
939 d_pedgespanpackage = a_spans;
940
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);
948
949// scan out the bottom part of the right edge, if it exists
950 if (pedgetable->numrightedges == 2)
951 {
952 int height;
953 spanpackage_t *pstart;
954
955 pstart = a_spans + initialrightheight;
956 pstart->count = originalcount;
957
958 d_aspancount = prightbottom[0] - prighttop[0];
959
960 prighttop = prightbottom;
961 prightbottom = pedgetable->prightedgevert2;
962
963 height = prightbottom[1] - prighttop[1];
964
965 D_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
966 prightbottom[0], prightbottom[1]);
967
968 d_countextrastep = ubasestep + 1;
969 a_spans[initialrightheight + height].count = -999999;
970 // mark end of the spanpackages
971 D_PolysetDrawSpans8 (pstart);
972 }
973}
974
975
976/*
977================
978D_PolysetSetEdgeTable
979================
980*/
981void D_PolysetSetEdgeTable (void)
982{
983 int edgetableindex;
984
985 edgetableindex = 0; // assume the vertices are already in
986 // top to bottom order
987
988//
989// determine which edges are right & left, and the order in which
990// to rasterize them
991//
992 if (r_p0[1] >= r_p1[1])
993 {
994 if (r_p0[1] == r_p1[1])
995 {
996 if (r_p0[1] < r_p2[1])
997 pedgetable = &edgetables[2];
998 else
999 pedgetable = &edgetables[5];
1000
1001 return;
1002 }
1003 else
1004 {
1005 edgetableindex = 1;
1006 }
1007 }
1008
1009 if (r_p0[1] == r_p2[1])
1010 {
1011 if (edgetableindex)
1012 pedgetable = &edgetables[8];
1013 else
1014 pedgetable = &edgetables[9];
1015
1016 return;
1017 }
1018 else if (r_p1[1] == r_p2[1])
1019 {
1020 if (edgetableindex)
1021 pedgetable = &edgetables[10];
1022 else
1023 pedgetable = &edgetables[11];
1024
1025 return;
1026 }
1027
1028 if (r_p0[1] > r_p2[1])
1029 edgetableindex += 2;
1030
1031 if (r_p1[1] > r_p2[1])
1032 edgetableindex += 4;
1033
1034 pedgetable = &edgetables[edgetableindex];
1035}
1036
1037
1038#if 0
1039
1040void D_PolysetRecursiveDrawLine (int *lp1, int *lp2)
1041{
1042 int d;
1043 int new[6];
1044 int ofs;
1045
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;
1052
1053 return; // line is completed
1054
1055split:
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;
1063
1064// draw the point
1065 ofs = d_scantable[new[1]] + new[0];
1066 if (new[5] > d_pzbuffer[ofs])
1067 {
1068 int pix;
1069
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;
1074 }
1075
1076// recursively continue
1077 D_PolysetRecursiveDrawLine (lp1, new);
1078 D_PolysetRecursiveDrawLine (new, lp2);
1079}
1080
1081void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3)
1082{
1083 int d;
1084 int new[4];
1085
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;
1093
1094split:
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;
1102
1103 D_PolysetRecursiveDrawLine (new, lp3);
1104
1105// recursively continue
1106 D_PolysetRecursiveTriangle (lp1, new, lp3);
1107 D_PolysetRecursiveTriangle (new, lp2, lp3);
1108}
1109
1110#endif
1111