1 /*
2 d_polyse.c
3
4 routines for drawing sets of polygons sharing the same texture
5 (used for Alias models)
6
7 Copyright (C) 1996-1997 Id Software, Inc.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18 See the GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to:
22
23 Free Software Foundation, Inc.
24 59 Temple Place - Suite 330
25 Boston, MA 02111-1307, USA
26
27 */
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #define NH_DEFINE
33 #include "namehack.h"
34
35 #include "QF/sys.h"
36
37 #include "d_local.h"
38 #include "r_internal.h"
39
40 static int ubasestep, errorterm, erroradjustup, erroradjustdown;
41
42 // TODO: put in span spilling to shrink list size
43 // !!! if this is changed, it must be changed in d_polysa.s too !!!
44 #define DPS_MAXSPANS MAXHEIGHT+1 // +1 for spanpackage marking end
45
46 // !!! if this is changed, it must be changed in asm_draw.h too !!!
47 typedef struct {
48 int pdest;
49 short *pz;
50 int count;
51 byte *ptex;
52 int sfrac, tfrac, light, zi;
53 } spanpackage_t;
54
55 typedef struct {
56 int isflattop;
57 int numleftedges;
58 int *pleftedgevert0;
59 int *pleftedgevert1;
60 int *pleftedgevert2;
61 int numrightedges;
62 int *prightedgevert0;
63 int *prightedgevert1;
64 int *prightedgevert2;
65 } edgetable;
66
67 static int r_p0[6], r_p1[6], r_p2[6];
68
69 static int d_xdenom;
70
71 static edgetable *pedgetable;
72
73 static edgetable edgetables[12] = {
74 {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2},
75 {0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL},
76 {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
77 {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0},
78 {0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL},
79 {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
80 {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1},
81 {0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL},
82 {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
83 {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
84 {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
85 {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
86 };
87
88 static int r_sstepx, r_tstepx, r_lstepx, r_lstepy, r_sstepy, r_tstepy;
89 static int r_zistepx, r_zistepy;
90 static int d_aspancount, d_countextrastep;
91
92 static spanpackage_t *a_spans;
93 static spanpackage_t *d_pedgespanpackage;
94 static int ystart;
95 static int d_pdest;
96 static byte *d_ptex;
97 static short *d_pz;
98 static int d_sfrac, d_tfrac, d_light, d_zi;
99 static int d_ptexextrastep, d_sfracextrastep;
100 static int d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
101 static int d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
102 static int d_sfracbasestep, d_tfracbasestep;
103 static int d_ziextrastep, d_zibasestep;
104 static int d_pzextrastep, d_pzbasestep;
105
106 typedef struct {
107 int quotient;
108 int remainder;
109 } adivtab_t;
110
111 static adivtab_t adivtab[32 * 32] = {
112 #include "adivtab.h"
113 };
114
115
116 void
sw32_D_PolysetSetEdgeTable(void)117 sw32_D_PolysetSetEdgeTable (void)
118 {
119 int edgetableindex;
120
121 // assume the vertices are already in top to bottom order
122 edgetableindex = 0;
123
124 // determine which edges are right & left, and the order in which
125 // to rasterize them
126 if (r_p0[1] >= r_p1[1]) {
127 if (r_p0[1] == r_p1[1]) {
128 if (r_p0[1] < r_p2[1])
129 pedgetable = &edgetables[2];
130 else
131 pedgetable = &edgetables[5];
132
133 return;
134 } else {
135 edgetableindex = 1;
136 }
137 }
138
139 if (r_p0[1] == r_p2[1]) {
140 if (edgetableindex)
141 pedgetable = &edgetables[8];
142 else
143 pedgetable = &edgetables[9];
144
145 return;
146 } else if (r_p1[1] == r_p2[1]) {
147 if (edgetableindex)
148 pedgetable = &edgetables[10];
149 else
150 pedgetable = &edgetables[11];
151
152 return;
153 }
154
155 if (r_p0[1] > r_p2[1])
156 edgetableindex += 2;
157
158 if (r_p1[1] > r_p2[1])
159 edgetableindex += 4;
160
161 pedgetable = &edgetables[edgetableindex];
162 }
163
164 static void
D_DrawNonSubdiv(void)165 D_DrawNonSubdiv (void)
166 {
167 mtriangle_t *ptri;
168 finalvert_t *pfv, *index0, *index1, *index2;
169 int i;
170 int lnumtriangles;
171
172 pfv = sw32_r_affinetridesc.pfinalverts;
173 ptri = sw32_r_affinetridesc.ptriangles;
174 lnumtriangles = sw32_r_affinetridesc.numtriangles;
175
176 for (i = 0; i < lnumtriangles; i++, ptri++) {
177 index0 = pfv + ptri->vertindex[0];
178 index1 = pfv + ptri->vertindex[1];
179 index2 = pfv + ptri->vertindex[2];
180
181 d_xdenom =
182 (index0->v[1] - index1->v[1]) * (index0->v[0] - index2->v[0]) -
183 (index0->v[0] - index1->v[0]) * (index0->v[1] - index2->v[1]);
184
185 if (d_xdenom >= 0)
186 continue;
187
188 r_p0[0] = index0->v[0]; // u
189 r_p0[1] = index0->v[1]; // v
190 r_p0[2] = index0->v[2]; // s
191 r_p0[3] = index0->v[3]; // t
192 r_p0[4] = index0->v[4]; // light
193 r_p0[5] = index0->v[5]; // iz
194
195 r_p1[0] = index1->v[0];
196 r_p1[1] = index1->v[1];
197 r_p1[2] = index1->v[2];
198 r_p1[3] = index1->v[3];
199 r_p1[4] = index1->v[4];
200 r_p1[5] = index1->v[5];
201
202 r_p2[0] = index2->v[0];
203 r_p2[1] = index2->v[1];
204 r_p2[2] = index2->v[2];
205 r_p2[3] = index2->v[3];
206 r_p2[4] = index2->v[4];
207 r_p2[5] = index2->v[5];
208
209 if (!ptri->facesfront) {
210 if (index0->flags & ALIAS_ONSEAM)
211 r_p0[2] += sw32_r_affinetridesc.seamfixupX16;
212 if (index1->flags & ALIAS_ONSEAM)
213 r_p1[2] += sw32_r_affinetridesc.seamfixupX16;
214 if (index2->flags & ALIAS_ONSEAM)
215 r_p2[2] += sw32_r_affinetridesc.seamfixupX16;
216 }
217
218 sw32_D_PolysetSetEdgeTable ();
219 sw32_D_RasterizeAliasPolySmooth ();
220 }
221 }
222
223 void
sw32_D_PolysetDraw(void)224 sw32_D_PolysetDraw (void)
225 {
226 spanpackage_t spans[DPS_MAXSPANS + 1 +
227 ((CACHE_SIZE - 1) / sizeof (spanpackage_t)) + 1];
228
229 // one extra because of cache line pretouching
230
231 a_spans = (spanpackage_t *)
232 (((intptr_t) &spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
233
234 D_DrawNonSubdiv ();
235 }
236
237 void
sw32_D_PolysetScanLeftEdge(int height)238 sw32_D_PolysetScanLeftEdge (int height)
239 {
240
241 do {
242 d_pedgespanpackage->pdest = d_pdest;
243 d_pedgespanpackage->pz = d_pz;
244 d_pedgespanpackage->count = d_aspancount;
245 d_pedgespanpackage->ptex = d_ptex;
246
247 d_pedgespanpackage->sfrac = d_sfrac;
248 d_pedgespanpackage->tfrac = d_tfrac;
249
250 // FIXME: need to clamp l, s, t, at both ends?
251 d_pedgespanpackage->light = d_light;
252 d_pedgespanpackage->zi = d_zi;
253
254 d_pedgespanpackage++;
255
256 errorterm += erroradjustup;
257 if (errorterm >= 0) {
258 d_pdest += d_pdestextrastep;
259 d_pz += d_pzextrastep;
260 d_aspancount += d_countextrastep;
261 d_ptex += d_ptexextrastep;
262 d_sfrac += d_sfracextrastep;
263 d_ptex += d_sfrac >> 16;
264
265 d_sfrac &= 0xFFFF;
266 d_tfrac += d_tfracextrastep;
267 if (d_tfrac & 0x10000) {
268 d_ptex += sw32_r_affinetridesc.skinwidth;
269 d_tfrac &= 0xFFFF;
270 }
271 d_light += d_lightextrastep;
272 d_zi += d_ziextrastep;
273 errorterm -= erroradjustdown;
274 } else {
275 d_pdest += d_pdestbasestep;
276 d_pz += d_pzbasestep;
277 d_aspancount += ubasestep;
278 d_ptex += d_ptexbasestep;
279 d_sfrac += d_sfracbasestep;
280 d_ptex += d_sfrac >> 16;
281 d_sfrac &= 0xFFFF;
282 d_tfrac += d_tfracbasestep;
283 if (d_tfrac & 0x10000) {
284 d_ptex += sw32_r_affinetridesc.skinwidth;
285 d_tfrac &= 0xFFFF;
286 }
287 d_light += d_lightbasestep;
288 d_zi += d_zibasestep;
289 }
290 } while (--height);
291 }
292
293 static void
D_PolysetSetUpForLineScan(fixed8_t startvertu,fixed8_t startvertv,fixed8_t endvertu,fixed8_t endvertv)294 D_PolysetSetUpForLineScan (fixed8_t startvertu, fixed8_t startvertv,
295 fixed8_t endvertu, fixed8_t endvertv)
296 {
297 double dm, dn;
298 int tm, tn;
299 adivtab_t *ptemp;
300
301 // TODO: implement x86 version
302
303 errorterm = -1;
304
305 tm = endvertu - startvertu;
306 tn = endvertv - startvertv;
307
308 if (((tm <= 16) && (tm >= -15)) && ((tn <= 16) && (tn >= -15))) {
309 ptemp = &adivtab[((tm + 15) << 5) + (tn + 15)];
310 ubasestep = ptemp->quotient;
311 erroradjustup = ptemp->remainder;
312 erroradjustdown = tn;
313 } else {
314 dm = (double) tm;
315 dn = (double) tn;
316
317 FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
318
319 erroradjustdown = dn;
320 }
321 }
322
323 void
sw32_D_PolysetCalcGradients(int skinwidth)324 sw32_D_PolysetCalcGradients (int skinwidth)
325 {
326 float xstepdenominv, ystepdenominv, t0, t1;
327 float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
328
329 p00_minus_p20 = r_p0[0] - r_p2[0];
330 p01_minus_p21 = r_p0[1] - r_p2[1];
331 p10_minus_p20 = r_p1[0] - r_p2[0];
332 p11_minus_p21 = r_p1[1] - r_p2[1];
333
334 xstepdenominv = 1.0 / (float) d_xdenom;
335
336 ystepdenominv = -xstepdenominv;
337
338 // ceil () for light so positive steps are exaggerated, negative steps
339 // diminished, pushing us away from underflow toward overflow. Underflow
340 // is very visible, overflow is very unlikely, because of ambient lighting
341 t0 = r_p0[4] - r_p2[4];
342 t1 = r_p1[4] - r_p2[4];
343 r_lstepx = (int)
344 ceil ((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
345 r_lstepy = (int)
346 ceil ((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
347
348 t0 = r_p0[2] - r_p2[2];
349 t1 = r_p1[2] - r_p2[2];
350 r_sstepx = (int) ((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
351 xstepdenominv);
352 r_sstepy = (int) ((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
353 ystepdenominv);
354
355 t0 = r_p0[3] - r_p2[3];
356 t1 = r_p1[3] - r_p2[3];
357 r_tstepx = (int) ((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
358 xstepdenominv);
359 r_tstepy = (int) ((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
360 ystepdenominv);
361
362 t0 = r_p0[5] - r_p2[5];
363 t1 = r_p1[5] - r_p2[5];
364 r_zistepx = (int) ((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
365 xstepdenominv);
366 r_zistepy = (int) ((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
367 ystepdenominv);
368
369 // a_sstepxfrac = r_sstepx & 0xFFFF;
370 // a_tstepxfrac = r_tstepx & 0xFFFF;
371
372 // a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
373 }
374
375
376 static void
D_PolysetDrawSpans(spanpackage_t * pspanpackage)377 D_PolysetDrawSpans (spanpackage_t * pspanpackage)
378 {
379 int i, j, texscantable[2*MAX_LBM_HEIGHT], *texscan;
380 // LordHavoc: compute skin row table
381 for (i = 0, j = -sw32_r_affinetridesc.skinheight * sw32_r_affinetridesc.skinwidth;
382 i < sw32_r_affinetridesc.skinheight*2;i++, j += sw32_r_affinetridesc.skinwidth)
383 texscantable[i] = j;
384 texscan = texscantable + sw32_r_affinetridesc.skinheight;
385
386 switch(sw32_r_pixbytes) {
387 case 1:
388 {
389 int lcount, count = 0;
390 byte *lpdest;
391 byte *lptex;
392 int lsfrac, ltfrac;
393 int llight;
394 int lzi;
395 short *lpz;
396
397 do
398 {
399 lcount = d_aspancount - pspanpackage->count;
400
401 errorterm += erroradjustup;
402 if (errorterm >= 0)
403 {
404 d_aspancount += d_countextrastep;
405 errorterm -= erroradjustdown;
406 }
407 else
408 d_aspancount += ubasestep;
409
410 if (lcount)
411 {
412 lpdest = (byte *) sw32_d_viewbuffer + pspanpackage->pdest;
413 lptex = pspanpackage->ptex;
414 lpz = pspanpackage->pz;
415 lsfrac = pspanpackage->sfrac;
416 ltfrac = pspanpackage->tfrac;
417 llight = pspanpackage->light;
418 lzi = pspanpackage->zi;
419
420 // LordHavoc: optimized zbuffer check (switchs between
421 // loops when state changes, and quickly skips groups
422 // of hidden pixels)
423 do
424 {
425 if ((lzi >> 16) < *lpz) // hidden
426 {
427 count = 0;
428 goto skiploop8;
429 }
430 drawloop8:
431 *lpz++ = lzi >> 16;
432 *lpdest++ = ((byte *)sw32_acolormap)
433 [(llight & 0xFF00) | lptex[texscan[ltfrac >> 16] +
434 (lsfrac >> 16)]];
435 lzi += r_zistepx;
436 lsfrac += r_sstepx;
437 ltfrac += r_tstepx;
438 llight += r_lstepx;
439 }
440 while (--lcount);
441 goto done8;
442
443 do
444 {
445 if ((lzi >> 16) >= *lpz) // draw
446 {
447 lsfrac += r_sstepx * count;
448 ltfrac += r_tstepx * count;
449 llight += r_lstepx * count;
450 lpdest += count;
451 goto drawloop8;
452 }
453 skiploop8:
454 count++;
455 lzi += r_zistepx;
456 lpz++;
457 }
458 while (--lcount);
459 done8: ;
460 }
461
462 pspanpackage++;
463 }
464 while (pspanpackage->count != -999999);
465 }
466 break;
467
468 case 2:
469 {
470 int lcount, count = 0;
471 short *lpdest;
472 byte *lptex;
473 int lsfrac, ltfrac;
474 int llight;
475 int lzi;
476 short *lpz;
477
478 do
479 {
480 lcount = d_aspancount - pspanpackage->count;
481
482 errorterm += erroradjustup;
483 if (errorterm >= 0)
484 {
485 d_aspancount += d_countextrastep;
486 errorterm -= erroradjustdown;
487 }
488 else
489 d_aspancount += ubasestep;
490
491 if (lcount)
492 {
493 lpdest = (short *) sw32_d_viewbuffer + pspanpackage->pdest;
494 lptex = pspanpackage->ptex;
495 lpz = pspanpackage->pz;
496 lsfrac = pspanpackage->sfrac;
497 ltfrac = pspanpackage->tfrac;
498 llight = pspanpackage->light;
499 lzi = pspanpackage->zi;
500
501 do
502 {
503 if ((lzi >> 16) < *lpz) // hidden
504 {
505 count = 0;
506 goto skiploop16;
507 }
508 drawloop16:
509 *lpz++ = lzi >> 16;
510 *lpdest++ = ((short *)sw32_acolormap)[(llight & 0xFF00) | lptex[texscan[ltfrac >> 16] + (lsfrac >> 16)]];
511 lzi += r_zistepx;
512 lsfrac += r_sstepx;
513 ltfrac += r_tstepx;
514 llight += r_lstepx;
515 }
516 while (--lcount);
517 goto done16;
518
519 do
520 {
521 if ((lzi >> 16) >= *lpz) // draw
522 {
523 lsfrac += r_sstepx * count;
524 ltfrac += r_tstepx * count;
525 llight += r_lstepx * count;
526 lpdest += count;
527 goto drawloop16;
528 }
529 skiploop16:
530 count++;
531 lzi += r_zistepx;
532 lpz++;
533 }
534 while (--lcount);
535 done16: ;
536 }
537
538 pspanpackage++;
539 }
540 while (pspanpackage->count != -999999);
541 }
542 break;
543
544 case 4:
545 {
546 int lcount, count = 0;
547 int *lpdest;
548 byte *lptex;
549 int lsfrac, ltfrac;
550 int llight;
551 int lzi;
552 short *lpz;
553
554 do
555 {
556 lcount = d_aspancount - pspanpackage->count;
557
558 errorterm += erroradjustup;
559 if (errorterm >= 0)
560 {
561 d_aspancount += d_countextrastep;
562 errorterm -= erroradjustdown;
563 }
564 else
565 d_aspancount += ubasestep;
566
567 if (lcount)
568 {
569 lpdest = (int *) sw32_d_viewbuffer + pspanpackage->pdest;
570 lptex = pspanpackage->ptex;
571 lpz = pspanpackage->pz;
572 lsfrac = pspanpackage->sfrac;
573 ltfrac = pspanpackage->tfrac;
574 llight = pspanpackage->light;
575 lzi = pspanpackage->zi;
576
577 do
578 {
579 if ((lzi >> 16) < *lpz) // hidden
580 {
581 count = 0;
582 goto skiploop32;
583 }
584 drawloop32:
585 *lpz++ = lzi >> 16;
586 *lpdest++ =
587 vid.colormap32[(llight & 0xFF00) |
588 lptex[texscan[ltfrac >> 16] +
589 (lsfrac >> 16)]];
590 lzi += r_zistepx;
591 lsfrac += r_sstepx;
592 ltfrac += r_tstepx;
593 llight += r_lstepx;
594 }
595 while (--lcount);
596 goto done32;
597
598 do
599 {
600 if ((lzi >> 16) >= *lpz) // draw
601 {
602 lsfrac += r_sstepx * count;
603 ltfrac += r_tstepx * count;
604 llight += r_lstepx * count;
605 lpdest += count;
606 goto drawloop32;
607 }
608 skiploop32:
609 count++;
610 lzi += r_zistepx;
611 lpz++;
612 }
613 while (--lcount);
614 done32: ;
615 }
616
617 pspanpackage++;
618 }
619 while (pspanpackage->count != -999999);
620 }
621 break;
622
623 default:
624 Sys_Error("D_PolysetDrawSpans: unsupported r_pixbytes %i",
625 sw32_r_pixbytes);
626 }
627 }
628
629
630 void
sw32_D_RasterizeAliasPolySmooth(void)631 sw32_D_RasterizeAliasPolySmooth (void)
632 {
633 int initialleftheight, initialrightheight;
634 int *plefttop, *prighttop, *pleftbottom, *prightbottom;
635 int working_lstepx, originalcount;
636
637 plefttop = pedgetable->pleftedgevert0;
638 prighttop = pedgetable->prightedgevert0;
639
640 pleftbottom = pedgetable->pleftedgevert1;
641 prightbottom = pedgetable->prightedgevert1;
642
643 initialleftheight = pleftbottom[1] - plefttop[1];
644 initialrightheight = prightbottom[1] - prighttop[1];
645
646 // set the s, t, and light gradients, which are consistent across the
647 // triangle, because being a triangle, things are affine
648 sw32_D_PolysetCalcGradients (sw32_r_affinetridesc.skinwidth);
649
650 // rasterize the polygon
651
652 // scan out the top (and possibly only) part of the left edge
653 D_PolysetSetUpForLineScan (plefttop[0], plefttop[1],
654 pleftbottom[0], pleftbottom[1]);
655
656 d_pedgespanpackage = a_spans;
657
658 ystart = plefttop[1];
659 d_aspancount = plefttop[0] - prighttop[0];
660
661 d_ptex = (byte *) sw32_r_affinetridesc.pskin + (plefttop[2] >> 16) +
662 (plefttop[3] >> 16) * sw32_r_affinetridesc.skinwidth;
663 d_sfrac = plefttop[2] & 0xFFFF;
664 d_tfrac = plefttop[3] & 0xFFFF;
665 d_pzbasestep = sw32_d_zwidth + ubasestep;
666 d_pzextrastep = d_pzbasestep + 1;
667 d_light = plefttop[4];
668 d_zi = plefttop[5];
669
670 d_pdestbasestep = sw32_screenwidth + ubasestep;
671 d_pdestextrastep = d_pdestbasestep + 1;
672 // LordHavoc: d_pdest has been changed to pixel offset
673 d_pdest = ystart * sw32_screenwidth + plefttop[0];
674 d_pz = sw32_d_pzbuffer + ystart * sw32_d_zwidth + plefttop[0];
675
676 // TODO: can reuse partial expressions here
677
678 // for negative steps in x along left edge, bias toward overflow rather
679 // than underflow (sort of turning the floor () we did in the gradient
680 // calcs into ceil (), but plus a little bit)
681 if (ubasestep < 0)
682 working_lstepx = r_lstepx - 1;
683 else
684 working_lstepx = r_lstepx;
685
686 d_countextrastep = ubasestep + 1;
687 d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
688 ((r_tstepy + r_tstepx * ubasestep) >> 16) * sw32_r_affinetridesc.skinwidth;
689 d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
690 d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
691 d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
692 d_zibasestep = r_zistepy + r_zistepx * ubasestep;
693
694 d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
695 ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
696 sw32_r_affinetridesc.skinwidth;
697 d_sfracextrastep = (r_sstepy + r_sstepx * d_countextrastep) & 0xFFFF;
698 d_tfracextrastep = (r_tstepy + r_tstepx * d_countextrastep) & 0xFFFF;
699 d_lightextrastep = d_lightbasestep + working_lstepx;
700 d_ziextrastep = d_zibasestep + r_zistepx;
701
702 sw32_D_PolysetScanLeftEdge (initialleftheight);
703
704 // scan out the bottom part of the left edge, if it exists
705 if (pedgetable->numleftedges == 2) {
706 int height;
707
708 plefttop = pleftbottom;
709 pleftbottom = pedgetable->pleftedgevert2;
710
711 D_PolysetSetUpForLineScan (plefttop[0], plefttop[1],
712 pleftbottom[0], pleftbottom[1]);
713
714 height = pleftbottom[1] - plefttop[1];
715
716 // TODO: make this a function; modularize this function in general
717
718 ystart = plefttop[1];
719 d_aspancount = plefttop[0] - prighttop[0];
720 d_ptex = (byte *) sw32_r_affinetridesc.pskin + (plefttop[2] >> 16) +
721 (plefttop[3] >> 16) * sw32_r_affinetridesc.skinwidth;
722 d_sfrac = 0;
723 d_tfrac = 0;
724 d_light = plefttop[4];
725 d_zi = plefttop[5];
726
727 d_pdestbasestep = sw32_screenwidth + ubasestep;
728 d_pdestextrastep = d_pdestbasestep + 1;
729 // LordHavoc: d_pdest and relatives have been changed to pixel
730 // offsets into framebuffer
731 d_pdest = ystart * sw32_screenwidth + plefttop[0];
732 d_pzbasestep = sw32_d_zwidth + ubasestep;
733 d_pzextrastep = d_pzbasestep + 1;
734 d_pz = sw32_d_pzbuffer + ystart * sw32_d_zwidth + plefttop[0];
735
736 if (ubasestep < 0)
737 working_lstepx = r_lstepx - 1;
738 else
739 working_lstepx = r_lstepx;
740
741 d_countextrastep = ubasestep + 1;
742 d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
743 ((r_tstepy + r_tstepx * ubasestep) >> 16) *
744 sw32_r_affinetridesc.skinwidth;
745 d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
746 d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
747 d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
748 d_zibasestep = r_zistepy + r_zistepx * ubasestep;
749
750 d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
751 ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
752 sw32_r_affinetridesc.skinwidth;
753 d_sfracextrastep = (r_sstepy + r_sstepx * d_countextrastep) & 0xFFFF;
754 d_tfracextrastep = (r_tstepy + r_tstepx * d_countextrastep) & 0xFFFF;
755 d_lightextrastep = d_lightbasestep + working_lstepx;
756 d_ziextrastep = d_zibasestep + r_zistepx;
757
758 sw32_D_PolysetScanLeftEdge (height);
759 }
760 // scan out the top (and possibly only) part of the right edge, updating
761 // the count field
762 d_pedgespanpackage = a_spans;
763
764 D_PolysetSetUpForLineScan (prighttop[0], prighttop[1],
765 prightbottom[0], prightbottom[1]);
766 d_aspancount = 0;
767 d_countextrastep = ubasestep + 1;
768 originalcount = a_spans[initialrightheight].count;
769 a_spans[initialrightheight].count = -999999; // mark end of the
770 // spanpackages
771 D_PolysetDrawSpans (a_spans);
772
773 // scan out the bottom part of the right edge, if it exists
774 if (pedgetable->numrightedges == 2) {
775 int height;
776 spanpackage_t *pstart;
777
778 pstart = a_spans + initialrightheight;
779 pstart->count = originalcount;
780
781 d_aspancount = prightbottom[0] - prighttop[0];
782
783 prighttop = prightbottom;
784 prightbottom = pedgetable->prightedgevert2;
785
786 height = prightbottom[1] - prighttop[1];
787
788 D_PolysetSetUpForLineScan (prighttop[0], prighttop[1],
789 prightbottom[0], prightbottom[1]);
790
791 d_countextrastep = ubasestep + 1;
792 a_spans[initialrightheight + height].count = -999999;
793 // mark end of the spanpackages
794 D_PolysetDrawSpans (pstart);
795 }
796 }
797