1 /*
2  * d_polyset.c - routines for drawing sets of polygons sharing the same
3  * texture (used for Alias models.)
4  *
5  * $Id: d_polyse.c 5976 2017-09-16 20:03:22Z sezero $
6  *
7  * Copyright (C) 1996-1997  Id Software, Inc.
8  * Copyright (C) 1997-1998  Raven Software Corp.
9  * C versions of several asm functions:  Juraj Styk <jurajstyk@host.sk>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or (at
14  * your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but
17  * WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * See the GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along
23  * with this program; if not, write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
25  */
26 
27 #include "quakedef.h"
28 #include "r_local.h"
29 #include "d_local.h"
30 
31 ASM_LINKAGE_BEGIN
32 int		r_p0[6], r_p1[6], r_p2[6];
33 
34 byte		*d_pcolormap;
35 
36 int		d_aflatcolor;
37 int		d_xdenom;
38 ASM_LINKAGE_END
39 
40 static edgetable_t	*pedgetable;
41 
42 static edgetable_t	edgetables[12] =
43 {
44 	{ 0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },
45 	{ 0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL },
46 	{ 1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL },
47 	{ 0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },
48 	{ 0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL },
49 	{ 0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL },
50 	{ 0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },
51 	{ 0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL },
52 	{ 0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL },
53 	{ 1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL },
54 	{ 1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL },
55 	{ 0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL }
56 };
57 
58 ASM_LINKAGE_BEGIN
59 // FIXME: some of these can become statics
60 int		a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
61 int		r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
62 int		r_zistepx, r_zistepy;
63 int		d_aspancount, d_countextrastep;
64 
65 spanpackage_t	*a_spans;
66 spanpackage_t	*d_pedgespanpackage;
67 byte		*d_pdest, *d_ptex;
68 short		*d_pz;
69 int		d_sfrac, d_tfrac, d_light, d_zi;
70 int		d_ptexextrastep, d_sfracextrastep;
71 int		d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
72 int		d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
73 int		d_sfracbasestep, d_tfracbasestep;
74 int		d_ziextrastep, d_zibasestep;
75 int		d_pzextrastep, d_pzbasestep;
76 
77 byte	*skintable[MAX_SKIN_HEIGHT];
78 ASM_LINKAGE_END
79 int		skinwidth;
80 byte	*skinstart;
81 
82 static int	ystart;
83 
84 typedef struct {
85 	int		quotient;
86 	int		remainder;
87 } adivtab_t;
88 
89 static adivtab_t	adivtab[32*32] =
90 {
91 #include "adivtab.h"
92 };
93 
94 #if !id386
95 static spanpackage_t	spans[DPS_MAXSPANS + 1 + ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1];
96 						/* one extra because of cache line pretouching */
97 #if !id68k
98 static void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage);
99 #endif
100 static void D_PolysetDrawSpans8T (spanpackage_t *pspanpackage);
101 static void D_PolysetDrawSpans8T2 (spanpackage_t *pspanpackage);
102 static void D_PolysetDrawSpans8T3 (spanpackage_t *pspanpackage);
103 static void D_PolysetDrawSpans8T5 (spanpackage_t *pspanpackage);
104 #endif
105 
106 
107 #if	!id386
108 
109 /*
110 ================
111 D_PolysetDrawFinalVerts
112 ================
113 */
114 #if !id68k
do_PolysetDrawFinalVerts(finalvert_t * pv)115 static inline void do_PolysetDrawFinalVerts (finalvert_t *pv)
116 {
117 	int		z;
118 	short		*zbuf;
119 
120 	// valid triangle coordinates for filling can include the bottom and
121 	// right clip edges, due to the fill rule; these shouldn't be drawn
122 	if (pv->v[0] < r_refdef.vrectright && pv->v[1] < r_refdef.vrectbottom)
123 	{
124 		z = pv->v[5]>>16;
125 		zbuf = zspantable[pv->v[1]] + pv->v[0];
126 		if (z >= *zbuf)
127 		{
128 			unsigned int	pix;
129 
130 			*zbuf = z;
131 			pix = skintable[pv->v[3]>>16][pv->v[2]>>16];
132 			pix = ((byte *)acolormap)[pix + (pv->v[4] & 0xFF00)];
133 			d_viewbuffer[d_scantable[pv->v[1]] + pv->v[0]] = pix;
134 		}
135 	}
136 }
137 #endif /* !id68k */
138 
do_PolysetDrawFinalVertsT(finalvert_t * pv)139 static inline void do_PolysetDrawFinalVertsT (finalvert_t *pv)
140 {
141 	int		z;
142 	short		*zbuf;
143 	unsigned int	color_map_idx;
144 
145 	// valid triangle coordinates for filling can include the bottom and
146 	// right clip edges, due to the fill rule; these shouldn't be drawn
147 	if (pv->v[0] < r_refdef.vrectright && pv->v[1] < r_refdef.vrectbottom)
148 	{
149 		z = pv->v[5]>>16;
150 		zbuf = zspantable[pv->v[1]] + pv->v[0];
151 		if (z >= *zbuf)
152 		{
153 			color_map_idx = skintable[pv->v[3]>>16][pv->v[2]>>16];
154 
155 			if (color_map_idx != 0)
156 			{
157 				unsigned int	pix, pix2;
158 
159 				*zbuf = z;
160 				pix = ((byte *)acolormap)[color_map_idx + (pv->v[4] & 0xFF00)];
161 				pix2 = d_viewbuffer[d_scantable[pv->v[1]] + pv->v[0]];
162 				pix = mainTransTable[(pix<<8) + pix2];
163 				d_viewbuffer[d_scantable[pv->v[1]] + pv->v[0]] = pix;
164 			}
165 		}
166 	}
167 }
168 
do_PolysetDrawFinalVertsT2(finalvert_t * pv)169 static inline void do_PolysetDrawFinalVertsT2 (finalvert_t *pv)
170 {
171 	int		z;
172 	short		*zbuf;
173 	unsigned int	color_map_idx;
174 
175 	// valid triangle coordinates for filling can include the bottom and
176 	// right clip edges, due to the fill rule; these shouldn't be drawn
177 	if (pv->v[0] < r_refdef.vrectright && pv->v[1] < r_refdef.vrectbottom)
178 	{
179 		z = pv->v[5]>>16;
180 		zbuf = zspantable[pv->v[1]] + pv->v[0];
181 		if (z >= *zbuf)
182 		{
183 			color_map_idx = skintable[pv->v[3]>>16][pv->v[2]>>16];
184 
185 			if (color_map_idx != 0)
186 			{
187 				unsigned int	pix, pix2;
188 
189 				*zbuf = z;
190 				pix = ((byte *)acolormap)[color_map_idx + (pv->v[4] & 0xFF00)];
191 				if (color_map_idx % 2 == 0)
192 				{
193 					d_viewbuffer[d_scantable[pv->v[1]] + pv->v[0]] = pix;
194 				}
195 				else
196 				{
197 					pix2 = d_viewbuffer[d_scantable[pv->v[1]] + pv->v[0]];
198 					pix = mainTransTable[(pix<<8) + pix2];
199 					d_viewbuffer[d_scantable[pv->v[1]] + pv->v[0]] = pix;
200 				}
201 			}
202 		}
203 	}
204 }
205 
do_PolysetDrawFinalVertsT3(finalvert_t * pv)206 static inline void do_PolysetDrawFinalVertsT3 (finalvert_t *pv)
207 {
208 	int		z;
209 	short		*zbuf;
210 	unsigned int	color_map_idx;
211 
212 	// valid triangle coordinates for filling can include the bottom and
213 	// right clip edges, due to the fill rule; these shouldn't be drawn
214 	if (pv->v[0] < r_refdef.vrectright && pv->v[1] < r_refdef.vrectbottom)
215 	{
216 		z = pv->v[5]>>16;
217 		zbuf = zspantable[pv->v[1]] + pv->v[0];
218 		if (z >= *zbuf)
219 		{
220 			color_map_idx = skintable[pv->v[3]>>16][pv->v[2]>>16];
221 
222 			if (color_map_idx != 0)
223 			{
224 				unsigned int	pix;
225 
226 				*zbuf = z;
227 				pix = ((byte *)acolormap)[color_map_idx + (pv->v[4] & 0xFF00)];
228 				d_viewbuffer[d_scantable[pv->v[1]] + pv->v[0]] = pix;
229 			}
230 		}
231 	}
232 }
233 
do_PolysetDrawFinalVertsT5(finalvert_t * pv)234 static inline void do_PolysetDrawFinalVertsT5 (finalvert_t *pv)
235 {
236 	int		z;
237 	short		*zbuf;
238 	unsigned int	color_map_idx;
239 
240 	// valid triangle coordinates for filling can include the bottom and
241 	// right clip edges, due to the fill rule; these shouldn't be drawn
242 	if (pv->v[0] < r_refdef.vrectright && pv->v[1] < r_refdef.vrectbottom)
243 	{
244 		z = pv->v[5]>>16;
245 		zbuf = zspantable[pv->v[1]] + pv->v[0];
246 		if (z >= *zbuf)
247 		{
248 			color_map_idx = skintable[pv->v[3]>>16][pv->v[2]>>16];
249 
250 			if (color_map_idx != 0)
251 			{
252 				unsigned int	pix, pix2;
253 
254 				*zbuf = z;
255 				pix = color_map_idx;
256 				pix2 = d_viewbuffer[d_scantable[pv->v[1]] + pv->v[0]];
257 				pix = transTable[(pix<<8) + pix2];
258 				d_viewbuffer[d_scantable[pv->v[1]] + pv->v[0]] = pix;
259 			}
260 		}
261 	}
262 }
263 
264 #if !id68k
D_PolysetDrawFinalVerts(finalvert_t * pv1,finalvert_t * pv2,finalvert_t * pv3)265 void D_PolysetDrawFinalVerts (finalvert_t *pv1, finalvert_t *pv2, finalvert_t *pv3)
266 {
267 	do_PolysetDrawFinalVerts (pv1);
268 	do_PolysetDrawFinalVerts (pv2);
269 	do_PolysetDrawFinalVerts (pv3);
270 }
271 #endif
272 
D_PolysetDrawFinalVertsT(finalvert_t * pv1,finalvert_t * pv2,finalvert_t * pv3)273 void D_PolysetDrawFinalVertsT (finalvert_t *pv1, finalvert_t *pv2, finalvert_t *pv3)
274 {
275 	do_PolysetDrawFinalVertsT (pv1);
276 	do_PolysetDrawFinalVertsT (pv2);
277 	do_PolysetDrawFinalVertsT (pv3);
278 }
279 
D_PolysetDrawFinalVertsT2(finalvert_t * pv1,finalvert_t * pv2,finalvert_t * pv3)280 void D_PolysetDrawFinalVertsT2 (finalvert_t *pv1, finalvert_t *pv2, finalvert_t *pv3)
281 {
282 	do_PolysetDrawFinalVertsT2 (pv1);
283 	do_PolysetDrawFinalVertsT2 (pv2);
284 	do_PolysetDrawFinalVertsT2 (pv3);
285 }
286 
D_PolysetDrawFinalVertsT3(finalvert_t * pv1,finalvert_t * pv2,finalvert_t * pv3)287 void D_PolysetDrawFinalVertsT3 (finalvert_t *pv1, finalvert_t *pv2, finalvert_t *pv3)
288 {
289 	do_PolysetDrawFinalVertsT3 (pv1);
290 	do_PolysetDrawFinalVertsT3 (pv2);
291 	do_PolysetDrawFinalVertsT3 (pv3);
292 }
293 
D_PolysetDrawFinalVertsT5(finalvert_t * pv1,finalvert_t * pv2,finalvert_t * pv3)294 void D_PolysetDrawFinalVertsT5 (finalvert_t *pv1, finalvert_t *pv2, finalvert_t *pv3)
295 {
296 	do_PolysetDrawFinalVertsT5 (pv1);
297 	do_PolysetDrawFinalVertsT5 (pv2);
298 	do_PolysetDrawFinalVertsT5 (pv3);
299 }
300 
301 
302 /*
303 ================
304 D_PolysetRecursiveTriangle
305 ================
306 */
307 #if !id68k
D_PolysetRecursiveTriangle(int * lp1,int * lp2,int * lp3)308 static void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3)
309 {
310 	int		*temp;
311 	int		d;
312 	int		new_p[6];
313 	int		z;
314 	short		*zbuf;
315 
316 	d = lp2[0] - lp1[0];
317 	if (d < -1 || d > 1)
318 		goto split;
319 	d = lp2[1] - lp1[1];
320 	if (d < -1 || d > 1)
321 		goto split;
322 
323 	d = lp3[0] - lp2[0];
324 	if (d < -1 || d > 1)
325 		goto split2;
326 	d = lp3[1] - lp2[1];
327 	if (d < -1 || d > 1)
328 		goto split2;
329 
330 	d = lp1[0] - lp3[0];
331 	if (d < -1 || d > 1)
332 		goto split3;
333 	d = lp1[1] - lp3[1];
334 	if (d < -1 || d > 1)
335 	{
336 split3:
337 		temp = lp1;
338 		lp1 = lp3;
339 		lp3 = lp2;
340 		lp2 = temp;
341 
342 		goto split;
343 	}
344 
345 	return; // entire tri is filled
346 
347 split2:
348 	temp = lp1;
349 	lp1 = lp2;
350 	lp2 = lp3;
351 	lp3 = temp;
352 
353 split:
354 // split this edge
355 	new_p[0] = (lp1[0] + lp2[0]) >> 1;
356 	new_p[1] = (lp1[1] + lp2[1]) >> 1;
357 	new_p[2] = (lp1[2] + lp2[2]) >> 1;
358 	new_p[3] = (lp1[3] + lp2[3]) >> 1;
359 	new_p[5] = (lp1[5] + lp2[5]) >> 1;
360 
361 // draw the point if splitting a leading edge
362 	if (lp2[1] > lp1[1])
363 		goto nodraw;
364 	if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
365 		goto nodraw;
366 
367 	z = new_p[5]>>16;
368 	zbuf = zspantable[new_p[1]] + new_p[0];
369 	if (z >= *zbuf)
370 	{
371 		unsigned int	pix;
372 
373 		*zbuf = z;
374 		pix = d_pcolormap[skintable[new_p[3]>>16][new_p[2]>>16]];
375 		d_viewbuffer[d_scantable[new_p[1]] + new_p[0]] = pix;
376 	}
377 
378 nodraw:
379 // recursively continue
380 	D_PolysetRecursiveTriangle (lp3, lp1, new_p);
381 	D_PolysetRecursiveTriangle (lp3, new_p, lp2);
382 }
383 #endif /* !id68k */
384 
D_PolysetRecursiveTriangleT(int * lp1,int * lp2,int * lp3)385 static void D_PolysetRecursiveTriangleT (int *lp1, int *lp2, int *lp3)
386 {
387 	int		*temp;
388 	int		d;
389 	int		new_p[6];
390 	int		z;
391 	short		*zbuf;
392 	unsigned int	color_map_idx;
393 
394 	d = lp2[0] - lp1[0];
395 	if (d < -1 || d > 1)
396 		goto split;
397 	d = lp2[1] - lp1[1];
398 	if (d < -1 || d > 1)
399 		goto split;
400 
401 	d = lp3[0] - lp2[0];
402 	if (d < -1 || d > 1)
403 		goto split2;
404 	d = lp3[1] - lp2[1];
405 	if (d < -1 || d > 1)
406 		goto split2;
407 
408 	d = lp1[0] - lp3[0];
409 	if (d < -1 || d > 1)
410 		goto split3;
411 	d = lp1[1] - lp3[1];
412 	if (d < -1 || d > 1)
413 	{
414 split3:
415 		temp = lp1;
416 		lp1 = lp3;
417 		lp3 = lp2;
418 		lp2 = temp;
419 
420 		goto split;
421 	}
422 
423 	return; // entire tri is filled
424 
425 split2:
426 	temp = lp1;
427 	lp1 = lp2;
428 	lp2 = lp3;
429 	lp3 = temp;
430 
431 split:
432 // split this edge
433 	new_p[0] = (lp1[0] + lp2[0]) >> 1;
434 	new_p[1] = (lp1[1] + lp2[1]) >> 1;
435 	new_p[2] = (lp1[2] + lp2[2]) >> 1;
436 	new_p[3] = (lp1[3] + lp2[3]) >> 1;
437 	new_p[5] = (lp1[5] + lp2[5]) >> 1;
438 
439 // draw the point if splitting a leading edge
440 	if (lp2[1] > lp1[1])
441 		goto nodraw;
442 	if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
443 		goto nodraw;
444 
445 	z = new_p[5]>>16;
446 	zbuf = zspantable[new_p[1]] + new_p[0];
447 	if (z >= *zbuf)
448 	{
449 		color_map_idx = skintable[new_p[3]>>16][new_p[2]>>16];
450 
451 		if (color_map_idx != 0)
452 		{
453 			unsigned int	pix, pix2;
454 
455 			*zbuf = z;
456 			pix = d_pcolormap[color_map_idx];
457 			pix2 = d_viewbuffer[d_scantable[new_p[1]] + new_p[0]];
458 			pix = mainTransTable[(pix<<8) + pix2];
459 			d_viewbuffer[d_scantable[new_p[1]] + new_p[0]] = pix;
460 		}
461 	}
462 
463 nodraw:
464 // recursively continue
465 	D_PolysetRecursiveTriangleT (lp3, lp1, new_p);
466 	D_PolysetRecursiveTriangleT (lp3, new_p, lp2);
467 }
468 
D_PolysetRecursiveTriangleT2(int * lp1,int * lp2,int * lp3)469 static void D_PolysetRecursiveTriangleT2 (int *lp1, int *lp2, int *lp3)
470 {
471 	int		*temp;
472 	int		d;
473 	int		new_p[6];
474 	int		z;
475 	short		*zbuf;
476 	unsigned int	color_map_idx;
477 
478 	d = lp2[0] - lp1[0];
479 	if (d < -1 || d > 1)
480 		goto split;
481 	d = lp2[1] - lp1[1];
482 	if (d < -1 || d > 1)
483 		goto split;
484 
485 	d = lp3[0] - lp2[0];
486 	if (d < -1 || d > 1)
487 		goto split2;
488 	d = lp3[1] - lp2[1];
489 	if (d < -1 || d > 1)
490 		goto split2;
491 
492 	d = lp1[0] - lp3[0];
493 	if (d < -1 || d > 1)
494 		goto split3;
495 	d = lp1[1] - lp3[1];
496 	if (d < -1 || d > 1)
497 	{
498 split3:
499 		temp = lp1;
500 		lp1 = lp3;
501 		lp3 = lp2;
502 		lp2 = temp;
503 
504 		goto split;
505 	}
506 
507 	return; // entire tri is filled
508 
509 split2:
510 	temp = lp1;
511 	lp1 = lp2;
512 	lp2 = lp3;
513 	lp3 = temp;
514 
515 split:
516 // split this edge
517 	new_p[0] = (lp1[0] + lp2[0]) >> 1;
518 	new_p[1] = (lp1[1] + lp2[1]) >> 1;
519 	new_p[2] = (lp1[2] + lp2[2]) >> 1;
520 	new_p[3] = (lp1[3] + lp2[3]) >> 1;
521 	new_p[5] = (lp1[5] + lp2[5]) >> 1;
522 
523 // draw the point if splitting a leading edge
524 	if (lp2[1] > lp1[1])
525 		goto nodraw;
526 	if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
527 		goto nodraw;
528 
529 	z = new_p[5]>>16;
530 	zbuf = zspantable[new_p[1]] + new_p[0];
531 	if (z >= *zbuf)
532 	{
533 		color_map_idx = skintable[new_p[3]>>16][new_p[2]>>16];
534 
535 		if (color_map_idx != 0)
536 		{
537 			unsigned int	pix, pix2;
538 
539 			*zbuf = z;
540 			pix = d_pcolormap[color_map_idx];
541 
542 			if (color_map_idx % 2 == 0)
543 			{
544 				d_viewbuffer[d_scantable[new_p[1]] + new_p[0]] = pix;
545 			}
546 			else
547 			{
548 				pix2 = d_viewbuffer[d_scantable[new_p[1]] + new_p[0]];
549 				pix = mainTransTable[(pix<<8) + pix2];
550 				d_viewbuffer[d_scantable[new_p[1]] + new_p[0]] = pix;
551 			}
552 		}
553 	}
554 
555 nodraw:
556 // recursively continue
557 	D_PolysetRecursiveTriangleT2 (lp3, lp1, new_p);
558 	D_PolysetRecursiveTriangleT2 (lp3, new_p, lp2);
559 }
560 
D_PolysetRecursiveTriangleT3(int * lp1,int * lp2,int * lp3)561 static void D_PolysetRecursiveTriangleT3 (int *lp1, int *lp2, int *lp3)
562 {
563 	int		*temp;
564 	int		d;
565 	int		new_p[6];
566 	int		z;
567 	short		*zbuf;
568 	unsigned int	color_map_idx;
569 
570 	d = lp2[0] - lp1[0];
571 	if (d < -1 || d > 1)
572 		goto split;
573 	d = lp2[1] - lp1[1];
574 	if (d < -1 || d > 1)
575 		goto split;
576 
577 	d = lp3[0] - lp2[0];
578 	if (d < -1 || d > 1)
579 		goto split2;
580 	d = lp3[1] - lp2[1];
581 	if (d < -1 || d > 1)
582 		goto split2;
583 
584 	d = lp1[0] - lp3[0];
585 	if (d < -1 || d > 1)
586 		goto split3;
587 	d = lp1[1] - lp3[1];
588 	if (d < -1 || d > 1)
589 	{
590 split3:
591 		temp = lp1;
592 		lp1 = lp3;
593 		lp3 = lp2;
594 		lp2 = temp;
595 
596 		goto split;
597 	}
598 
599 	return; // entire tri is filled
600 
601 split2:
602 	temp = lp1;
603 	lp1 = lp2;
604 	lp2 = lp3;
605 	lp3 = temp;
606 
607 split:
608 // split this edge
609 	new_p[0] = (lp1[0] + lp2[0]) >> 1;
610 	new_p[1] = (lp1[1] + lp2[1]) >> 1;
611 	new_p[2] = (lp1[2] + lp2[2]) >> 1;
612 	new_p[3] = (lp1[3] + lp2[3]) >> 1;
613 	new_p[5] = (lp1[5] + lp2[5]) >> 1;
614 
615 // draw the point if splitting a leading edge
616 	if (lp2[1] > lp1[1])
617 		goto nodraw;
618 	if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
619 		goto nodraw;
620 
621 	z = new_p[5]>>16;
622 	zbuf = zspantable[new_p[1]] + new_p[0];
623 	if (z >= *zbuf)
624 	{
625 		color_map_idx = skintable[new_p[3]>>16][new_p[2]>>16];
626 
627 		if (color_map_idx != 0)
628 		{
629 			unsigned int	pix;
630 
631 			*zbuf = z;
632 			pix = d_pcolormap[color_map_idx];
633 			d_viewbuffer[d_scantable[new_p[1]] + new_p[0]] = pix;
634 		}
635 	}
636 
637 nodraw:
638 // recursively continue
639 	D_PolysetRecursiveTriangleT3 (lp3, lp1, new_p);
640 	D_PolysetRecursiveTriangleT3 (lp3, new_p, lp2);
641 }
642 
D_PolysetRecursiveTriangleT5(int * lp1,int * lp2,int * lp3)643 static void D_PolysetRecursiveTriangleT5 (int *lp1, int *lp2, int *lp3)
644 {
645 	int		*temp;
646 	int		d;
647 	int		new_p[6];
648 	int		z;
649 	short		*zbuf;
650 	unsigned int	color_map_idx;
651 
652 	d = lp2[0] - lp1[0];
653 	if (d < -1 || d > 1)
654 		goto split;
655 	d = lp2[1] - lp1[1];
656 	if (d < -1 || d > 1)
657 		goto split;
658 
659 	d = lp3[0] - lp2[0];
660 	if (d < -1 || d > 1)
661 		goto split2;
662 	d = lp3[1] - lp2[1];
663 	if (d < -1 || d > 1)
664 		goto split2;
665 
666 	d = lp1[0] - lp3[0];
667 	if (d < -1 || d > 1)
668 		goto split3;
669 	d = lp1[1] - lp3[1];
670 	if (d < -1 || d > 1)
671 	{
672 split3:
673 		temp = lp1;
674 		lp1 = lp3;
675 		lp3 = lp2;
676 		lp2 = temp;
677 
678 		goto split;
679 	}
680 
681 	return; // entire tri is filled
682 
683 split2:
684 	temp = lp1;
685 	lp1 = lp2;
686 	lp2 = lp3;
687 	lp3 = temp;
688 
689 split:
690 // split this edge
691 	new_p[0] = (lp1[0] + lp2[0]) >> 1;
692 	new_p[1] = (lp1[1] + lp2[1]) >> 1;
693 	new_p[2] = (lp1[2] + lp2[2]) >> 1;
694 	new_p[3] = (lp1[3] + lp2[3]) >> 1;
695 	new_p[5] = (lp1[5] + lp2[5]) >> 1;
696 
697 // draw the point if splitting a leading edge
698 	if (lp2[1] > lp1[1])
699 		goto nodraw;
700 	if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))
701 		goto nodraw;
702 
703 	z = new_p[5]>>16;
704 	zbuf = zspantable[new_p[1]] + new_p[0];
705 	if (z >= *zbuf)
706 	{
707 		color_map_idx = skintable[new_p[3]>>16][new_p[2]>>16];
708 
709 		if (color_map_idx != 0)
710 		{
711 			unsigned int	pix, pix2;
712 
713 			*zbuf = z;
714 			pix = color_map_idx;
715 			pix2 = d_viewbuffer[d_scantable[new_p[1]] + new_p[0]];
716 			pix = transTable[(pix<<8) + pix2];
717 			d_viewbuffer[d_scantable[new_p[1]] + new_p[0]] = pix;
718 		}
719 	}
720 
721 nodraw:
722 // recursively continue
723 	D_PolysetRecursiveTriangleT5 (lp3, lp1, new_p);
724 	D_PolysetRecursiveTriangleT5 (lp3, new_p, lp2);
725 }
726 
727 /*
728 ================
729 D_DrawSubdiv
730 ================
731 */
D_DrawSubdiv(void)732 static void D_DrawSubdiv (void)
733 {
734 	mtriangle_t		*ptri;
735 	finalvert_t		*pfv, *index0, *index1, *index2;
736 	int			i, lnumtriangles;
737 
738 	pfv = r_affinetridesc.pfinalverts;
739 	ptri = r_affinetridesc.ptriangles;
740 	lnumtriangles = r_affinetridesc.numtriangles;
741 
742 	for (i = 0; i < lnumtriangles; i++)
743 	{
744 		index0 = pfv + ptri[i].vertindex[0];
745 		index1 = pfv + ptri[i].vertindex[1];
746 		index2 = pfv + ptri[i].vertindex[2];
747 
748 		if (((index0->v[1]-index1->v[1]) * (index0->v[0]-index2->v[0]) -
749 			 (index0->v[0]-index1->v[0]) * (index0->v[1]-index2->v[1])) >= 0)
750 		{
751 			continue;
752 		}
753 
754 		d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00];
755 
756 		if (ptri[i].facesfront)
757 		{
758 			D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
759 		}
760 		else
761 		{
762 			int		s0, s1, s2;
763 
764 			s0 = index0->v[2];
765 			s1 = index1->v[2];
766 			s2 = index2->v[2];
767 
768 			if (index0->flags & ALIAS_ONSEAM)
769 				index0->v[2] += r_affinetridesc.seamfixupX16;
770 			if (index1->flags & ALIAS_ONSEAM)
771 				index1->v[2] += r_affinetridesc.seamfixupX16;
772 			if (index2->flags & ALIAS_ONSEAM)
773 				index2->v[2] += r_affinetridesc.seamfixupX16;
774 
775 			D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);
776 
777 			index0->v[2] = s0;
778 			index1->v[2] = s1;
779 			index2->v[2] = s2;
780 		}
781 	}
782 }
783 
D_DrawSubdivT(void)784 static void D_DrawSubdivT (void)
785 {
786 	mtriangle_t		*ptri;
787 	finalvert_t		*pfv, *index0, *index1, *index2;
788 	int			i, lnumtriangles;
789 
790 	pfv = r_affinetridesc.pfinalverts;
791 	ptri = r_affinetridesc.ptriangles;
792 	lnumtriangles = r_affinetridesc.numtriangles;
793 
794 	for (i = 0; i < lnumtriangles; i++)
795 	{
796 		index0 = pfv + ptri[i].vertindex[0];
797 		index1 = pfv + ptri[i].vertindex[1];
798 		index2 = pfv + ptri[i].vertindex[2];
799 
800 		if (((index0->v[1]-index1->v[1]) * (index0->v[0]-index2->v[0]) -
801 			 (index0->v[0]-index1->v[0]) * (index0->v[1]-index2->v[1])) >= 0)
802 		{
803 			continue;
804 		}
805 
806 		d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00];
807 
808 		if (ptri[i].facesfront)
809 		{
810 			D_PolysetRecursiveTriangleT(index0->v, index1->v, index2->v);
811 		}
812 		else
813 		{
814 			int		s0, s1, s2;
815 
816 			s0 = index0->v[2];
817 			s1 = index1->v[2];
818 			s2 = index2->v[2];
819 
820 			if (index0->flags & ALIAS_ONSEAM)
821 				index0->v[2] += r_affinetridesc.seamfixupX16;
822 			if (index1->flags & ALIAS_ONSEAM)
823 				index1->v[2] += r_affinetridesc.seamfixupX16;
824 			if (index2->flags & ALIAS_ONSEAM)
825 				index2->v[2] += r_affinetridesc.seamfixupX16;
826 
827 			D_PolysetRecursiveTriangleT(index0->v, index1->v, index2->v);
828 
829 			index0->v[2] = s0;
830 			index1->v[2] = s1;
831 			index2->v[2] = s2;
832 		}
833 	}
834 }
835 
D_DrawSubdivT2(void)836 static void D_DrawSubdivT2 (void)
837 {
838 	mtriangle_t		*ptri;
839 	finalvert_t		*pfv, *index0, *index1, *index2;
840 	int			i, lnumtriangles;
841 
842 	pfv = r_affinetridesc.pfinalverts;
843 	ptri = r_affinetridesc.ptriangles;
844 	lnumtriangles = r_affinetridesc.numtriangles;
845 
846 	for (i = 0; i < lnumtriangles; i++)
847 	{
848 		index0 = pfv + ptri[i].vertindex[0];
849 		index1 = pfv + ptri[i].vertindex[1];
850 		index2 = pfv + ptri[i].vertindex[2];
851 
852 		if (((index0->v[1]-index1->v[1]) * (index0->v[0]-index2->v[0]) -
853 			 (index0->v[0]-index1->v[0]) * (index0->v[1]-index2->v[1])) >= 0)
854 		{
855 			continue;
856 		}
857 
858 		d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00];
859 
860 		if (ptri[i].facesfront)
861 		{
862 			D_PolysetRecursiveTriangleT2(index0->v, index1->v, index2->v);
863 		}
864 		else
865 		{
866 			int		s0, s1, s2;
867 
868 			s0 = index0->v[2];
869 			s1 = index1->v[2];
870 			s2 = index2->v[2];
871 
872 			if (index0->flags & ALIAS_ONSEAM)
873 				index0->v[2] += r_affinetridesc.seamfixupX16;
874 			if (index1->flags & ALIAS_ONSEAM)
875 				index1->v[2] += r_affinetridesc.seamfixupX16;
876 			if (index2->flags & ALIAS_ONSEAM)
877 				index2->v[2] += r_affinetridesc.seamfixupX16;
878 
879 			D_PolysetRecursiveTriangleT2(index0->v, index1->v, index2->v);
880 
881 			index0->v[2] = s0;
882 			index1->v[2] = s1;
883 			index2->v[2] = s2;
884 		}
885 	}
886 }
887 
D_DrawSubdivT3(void)888 static void D_DrawSubdivT3 (void)
889 {
890 	mtriangle_t		*ptri;
891 	finalvert_t		*pfv, *index0, *index1, *index2;
892 	int			i, lnumtriangles;
893 
894 	pfv = r_affinetridesc.pfinalverts;
895 	ptri = r_affinetridesc.ptriangles;
896 	lnumtriangles = r_affinetridesc.numtriangles;
897 
898 	for (i = 0; i < lnumtriangles; i++)
899 	{
900 		index0 = pfv + ptri[i].vertindex[0];
901 		index1 = pfv + ptri[i].vertindex[1];
902 		index2 = pfv + ptri[i].vertindex[2];
903 
904 		if (((index0->v[1]-index1->v[1]) * (index0->v[0]-index2->v[0]) -
905 			 (index0->v[0]-index1->v[0]) * (index0->v[1]-index2->v[1])) >= 0)
906 		{
907 			continue;
908 		}
909 
910 		d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00];
911 
912 		if (ptri[i].facesfront)
913 		{
914 			D_PolysetRecursiveTriangleT3(index0->v, index1->v, index2->v);
915 		}
916 		else
917 		{
918 			int		s0, s1, s2;
919 
920 			s0 = index0->v[2];
921 			s1 = index1->v[2];
922 			s2 = index2->v[2];
923 
924 			if (index0->flags & ALIAS_ONSEAM)
925 				index0->v[2] += r_affinetridesc.seamfixupX16;
926 			if (index1->flags & ALIAS_ONSEAM)
927 				index1->v[2] += r_affinetridesc.seamfixupX16;
928 			if (index2->flags & ALIAS_ONSEAM)
929 				index2->v[2] += r_affinetridesc.seamfixupX16;
930 
931 			D_PolysetRecursiveTriangleT3(index0->v, index1->v, index2->v);
932 
933 			index0->v[2] = s0;
934 			index1->v[2] = s1;
935 			index2->v[2] = s2;
936 		}
937 	}
938 }
939 
D_DrawSubdivT5(void)940 static void D_DrawSubdivT5 (void)
941 {
942 	mtriangle_t		*ptri;
943 	finalvert_t		*pfv, *index0, *index1, *index2;
944 	int			i, lnumtriangles;
945 
946 	pfv = r_affinetridesc.pfinalverts;
947 	ptri = r_affinetridesc.ptriangles;
948 	lnumtriangles = r_affinetridesc.numtriangles;
949 
950 	for (i = 0; i < lnumtriangles; i++)
951 	{
952 		index0 = pfv + ptri[i].vertindex[0];
953 		index1 = pfv + ptri[i].vertindex[1];
954 		index2 = pfv + ptri[i].vertindex[2];
955 
956 		if (((index0->v[1]-index1->v[1]) * (index0->v[0]-index2->v[0]) -
957 			 (index0->v[0]-index1->v[0]) * (index0->v[1]-index2->v[1])) >= 0)
958 		{
959 			continue;
960 		}
961 
962 		if (ptri[i].facesfront)
963 		{
964 			D_PolysetRecursiveTriangleT5(index0->v, index1->v, index2->v);
965 		}
966 		else
967 		{
968 			int		s0, s1, s2;
969 
970 			s0 = index0->v[2];
971 			s1 = index1->v[2];
972 			s2 = index2->v[2];
973 
974 			if (index0->flags & ALIAS_ONSEAM)
975 				index0->v[2] += r_affinetridesc.seamfixupX16;
976 			if (index1->flags & ALIAS_ONSEAM)
977 				index1->v[2] += r_affinetridesc.seamfixupX16;
978 			if (index2->flags & ALIAS_ONSEAM)
979 				index2->v[2] += r_affinetridesc.seamfixupX16;
980 
981 			D_PolysetRecursiveTriangleT5(index0->v, index1->v, index2->v);
982 
983 			index0->v[2] = s0;
984 			index1->v[2] = s1;
985 			index2->v[2] = s2;
986 		}
987 	}
988 }
989 
990 
991 /*
992 ================
993 D_DrawNonSubdiv
994 ================
995 */
D_DrawNonSubdiv(void)996 static void D_DrawNonSubdiv (void)
997 {
998 	mtriangle_t		*ptri;
999 	finalvert_t		*pfv, *index0, *index1, *index2;
1000 	int			i, lnumtriangles;
1001 
1002 	pfv = r_affinetridesc.pfinalverts;
1003 	ptri = r_affinetridesc.ptriangles;
1004 	lnumtriangles = r_affinetridesc.numtriangles;
1005 
1006 	for (i = 0; i < lnumtriangles; i++, ptri++)
1007 	{
1008 		index0 = pfv + ptri->vertindex[0];
1009 		index1 = pfv + ptri->vertindex[1];
1010 		index2 = pfv + ptri->vertindex[2];
1011 
1012 		d_xdenom = (index0->v[1]-index1->v[1]) * (index0->v[0]-index2->v[0]) -
1013 				(index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]);
1014 
1015 		if (d_xdenom >= 0)
1016 		{
1017 			continue;
1018 		}
1019 
1020 		r_p0[0] = index0->v[0];		// u
1021 		r_p0[1] = index0->v[1];		// v
1022 		r_p0[2] = index0->v[2];		// s
1023 		r_p0[3] = index0->v[3];		// t
1024 		r_p0[4] = index0->v[4];		// light
1025 		r_p0[5] = index0->v[5];		// iz
1026 
1027 		r_p1[0] = index1->v[0];
1028 		r_p1[1] = index1->v[1];
1029 		r_p1[2] = index1->v[2];
1030 		r_p1[3] = index1->v[3];
1031 		r_p1[4] = index1->v[4];
1032 		r_p1[5] = index1->v[5];
1033 
1034 		r_p2[0] = index2->v[0];
1035 		r_p2[1] = index2->v[1];
1036 		r_p2[2] = index2->v[2];
1037 		r_p2[3] = index2->v[3];
1038 		r_p2[4] = index2->v[4];
1039 		r_p2[5] = index2->v[5];
1040 
1041 		if (!ptri->facesfront)
1042 		{
1043 			if (index0->flags & ALIAS_ONSEAM)
1044 				r_p0[2] += r_affinetridesc.seamfixupX16;
1045 			if (index1->flags & ALIAS_ONSEAM)
1046 				r_p1[2] += r_affinetridesc.seamfixupX16;
1047 			if (index2->flags & ALIAS_ONSEAM)
1048 				r_p2[2] += r_affinetridesc.seamfixupX16;
1049 		}
1050 
1051 		D_PolysetSetEdgeTable ();
1052 		D_RasterizeAliasPolySmooth ();
1053 	}
1054 }
1055 
1056 
1057 /*
1058 ================
1059 D_PolysetDraw
1060 ================
1061 */
D_PolysetDraw(void)1062 void D_PolysetDraw (void)
1063 {
1064 	a_spans = (spanpackage_t *)
1065 			(((intptr_t)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
1066 
1067 	if (r_affinetridesc.drawtype)
1068 	{
1069 		D_DrawSubdiv ();
1070 	}
1071 	else
1072 	{
1073 		D_DrawNonSubdiv ();
1074 	}
1075 }
1076 
D_PolysetDrawT(void)1077 void D_PolysetDrawT (void)
1078 {
1079 	a_spans = (spanpackage_t *)
1080 			(((intptr_t)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
1081 
1082 	if (r_affinetridesc.drawtype)
1083 	{
1084 		D_DrawSubdivT ();
1085 	}
1086 	else
1087 	{
1088 		D_DrawNonSubdiv ();
1089 	}
1090 }
1091 
D_PolysetDrawT2(void)1092 void D_PolysetDrawT2 (void)
1093 {
1094 	a_spans = (spanpackage_t *)
1095 			(((intptr_t)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
1096 
1097 	if (r_affinetridesc.drawtype)
1098 	{
1099 		D_DrawSubdivT2 ();
1100 	}
1101 	else
1102 	{
1103 		D_DrawNonSubdiv ();
1104 	}
1105 }
1106 
D_PolysetDrawT3(void)1107 void D_PolysetDrawT3 (void)
1108 {
1109 	a_spans = (spanpackage_t *)
1110 			(((intptr_t)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
1111 
1112 	if (r_affinetridesc.drawtype)
1113 	{
1114 		D_DrawSubdivT3 ();
1115 	}
1116 	else
1117 	{
1118 		D_DrawNonSubdiv ();
1119 	}
1120 }
1121 
D_PolysetDrawT5(void)1122 void D_PolysetDrawT5 (void)
1123 {
1124 	a_spans = (spanpackage_t *)
1125 			(((intptr_t)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
1126 
1127 	if (r_affinetridesc.drawtype)
1128 	{
1129 		D_DrawSubdivT5 ();
1130 	}
1131 	else
1132 	{
1133 		D_DrawNonSubdiv ();
1134 	}
1135 }
1136 
1137 #endif	/* !id386 */
1138 
1139 
1140 /*
1141 ================
1142 D_PolysetUpdateTables
1143 ================
1144 */
D_PolysetUpdateTables(void)1145 void D_PolysetUpdateTables (void)
1146 {
1147 	int		i;
1148 	byte		*s;
1149 
1150 	if (r_affinetridesc.skinwidth != skinwidth ||
1151 		r_affinetridesc.pskin != skinstart)
1152 	{
1153 		skinwidth = r_affinetridesc.skinwidth;
1154 		skinstart = (byte *) r_affinetridesc.pskin;
1155 		s = skinstart;
1156 		for (i = 0; i < MAX_SKIN_HEIGHT; i++, s += skinwidth)
1157 			skintable[i] = s;
1158 	}
1159 }
1160 
1161 
1162 #if	!id386
1163 
1164 #define D_PolysetScanLeftEdgeT		D_PolysetScanLeftEdge
1165 #define D_PolysetScanLeftEdgeT2		D_PolysetScanLeftEdge
1166 #define D_PolysetScanLeftEdgeT3		D_PolysetScanLeftEdge
1167 #define D_PolysetScanLeftEdgeT5		D_PolysetScanLeftEdge
1168 /*
1169 ===================
1170 D_PolysetScanLeftEdge
1171 ====================
1172 */
D_PolysetScanLeftEdge(int height)1173 static void D_PolysetScanLeftEdge (int height)
1174 {
1175 	do
1176 	{
1177 		d_pedgespanpackage->pdest = d_pdest;
1178 		d_pedgespanpackage->pz = d_pz;
1179 		d_pedgespanpackage->count = d_aspancount;
1180 		d_pedgespanpackage->ptex = d_ptex;
1181 
1182 		d_pedgespanpackage->sfrac = d_sfrac;
1183 		d_pedgespanpackage->tfrac = d_tfrac;
1184 
1185 	// FIXME: need to clamp l, s, t, at both ends?
1186 		d_pedgespanpackage->light = d_light;
1187 		d_pedgespanpackage->zi = d_zi;
1188 
1189 		d_pedgespanpackage++;
1190 
1191 		errorterm += erroradjustup;
1192 		if (errorterm >= 0)
1193 		{
1194 			d_pdest += d_pdestextrastep;
1195 			d_pz += d_pzextrastep;
1196 			d_aspancount += d_countextrastep;
1197 			d_ptex += d_ptexextrastep;
1198 			d_sfrac += d_sfracextrastep;
1199 			d_ptex += d_sfrac >> 16;
1200 
1201 			d_sfrac &= 0xFFFF;
1202 			d_tfrac += d_tfracextrastep;
1203 			if (d_tfrac & 0x10000)
1204 			{
1205 				d_ptex += r_affinetridesc.skinwidth;
1206 				d_tfrac &= 0xFFFF;
1207 			}
1208 			d_light += d_lightextrastep;
1209 			d_zi += d_ziextrastep;
1210 			errorterm -= erroradjustdown;
1211 		}
1212 		else
1213 		{
1214 			d_pdest += d_pdestbasestep;
1215 			d_pz += d_pzbasestep;
1216 			d_aspancount += ubasestep;
1217 			d_ptex += d_ptexbasestep;
1218 			d_sfrac += d_sfracbasestep;
1219 			d_ptex += d_sfrac >> 16;
1220 			d_sfrac &= 0xFFFF;
1221 			d_tfrac += d_tfracbasestep;
1222 			if (d_tfrac & 0x10000)
1223 			{
1224 				d_ptex += r_affinetridesc.skinwidth;
1225 				d_tfrac &= 0xFFFF;
1226 			}
1227 			d_light += d_lightbasestep;
1228 			d_zi += d_zibasestep;
1229 		}
1230 	} while (--height);
1231 }
1232 
1233 #endif	/* !id386 */
1234 
1235 
1236 /*
1237 ===================
1238 D_PolysetSetUpForLineScan
1239 ====================
1240 */
D_PolysetSetUpForLineScan(fixed8_t startvertu,fixed8_t startvertv,fixed8_t endvertu,fixed8_t endvertv)1241 static void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
1242 					fixed8_t endvertu, fixed8_t endvertv)
1243 {
1244 	double		dm, dn;
1245 	int		tm, tn;
1246 	adivtab_t	*ptemp;
1247 
1248 // TODO: implement x86 version
1249 
1250 	errorterm = -1;
1251 
1252 	tm = endvertu - startvertu;
1253 	tn = endvertv - startvertv;
1254 
1255 	if (((tm <= 16) && (tm >= -15)) &&
1256 		((tn <= 16) && (tn >= -15)))
1257 	{
1258 		ptemp = &adivtab[((tm+15) << 5) + (tn+15)];
1259 		ubasestep = ptemp->quotient;
1260 		erroradjustup = ptemp->remainder;
1261 		erroradjustdown = tn;
1262 	}
1263 	else
1264 	{
1265 		dm = (double)tm;
1266 		dn = (double)tn;
1267 
1268 		FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
1269 
1270 		erroradjustdown = dn;
1271 	}
1272 }
1273 
1274 
1275 #if	!id386 && !id68k
1276 
1277 #define D_PolysetCalcGradientsT		D_PolysetCalcGradients
1278 #define D_PolysetCalcGradientsT2	D_PolysetCalcGradients
1279 #define D_PolysetCalcGradientsT3	D_PolysetCalcGradients
1280 #define D_PolysetCalcGradientsT5	D_PolysetCalcGradients
1281 /*
1282 ================
1283 D_PolysetCalcGradients
1284 ================
1285 */
D_PolysetCalcGradients(int skin_width)1286 static void D_PolysetCalcGradients (int skin_width)
1287 {
1288 	float	xstepdenominv, ystepdenominv, t0, t1;
1289 	float	p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
1290 
1291 	p00_minus_p20 = r_p0[0] - r_p2[0];
1292 	p01_minus_p21 = r_p0[1] - r_p2[1];
1293 	p10_minus_p20 = r_p1[0] - r_p2[0];
1294 	p11_minus_p21 = r_p1[1] - r_p2[1];
1295 
1296 	xstepdenominv = 1.0 / (float)d_xdenom;
1297 
1298 	ystepdenominv = -xstepdenominv;
1299 
1300 // ceil () for light so positive steps are exaggerated, negative steps
1301 // diminished,  pushing us away from underflow toward overflow. Underflow is
1302 // very visible, overflow is very unlikely, because of ambient lighting
1303 	t0 = r_p0[4] - r_p2[4];
1304 	t1 = r_p1[4] - r_p2[4];
1305 	r_lstepx = (int)ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
1306 	r_lstepy = (int)ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
1307 
1308 	t0 = r_p0[2] - r_p2[2];
1309 	t1 = r_p1[2] - r_p2[2];
1310 	r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
1311 	r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) * ystepdenominv);
1312 
1313 	t0 = r_p0[3] - r_p2[3];
1314 	t1 = r_p1[3] - r_p2[3];
1315 	r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
1316 	r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
1317 
1318 	t0 = r_p0[5] - r_p2[5];
1319 	t1 = r_p1[5] - r_p2[5];
1320 	r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
1321 	r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
1322 
1323 //	a_sstepxfrac = r_sstepx << 16;	// was #if id386 code
1324 //	a_tstepxfrac = r_tstepx << 16;	// was #if id386 code
1325 	a_sstepxfrac = r_sstepx & 0xFFFF;
1326 	a_tstepxfrac = r_tstepx & 0xFFFF;
1327 
1328 	a_ststepxwhole = skin_width * (r_tstepx >> 16) + (r_sstepx >> 16);
1329 }
1330 
1331 #endif	/* !id386 */
1332 
1333 
1334 #if 0
1335 byte gelmap[256];
1336 void InitGel (byte *palette)
1337 {
1338 	int		i;
1339 	int		r;
1340 
1341 	for (i = 0; i < 256; i++)
1342 	{
1343 //		r = (palette[i*3]>>4);
1344 		r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3);
1345 		gelmap[i] = /* 64 */ 0 + r;
1346 	}
1347 }
1348 #endif
1349 
1350 
1351 #if	!id386
1352 
1353 /*
1354 ================
1355 D_PolysetDrawSpans8
1356 ================
1357 */
1358 #if !id68k
D_PolysetDrawSpans8(spanpackage_t * pspanpackage)1359 static void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage)
1360 {
1361 	int		lcount;
1362 	byte		*lpdest;
1363 	byte		*lptex;
1364 	int		lsfrac, ltfrac;
1365 	int		llight;
1366 	int		lzi;
1367 	short		*lpz;
1368 
1369 	do
1370 	{
1371 		lcount = d_aspancount - pspanpackage->count;
1372 
1373 		errorterm += erroradjustup;
1374 		if (errorterm >= 0)
1375 		{
1376 			d_aspancount += d_countextrastep;
1377 			errorterm -= erroradjustdown;
1378 		}
1379 		else
1380 		{
1381 			d_aspancount += ubasestep;
1382 		}
1383 
1384 		if (lcount)
1385 		{
1386 			lpdest = (byte *) pspanpackage->pdest;
1387 			lptex = pspanpackage->ptex;
1388 			lpz = pspanpackage->pz;
1389 			lsfrac = pspanpackage->sfrac;
1390 			ltfrac = pspanpackage->tfrac;
1391 			llight = pspanpackage->light;
1392 			lzi = pspanpackage->zi;
1393 
1394 			do
1395 			{
1396 				if ((lzi >> 16) >= *lpz)
1397 				{
1398 					*lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)];
1399 				// gel mapping
1400 				//	*lpdest = gelmap[*lpdest];
1401 					*lpz = lzi >> 16;
1402 				}
1403 				lpdest++;
1404 				lzi += r_zistepx;
1405 				lpz++;
1406 				llight += r_lstepx;
1407 				lptex += a_ststepxwhole;
1408 				lsfrac += a_sstepxfrac;
1409 				lptex += lsfrac >> 16;
1410 				lsfrac &= 0xFFFF;
1411 				ltfrac += a_tstepxfrac;
1412 				if (ltfrac & 0x10000)
1413 				{
1414 					lptex += r_affinetridesc.skinwidth;
1415 					ltfrac &= 0xFFFF;
1416 				}
1417 			} while (--lcount);
1418 		}
1419 
1420 		pspanpackage++;
1421 	} while (pspanpackage->count != -999999);
1422 }
1423 #endif /* !id68k */
1424 
D_PolysetDrawSpans8T(spanpackage_t * pspanpackage)1425 static void D_PolysetDrawSpans8T (spanpackage_t *pspanpackage)
1426 {
1427 	int		lcount;
1428 	byte		*lpdest;
1429 	byte		*lptex;
1430 	int		lsfrac, ltfrac;
1431 	int		llight;
1432 	int		lzi;
1433 	short		*lpz;
1434 	unsigned int	btemp, color_map_idx;
1435 
1436 	do
1437 	{
1438 		lcount = d_aspancount - pspanpackage->count;
1439 
1440 		errorterm += erroradjustup;
1441 		if (errorterm >= 0)
1442 		{
1443 			d_aspancount += d_countextrastep;
1444 			errorterm -= erroradjustdown;
1445 		}
1446 		else
1447 		{
1448 			d_aspancount += ubasestep;
1449 		}
1450 
1451 		if (lcount)
1452 		{
1453 			lpdest = (byte *) pspanpackage->pdest;
1454 			lptex = pspanpackage->ptex;
1455 			lpz = pspanpackage->pz;
1456 			lsfrac = pspanpackage->sfrac;
1457 			ltfrac = pspanpackage->tfrac;
1458 			llight = pspanpackage->light;
1459 			lzi = pspanpackage->zi;
1460 
1461 			do
1462 			{
1463 				color_map_idx = lptex[0];
1464 				if (color_map_idx != 0)
1465 				{
1466 					if ((lzi >> 16) >= *lpz)
1467 					{
1468 						btemp = ((byte *) acolormap)[*lptex + (llight & 0xFF00)];
1469 						*lpdest = mainTransTable[(btemp<<8) + (*lpdest)];
1470 						*lpz = lzi >> 16;
1471 					}
1472 				}
1473 				lpdest++;
1474 				lzi += r_zistepx;
1475 				lpz++;
1476 				llight += r_lstepx;
1477 				lptex += a_ststepxwhole;
1478 				lsfrac += a_sstepxfrac;
1479 				lptex += lsfrac >> 16;
1480 				lsfrac &= 0xFFFF;
1481 				ltfrac += a_tstepxfrac;
1482 				if (ltfrac & 0x10000)
1483 				{
1484 					lptex += r_affinetridesc.skinwidth;
1485 					ltfrac &= 0xFFFF;
1486 				}
1487 			} while (--lcount);
1488 		}
1489 
1490 		pspanpackage++;
1491 	} while (pspanpackage->count != -999999);
1492 }
1493 
D_PolysetDrawSpans8T2(spanpackage_t * pspanpackage)1494 static void D_PolysetDrawSpans8T2 (spanpackage_t *pspanpackage)
1495 {
1496 	int		lcount;
1497 	byte		*lpdest;
1498 	byte		*lptex;
1499 	int		lsfrac, ltfrac;
1500 	int		llight;
1501 	int		lzi;
1502 	short		*lpz;
1503 	unsigned int	btemp, color_map_idx;
1504 
1505 	do
1506 	{
1507 		lcount = d_aspancount - pspanpackage->count;
1508 
1509 		errorterm += erroradjustup;
1510 		if (errorterm >= 0)
1511 		{
1512 			d_aspancount += d_countextrastep;
1513 			errorterm -= erroradjustdown;
1514 		}
1515 		else
1516 		{
1517 			d_aspancount += ubasestep;
1518 		}
1519 
1520 		if (lcount)
1521 		{
1522 			lpdest = (byte *) pspanpackage->pdest;
1523 			lptex = pspanpackage->ptex;
1524 			lpz = pspanpackage->pz;
1525 			lsfrac = pspanpackage->sfrac;
1526 			ltfrac = pspanpackage->tfrac;
1527 			llight = pspanpackage->light;
1528 			lzi = pspanpackage->zi;
1529 
1530 			do
1531 			{
1532 				color_map_idx = lptex[0];
1533 				if (color_map_idx != 0)
1534 				{
1535 					if ((lzi >> 16) >= *lpz)
1536 					{
1537 						if (color_map_idx % 2 == 0)
1538 						{
1539 							btemp = ((byte *) acolormap)[*lptex + (llight & 0xFF00)];
1540 							*lpdest = (byte) btemp;
1541 							*lpz = lzi >> 16;
1542 						}
1543 						else
1544 						{
1545 							btemp = ((byte *) acolormap)[*lptex + (llight & 0xFF00)];
1546 							*lpdest = mainTransTable[(btemp<<8) + (*lpdest)];
1547 							*lpz = lzi >> 16;
1548 						}
1549 					}
1550 				}
1551 				lpdest++;
1552 				lzi += r_zistepx;
1553 				lpz++;
1554 				llight += r_lstepx;
1555 				lptex += a_ststepxwhole;
1556 				lsfrac += a_sstepxfrac;
1557 				lptex += lsfrac >> 16;
1558 				lsfrac &= 0xFFFF;
1559 				ltfrac += a_tstepxfrac;
1560 				if (ltfrac & 0x10000)
1561 				{
1562 					lptex += r_affinetridesc.skinwidth;
1563 					ltfrac &= 0xFFFF;
1564 				}
1565 			} while (--lcount);
1566 		}
1567 
1568 		pspanpackage++;
1569 	} while (pspanpackage->count != -999999);
1570 }
1571 
D_PolysetDrawSpans8T3(spanpackage_t * pspanpackage)1572 static void D_PolysetDrawSpans8T3 (spanpackage_t *pspanpackage)
1573 {
1574 	int		lcount;
1575 	byte		*lpdest;
1576 	byte		*lptex;
1577 	int		lsfrac, ltfrac;
1578 	int		llight;
1579 	int		lzi;
1580 	short		*lpz;
1581 	unsigned int	color_map_idx;
1582 
1583 	do
1584 	{
1585 		lcount = d_aspancount - pspanpackage->count;
1586 
1587 		errorterm += erroradjustup;
1588 		if (errorterm >= 0)
1589 		{
1590 			d_aspancount += d_countextrastep;
1591 			errorterm -= erroradjustdown;
1592 		}
1593 		else
1594 		{
1595 			d_aspancount += ubasestep;
1596 		}
1597 
1598 		if (lcount)
1599 		{
1600 			lpdest = (byte *) pspanpackage->pdest;
1601 			lptex = pspanpackage->ptex;
1602 			lpz = pspanpackage->pz;
1603 			lsfrac = pspanpackage->sfrac;
1604 			ltfrac = pspanpackage->tfrac;
1605 			llight = pspanpackage->light;
1606 			lzi = pspanpackage->zi;
1607 
1608 			do
1609 			{
1610 				color_map_idx = lptex[0];
1611 				if (color_map_idx != 0)
1612 				{
1613 					if ((lzi >> 16) >= *lpz)
1614 					{
1615 						*lpdest = ((byte *) acolormap)[*lptex + (llight & 0xFF00)];
1616 						*lpz = lzi >> 16;
1617 					}
1618 				}
1619 				lpdest++;
1620 				lzi += r_zistepx;
1621 				lpz++;
1622 				llight += r_lstepx;
1623 				lptex += a_ststepxwhole;
1624 				lsfrac += a_sstepxfrac;
1625 				lptex += lsfrac >> 16;
1626 				lsfrac &= 0xFFFF;
1627 				ltfrac += a_tstepxfrac;
1628 				if (ltfrac & 0x10000)
1629 				{
1630 					lptex += r_affinetridesc.skinwidth;
1631 					ltfrac &= 0xFFFF;
1632 				}
1633 			} while (--lcount);
1634 		}
1635 
1636 		pspanpackage++;
1637 	} while (pspanpackage->count != -999999);
1638 }
1639 
D_PolysetDrawSpans8T5(spanpackage_t * pspanpackage)1640 static void D_PolysetDrawSpans8T5 (spanpackage_t *pspanpackage)
1641 {
1642 	int		lcount;
1643 	byte		*lpdest;
1644 	byte		*lptex;
1645 	int		lsfrac, ltfrac;
1646 	int		lzi;
1647 	short		*lpz;
1648 	unsigned int	color_map_idx;
1649 
1650 	do
1651 	{
1652 		lcount = d_aspancount - pspanpackage->count;
1653 
1654 		errorterm += erroradjustup;
1655 		if (errorterm >= 0)
1656 		{
1657 			d_aspancount += d_countextrastep;
1658 			errorterm -= erroradjustdown;
1659 		}
1660 		else
1661 		{
1662 			d_aspancount += ubasestep;
1663 		}
1664 
1665 		if (lcount)
1666 		{
1667 			lpdest = (byte *) pspanpackage->pdest;
1668 			lptex = pspanpackage->ptex;
1669 			lpz = pspanpackage->pz;
1670 			lsfrac = pspanpackage->sfrac;
1671 			ltfrac = pspanpackage->tfrac;
1672 			lzi = pspanpackage->zi;
1673 
1674 			do
1675 			{
1676 				color_map_idx = lptex[0];
1677 				if (color_map_idx != 0)
1678 				{
1679 					if ((lzi >> 16) >= *lpz)
1680 					{
1681 						*lpdest = transTable[(color_map_idx<<8) + (*lpdest)];
1682 						*lpz = lzi >> 16;
1683 					}
1684 				}
1685 				lpdest++;
1686 				lzi += r_zistepx;
1687 				lpz++;
1688 				lptex += a_ststepxwhole;
1689 				lsfrac += a_sstepxfrac;
1690 				lptex += lsfrac >> 16;
1691 				lsfrac &= 0xFFFF;
1692 				ltfrac += a_tstepxfrac;
1693 				if (ltfrac & 0x10000)
1694 				{
1695 					lptex += r_affinetridesc.skinwidth;
1696 					ltfrac &= 0xFFFF;
1697 				}
1698 			} while (--lcount);
1699 		}
1700 
1701 		pspanpackage++;
1702 	} while (pspanpackage->count != -999999);
1703 }
1704 
1705 #endif	/* !id386 */
1706 
1707 
1708 /*
1709 ================
1710 D_PolysetFillSpans8
1711 ================
1712 */
D_PolysetFillSpans8(spanpackage_t * pspanpackage)1713 void D_PolysetFillSpans8 (spanpackage_t *pspanpackage)
1714 {
1715 	int		color;
1716 
1717 // FIXME: do z buffering
1718 
1719 	color = d_aflatcolor++;
1720 
1721 	while (1)
1722 	{
1723 		int		lcount;
1724 		byte	*lpdest;
1725 
1726 		lcount = pspanpackage->count;
1727 
1728 		if (lcount == -1)
1729 			return;
1730 
1731 		if (lcount)
1732 		{
1733 			lpdest = (byte *) pspanpackage->pdest;
1734 
1735 			do
1736 			{
1737 				*lpdest++ = color;
1738 			} while (--lcount);
1739 		}
1740 
1741 		pspanpackage++;
1742 	}
1743 }
1744 
1745 /*
1746 ================
1747 D_RasterizeAliasPolySmooth
1748 ================
1749 */
D_RasterizeAliasPolySmooth(void)1750 void D_RasterizeAliasPolySmooth (void)
1751 {
1752 	int		initialleftheight, initialrightheight;
1753 	int		*plefttop, *prighttop, *pleftbottom, *prightbottom;
1754 	int		working_lstepx, originalcount;
1755 
1756 	plefttop = pedgetable->pleftedgevert0;
1757 	prighttop = pedgetable->prightedgevert0;
1758 
1759 	pleftbottom = pedgetable->pleftedgevert1;
1760 	prightbottom = pedgetable->prightedgevert1;
1761 
1762 	initialleftheight = pleftbottom[1] - plefttop[1];
1763 	initialrightheight = prightbottom[1] - prighttop[1];
1764 
1765 //
1766 // set the s, t, and light gradients, which are consistent across the triangle
1767 // because being a triangle, things are affine
1768 //
1769 	if ((currententity->model->flags & EF_SPECIAL_TRANS))
1770 		D_PolysetCalcGradientsT5 (r_affinetridesc.skinwidth);
1771 	else if (currententity->drawflags & DRF_TRANSLUCENT)
1772 		D_PolysetCalcGradientsT (r_affinetridesc.skinwidth);
1773 	else if ((currententity->model->flags & EF_TRANSPARENT))
1774 		D_PolysetCalcGradientsT2 (r_affinetridesc.skinwidth);
1775 	else if ((currententity->model->flags & EF_HOLEY))
1776 		D_PolysetCalcGradientsT3 (r_affinetridesc.skinwidth);
1777 	else
1778 		D_PolysetCalcGradients (r_affinetridesc.skinwidth);
1779 
1780 //
1781 // rasterize the polygon
1782 //
1783 
1784 //
1785 // scan out the top (and possibly only) part of the left edge
1786 //
1787 	d_pedgespanpackage = a_spans;
1788 
1789 	ystart = plefttop[1];
1790 	d_aspancount = plefttop[0] - prighttop[0];
1791 
1792 	d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
1793 			(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
1794 #if	id386
1795 	d_sfrac = (plefttop[2] & 0xFFFF) << 16;
1796 	d_tfrac = (plefttop[3] & 0xFFFF) << 16;
1797 #else
1798 	d_sfrac = plefttop[2] & 0xFFFF;
1799 	d_tfrac = plefttop[3] & 0xFFFF;
1800 #endif
1801 	d_light = plefttop[4];
1802 	d_zi = plefttop[5];
1803 
1804 	d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0];
1805 	d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
1806 
1807 	if (initialleftheight == 1)
1808 	{
1809 		d_pedgespanpackage->pdest = d_pdest;
1810 		d_pedgespanpackage->pz = d_pz;
1811 		d_pedgespanpackage->count = d_aspancount;
1812 		d_pedgespanpackage->ptex = d_ptex;
1813 
1814 		d_pedgespanpackage->sfrac = d_sfrac;
1815 		d_pedgespanpackage->tfrac = d_tfrac;
1816 
1817 	// FIXME: need to clamp l, s, t, at both ends?
1818 		d_pedgespanpackage->light = d_light;
1819 		d_pedgespanpackage->zi = d_zi;
1820 
1821 		d_pedgespanpackage++;
1822 	}
1823 	else
1824 	{
1825 		D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], pleftbottom[0], pleftbottom[1]);
1826 
1827 #if	id386
1828 		d_pzbasestep = (d_zwidth + ubasestep) << 1;
1829 		d_pzextrastep = d_pzbasestep + 2;
1830 #else
1831 		d_pzbasestep = d_zwidth + ubasestep;
1832 		d_pzextrastep = d_pzbasestep + 1;
1833 #endif
1834 
1835 		d_pdestbasestep = screenwidth + ubasestep;
1836 		d_pdestextrastep = d_pdestbasestep + 1;
1837 
1838 	// TODO: can reuse partial expressions here
1839 
1840 	// for negative steps in x along left edge, bias toward overflow rather than
1841 	// underflow (sort of turning the floor () we did in the gradient calcs into
1842 	// ceil (), but plus a little bit)
1843 		if (ubasestep < 0)
1844 			working_lstepx = r_lstepx - 1;
1845 		else
1846 			working_lstepx = r_lstepx;
1847 
1848 		d_countextrastep = ubasestep + 1;
1849 		d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
1850 				((r_tstepy + r_tstepx * ubasestep) >> 16) * r_affinetridesc.skinwidth;
1851 #if	id386
1852 		d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
1853 		d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
1854 #else
1855 		d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
1856 		d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
1857 #endif
1858 		d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
1859 		d_zibasestep = r_zistepy + r_zistepx * ubasestep;
1860 
1861 		d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
1862 				((r_tstepy + r_tstepx * d_countextrastep) >> 16) * r_affinetridesc.skinwidth;
1863 #if	id386
1864 		d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16;
1865 		d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16;
1866 #else
1867 		d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF;
1868 		d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF;
1869 #endif
1870 		d_lightextrastep = d_lightbasestep + working_lstepx;
1871 		d_ziextrastep = d_zibasestep + r_zistepx;
1872 
1873 		if ((currententity->model->flags & EF_SPECIAL_TRANS))
1874 			D_PolysetScanLeftEdgeT5 (initialleftheight);
1875 		else if (currententity->drawflags & DRF_TRANSLUCENT)
1876 			D_PolysetScanLeftEdgeT (initialleftheight);
1877 		else if ((currententity->model->flags & EF_TRANSPARENT))
1878 			D_PolysetScanLeftEdgeT2 (initialleftheight);
1879 		else if ((currententity->model->flags & EF_HOLEY))
1880 			D_PolysetScanLeftEdgeT3 (initialleftheight);
1881 		else
1882 			D_PolysetScanLeftEdge (initialleftheight);
1883 	}
1884 
1885 //
1886 // scan out the bottom part of the left edge, if it exists
1887 //
1888 	if (pedgetable->numleftedges == 2)
1889 	{
1890 		int		height;
1891 
1892 		plefttop = pleftbottom;
1893 		pleftbottom = pedgetable->pleftedgevert2;
1894 
1895 		height = pleftbottom[1] - plefttop[1];
1896 
1897 // TODO: make this a function; modularize this function in general
1898 
1899 		ystart = plefttop[1];
1900 		d_aspancount = plefttop[0] - prighttop[0];
1901 		d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
1902 				(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
1903 		d_sfrac = 0;
1904 		d_tfrac = 0;
1905 		d_light = plefttop[4];
1906 		d_zi = plefttop[5];
1907 
1908 		d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0];
1909 		d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
1910 
1911 		if (height == 1)
1912 		{
1913 			d_pedgespanpackage->pdest = d_pdest;
1914 			d_pedgespanpackage->pz = d_pz;
1915 			d_pedgespanpackage->count = d_aspancount;
1916 			d_pedgespanpackage->ptex = d_ptex;
1917 
1918 			d_pedgespanpackage->sfrac = d_sfrac;
1919 			d_pedgespanpackage->tfrac = d_tfrac;
1920 
1921 		// FIXME: need to clamp l, s, t, at both ends?
1922 			d_pedgespanpackage->light = d_light;
1923 			d_pedgespanpackage->zi = d_zi;
1924 
1925 			d_pedgespanpackage++;
1926 		}
1927 		else
1928 		{
1929 			D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], pleftbottom[0], pleftbottom[1]);
1930 
1931 			d_pdestbasestep = screenwidth + ubasestep;
1932 			d_pdestextrastep = d_pdestbasestep + 1;
1933 
1934 #if	id386
1935 			d_pzbasestep = (d_zwidth + ubasestep) << 1;
1936 			d_pzextrastep = d_pzbasestep + 2;
1937 #else
1938 			d_pzbasestep = d_zwidth + ubasestep;
1939 			d_pzextrastep = d_pzbasestep + 1;
1940 #endif
1941 
1942 			if (ubasestep < 0)
1943 				working_lstepx = r_lstepx - 1;
1944 			else
1945 				working_lstepx = r_lstepx;
1946 
1947 			d_countextrastep = ubasestep + 1;
1948 			d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
1949 					((r_tstepy + r_tstepx * ubasestep) >> 16) * r_affinetridesc.skinwidth;
1950 #if	id386
1951 			d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
1952 			d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
1953 #else
1954 			d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
1955 			d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
1956 #endif
1957 			d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
1958 			d_zibasestep = r_zistepy + r_zistepx * ubasestep;
1959 
1960 			d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
1961 					((r_tstepy + r_tstepx * d_countextrastep) >> 16) * r_affinetridesc.skinwidth;
1962 #if	id386
1963 			d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16;
1964 			d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16;
1965 #else
1966 			d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF;
1967 			d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF;
1968 #endif
1969 			d_lightextrastep = d_lightbasestep + working_lstepx;
1970 			d_ziextrastep = d_zibasestep + r_zistepx;
1971 
1972 			if ((currententity->model->flags & EF_SPECIAL_TRANS))
1973 				D_PolysetScanLeftEdgeT5 (height);
1974 			else if (currententity->drawflags & DRF_TRANSLUCENT)
1975 				D_PolysetScanLeftEdgeT (height);
1976 			else if ((currententity->model->flags & EF_TRANSPARENT))
1977 				D_PolysetScanLeftEdgeT2 (height);
1978 			else if ((currententity->model->flags & EF_HOLEY))
1979 				D_PolysetScanLeftEdgeT3 (height);
1980 			else
1981 				D_PolysetScanLeftEdge (height);
1982 		}
1983 	}
1984 
1985 // scan out the top (and possibly only) part of the right edge, updating the
1986 // count field
1987 	d_pedgespanpackage = a_spans;
1988 
1989 	D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], prightbottom[0], prightbottom[1]);
1990 	d_aspancount = 0;
1991 	d_countextrastep = ubasestep + 1;
1992 	originalcount = a_spans[initialrightheight].count;
1993 	a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
1994 
1995 	if ((currententity->model->flags & EF_SPECIAL_TRANS))
1996 		D_PolysetDrawSpans8T5 (a_spans);
1997 	else if (currententity->drawflags & DRF_TRANSLUCENT)
1998 		D_PolysetDrawSpans8T (a_spans);
1999 	else if ((currententity->model->flags & EF_TRANSPARENT))
2000 		D_PolysetDrawSpans8T2 (a_spans);
2001 	else if ((currententity->model->flags & EF_HOLEY))
2002 		D_PolysetDrawSpans8T3 (a_spans);
2003 	else
2004 		D_PolysetDrawSpans8 (a_spans);
2005 
2006 // scan out the bottom part of the right edge, if it exists
2007 	if (pedgetable->numrightedges == 2)
2008 	{
2009 		int				height;
2010 		spanpackage_t	*pstart;
2011 
2012 		pstart = a_spans + initialrightheight;
2013 		pstart->count = originalcount;
2014 
2015 		d_aspancount = prightbottom[0] - prighttop[0];
2016 
2017 		prighttop = prightbottom;
2018 		prightbottom = pedgetable->prightedgevert2;
2019 
2020 		height = prightbottom[1] - prighttop[1];
2021 
2022 		D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], prightbottom[0], prightbottom[1]);
2023 
2024 		d_countextrastep = ubasestep + 1;
2025 		a_spans[initialrightheight + height].count = -999999;
2026 											// mark end of the spanpackages
2027 		if ((currententity->model->flags & EF_SPECIAL_TRANS))
2028 			D_PolysetDrawSpans8T5 (pstart);
2029 		else if (currententity->drawflags & DRF_TRANSLUCENT)
2030 			D_PolysetDrawSpans8T (pstart);
2031 		else if ((currententity->model->flags & EF_TRANSPARENT))
2032 			D_PolysetDrawSpans8T2 (pstart);
2033 		else if ((currententity->model->flags & EF_HOLEY))
2034 			D_PolysetDrawSpans8T3 (pstart);
2035 		else
2036 			D_PolysetDrawSpans8 (pstart);
2037 	}
2038 }
2039 
2040 
2041 /*
2042 ================
2043 D_PolysetSetEdgeTable
2044 ================
2045 */
D_PolysetSetEdgeTable(void)2046 void D_PolysetSetEdgeTable (void)
2047 {
2048 	int			edgetableindex;
2049 
2050 	edgetableindex = 0;	// assume the vertices are already in
2051 						//  top to bottom order
2052 
2053 //
2054 // determine which edges are right & left, and the order in which
2055 // to rasterize them
2056 //
2057 	if (r_p0[1] >= r_p1[1])
2058 	{
2059 		if (r_p0[1] == r_p1[1])
2060 		{
2061 			if (r_p0[1] < r_p2[1])
2062 				pedgetable = &edgetables[2];
2063 			else
2064 				pedgetable = &edgetables[5];
2065 
2066 			return;
2067 		}
2068 		else
2069 		{
2070 			edgetableindex = 1;
2071 		}
2072 	}
2073 
2074 	if (r_p0[1] == r_p2[1])
2075 	{
2076 		if (edgetableindex)
2077 			pedgetable = &edgetables[8];
2078 		else
2079 			pedgetable = &edgetables[9];
2080 
2081 		return;
2082 	}
2083 	else if (r_p1[1] == r_p2[1])
2084 	{
2085 		if (edgetableindex)
2086 			pedgetable = &edgetables[10];
2087 		else
2088 			pedgetable = &edgetables[11];
2089 
2090 		return;
2091 	}
2092 
2093 	if (r_p0[1] > r_p2[1])
2094 		edgetableindex += 2;
2095 
2096 	if (r_p1[1] > r_p2[1])
2097 		edgetableindex += 4;
2098 
2099 	pedgetable = &edgetables[edgetableindex];
2100 }
2101 
2102 
2103 #if 0
2104 
2105 void D_PolysetRecursiveDrawLine (int *lp1, int *lp2)
2106 {
2107 	int		d;
2108 	int		new_p[6];
2109 	int		ofs;
2110 
2111 	d = lp2[0] - lp1[0];
2112 	if (d < -1 || d > 1)
2113 		goto split;
2114 	d = lp2[1] - lp1[1];
2115 	if (d < -1 || d > 1)
2116 		goto split;
2117 
2118 	return;	// line is completed
2119 
2120 split:
2121 // split this edge
2122 	new_p[0] = (lp1[0] + lp2[0]) >> 1;
2123 	new_p[1] = (lp1[1] + lp2[1]) >> 1;
2124 	new_p[5] = (lp1[5] + lp2[5]) >> 1;
2125 	new_p[2] = (lp1[2] + lp2[2]) >> 1;
2126 	new_p[3] = (lp1[3] + lp2[3]) >> 1;
2127 	new_p[4] = (lp1[4] + lp2[4]) >> 1;
2128 
2129 // draw the point
2130 	ofs = d_scantable[new_p[1]] + new_p[0];
2131 	if (new_p[5] > d_pzbuffer[ofs])
2132 	{
2133 		unsigned int	pix;
2134 
2135 		d_pzbuffer[ofs] = new_p[5];
2136 		pix = skintable[new_p[3]>>16][new_p[2]>>16];
2137 //		pix = ((byte *)acolormap)[pix + (new_p[4] & 0xFF00)];
2138 		d_viewbuffer[ofs] = pix;
2139 	}
2140 
2141 // recursively continue
2142 	D_PolysetRecursiveDrawLine (lp1, new_p);
2143 	D_PolysetRecursiveDrawLine (new_p, lp2);
2144 }
2145 
2146 void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3)
2147 {
2148 	int		d;
2149 	int		new_p[6];
2150 
2151 	d = lp2[0] - lp1[0];
2152 	if (d < -1 || d > 1)
2153 		goto split;
2154 	d = lp2[1] - lp1[1];
2155 	if (d < -1 || d > 1)
2156 		goto split;
2157 	return;
2158 
2159 split:
2160 // split this edge
2161 	new_p[0] = (lp1[0] + lp2[0]) >> 1;
2162 	new_p[1] = (lp1[1] + lp2[1]) >> 1;
2163 	new_p[5] = (lp1[5] + lp2[5]) >> 1;
2164 	new_p[2] = (lp1[2] + lp2[2]) >> 1;
2165 	new_p[3] = (lp1[3] + lp2[3]) >> 1;
2166 	new_p[4] = (lp1[4] + lp2[4]) >> 1;
2167 
2168 	D_PolysetRecursiveDrawLine (new, lp3);
2169 
2170 // recursively continue
2171 	D_PolysetRecursiveTriangle (lp1, new, lp3);
2172 	D_PolysetRecursiveTriangle (new, lp2, lp3);
2173 }
2174 
2175 #endif
2176 
2177