Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
Copyright (C) 1996-1997 Id Software, Inc.
3
 
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
 
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
 
13
See the GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 !!!
33
typedef struct {
34
	void			*pdest;
35
	short			*pz;
36
	int				count;
37
	byte			*ptex;
38
	int				sfrac, tfrac, light, zi;
39
} spanpackage_t;
40
 
41
typedef struct {
42
	int		isflattop;
43
	int		numleftedges;
44
	int		*pleftedgevert0;
45
	int		*pleftedgevert1;
46
	int		*pleftedgevert2;
47
	int		numrightedges;
48
	int		*prightedgevert0;
49
	int		*prightedgevert1;
50
	int		*prightedgevert2;
51
} edgetable;
52
 
53
int	r_p0[6], r_p1[6], r_p2[6];
54
 
55
byte		*d_pcolormap;
56
 
57
int			d_aflatcolor;
58
int			d_xdenom;
59
 
60
edgetable	*pedgetable;
61
 
62
edgetable	edgetables[12] = {
63
	{0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },
64
	{0, 2, r_p1, r_p0, r_p2,   1, r_p1, r_p2, NULL},
65
	{1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
66
	{0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },
67
	{0, 2, r_p0, r_p2, r_p1,   1, r_p0, r_p1, NULL},
68
	{0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
69
	{0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },
70
	{0, 2, r_p2, r_p1, r_p0,   1, r_p2, r_p0, NULL},
71
	{0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
72
	{1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
73
	{1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
74
	{0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
75
};
76
 
77
// FIXME: some of these can become statics
78
int				a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
79
int				r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
80
int				r_zistepx, r_zistepy;
81
int				d_aspancount, d_countextrastep;
82
 
83
spanpackage_t			*a_spans;
84
spanpackage_t			*d_pedgespanpackage;
85
static int				ystart;
86
byte					*d_pdest, *d_ptex;
87
short					*d_pz;
88
int						d_sfrac, d_tfrac, d_light, d_zi;
89
int						d_ptexextrastep, d_sfracextrastep;
90
int						d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
91
int						d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
92
int						d_sfracbasestep, d_tfracbasestep;
93
int						d_ziextrastep, d_zibasestep;
94
int						d_pzextrastep, d_pzbasestep;
95
 
96
typedef struct {
97
	int		quotient;
98
	int		remainder;
99
} adivtab_t;
100
 
101
static adivtab_t	adivtab[32*32] = {
102
#include "adivtab.h"
103
};
104
 
105
byte	*skintable[MAX_LBM_HEIGHT];
106
int		skinwidth;
107
byte	*skinstart;
108
 
109
void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage);
110
void D_PolysetCalcGradients (int skinwidth);
111
void D_DrawSubdiv (void);
112
void D_DrawNonSubdiv (void);
113
void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3);
114
void D_PolysetSetEdgeTable (void);
115
void D_RasterizeAliasPolySmooth (void);
116
void D_PolysetScanLeftEdge (int height);
117
 
118
#if	!id386
119
 
120
/*
121
================
122
D_PolysetDraw
123
================
124
*/
125
void 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
================
147
D_PolysetDrawFinalVerts
148
================
149
*/
150
void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts)
151
{
152
	int		i, z;
153
	short	*zbuf;
154
 
155
	for (i=0 ; i
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
================
180
D_DrawSubdiv
181
================
182
*/
183
void 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
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
================
241
D_DrawNonSubdiv
242
================
243
*/
244
void 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
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
================
309
D_PolysetRecursiveTriangle
310
================
311
*/
312
void 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
	{
340
split3:
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
 
351
split2:
352
	temp = lp1;
353
	lp1 = lp2;
354
	lp2 = lp3;
355
	lp3 = temp;
356
 
357
split:
358
// split this edge
359
	new[0] = (lp1[0] + lp2[0]) >> 1;
360
	new[1] = (lp1[1] + lp2[1]) >> 1;
361
	new[2] = (lp1[2] + lp2[2]) >> 1;
362
	new[3] = (lp1[3] + lp2[3]) >> 1;
363
	new[5] = (lp1[5] + lp2[5]) >> 1;
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
 
383
nodraw:
384
// recursively continue
385
	D_PolysetRecursiveTriangle (lp3, lp1, new);
386
	D_PolysetRecursiveTriangle (lp3, new, lp2);
387
}
388
 
389
#endif	// !id386
390
 
391
 
392
/*
393
================
394
D_PolysetUpdateTables
395
================
396
*/
397
void 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
409
			skintable[i] = s;
410
	}
411
}
412
 
413
 
414
#if	!id386
415
 
416
/*
417
===================
418
D_PolysetScanLeftEdge
419
====================
420
*/
421
void 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
===================
487
D_PolysetSetUpForLineScan
488
====================
489
*/
490
void 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
================
528
D_PolysetCalcGradients
529
================
530
*/
531
void 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
591
byte gelmap[256];
592
void 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
================
611
D_PolysetDrawSpans8
612
================
613
*/
614
void 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
================
682
D_PolysetFillSpans8
683
================
684
*/
685
void 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
================
719
D_RasterizeAliasPolySmooth
720
================
721
*/
722
void 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
================
978
D_PolysetSetEdgeTable
979
================
980
*/
981
void 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
 
1040
void 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
 
1055
split:
1056
// split this edge
1057
	new[0] = (lp1[0] + lp2[0]) >> 1;
1058
	new[1] = (lp1[1] + lp2[1]) >> 1;
1059
	new[5] = (lp1[5] + lp2[5]) >> 1;
1060
	new[2] = (lp1[2] + lp2[2]) >> 1;
1061
	new[3] = (lp1[3] + lp2[3]) >> 1;
1062
	new[4] = (lp1[4] + lp2[4]) >> 1;
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
 
1081
void 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
 
1094
split:
1095
// split this edge
1096
	new[0] = (lp1[0] + lp2[0]) >> 1;
1097
	new[1] = (lp1[1] + lp2[1]) >> 1;
1098
	new[5] = (lp1[5] + lp2[5]) >> 1;
1099
	new[2] = (lp1[2] + lp2[2]) >> 1;
1100
	new[3] = (lp1[3] + lp2[3]) >> 1;
1101
	new[4] = (lp1[4] + lp2[4]) >> 1;
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