1 /*
2 Copyright (C) 1997-2001 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 "sw_local.h"
24 
25 int	rand1k[] = {
26 #include "rand1k.h"
27 };
28 
29 #define MASK_1K	0x3FF
30 
31 int		rand1k_index = 0;
32 
33 // TODO: put in span spilling to shrink list size
34 // !!! if this is changed, it must be changed in d_polysa.s too !!!
35 #define DPS_MAXSPANS			MAXHEIGHT+1
36 									// 1 extra for spanpackage that marks end
37 
38 // !!! if this is changed, it must be changed in asm_draw.h too !!!
39 typedef struct {
40 	void			*pdest;
41 	short			*pz;
42 	int				count;
43 	byte			*ptex;
44 	int				sfrac, tfrac, light, zi;
45 } spanpackage_t;
46 
47 typedef struct {
48 	int		isflattop;
49 	int		numleftedges;
50 	int		*pleftedgevert0;
51 	int		*pleftedgevert1;
52 	int		*pleftedgevert2;
53 	int		numrightedges;
54 	int		*prightedgevert0;
55 	int		*prightedgevert1;
56 	int		*prightedgevert2;
57 } edgetable;
58 
59 aliastriangleparms_t aliastriangleparms;
60 
61 int	r_p0[6], r_p1[6], r_p2[6];
62 
63 int			d_aflatcolor;
64 int			d_xdenom;
65 
66 edgetable	*pedgetable;
67 
68 edgetable	edgetables[12] = {
69 	{0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },
70 	{0, 2, r_p1, r_p0, r_p2,   1, r_p1, r_p2, NULL},
71 	{1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
72 	{0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },
73 	{0, 2, r_p0, r_p2, r_p1,   1, r_p0, r_p1, NULL},
74 	{0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
75 	{0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },
76 	{0, 2, r_p2, r_p1, r_p0,   1, r_p2, r_p0, NULL},
77 	{0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
78 	{1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
79 	{1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
80 	{0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
81 };
82 
83 // FIXME: some of these can become statics
84 int				a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
85 int				r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
86 int				r_zistepx, r_zistepy;
87 int				d_aspancount, d_countextrastep;
88 
89 spanpackage_t			*a_spans;
90 spanpackage_t			*d_pedgespanpackage;
91 static int				ystart;
92 byte					*d_pdest, *d_ptex;
93 short					*d_pz;
94 int						d_sfrac, d_tfrac, d_light, d_zi;
95 int						d_ptexextrastep, d_sfracextrastep;
96 int						d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
97 int						d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
98 int						d_sfracbasestep, d_tfracbasestep;
99 int						d_ziextrastep, d_zibasestep;
100 int						d_pzextrastep, d_pzbasestep;
101 
102 typedef struct {
103 	int		quotient;
104 	int		remainder;
105 } adivtab_t;
106 
107 static adivtab_t	adivtab[32*32] = {
108 #include "adivtab.h"
109 };
110 
111 byte	*skintable[MAX_LBM_HEIGHT];
112 int		skinwidth;
113 byte	*skinstart;
114 
115 void	(*d_pdrawspans)(spanpackage_t *pspanpackage);
116 
117 void R_PolysetDrawSpans8_33 (spanpackage_t *pspanpackage);
118 void R_PolysetDrawSpans8_66 (spanpackage_t *pspanpackage);
119 void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage);
120 
121 void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage);
122 void R_PolysetCalcGradients (int skinwidth);
123 void R_DrawNonSubdiv (void);
124 void R_PolysetSetEdgeTable (void);
125 void R_RasterizeAliasPolySmooth (void);
126 void R_PolysetScanLeftEdge(int height);
127 void R_PolysetScanLeftEdge_C(int height);
128 
129 // ======================
130 // PGM
131 // 64 65 66 67 68 69 70 71   72 73 74 75 76 77 78 79
132 byte iractive = 0;
133 byte irtable[256] = { 79, 78, 77, 76, 75, 74, 73, 72,		// black/white
134 					  71, 70, 69, 68, 67, 66, 65, 64,
135 					  64, 65, 66, 67, 68, 69, 70, 71,		// dark taupe
136 					  72, 73, 74, 75, 76, 77, 78, 79,
137 
138 					  64, 65, 66, 67, 68, 69, 70, 71,		// slate grey
139 					  72, 73, 74, 75, 76, 77, 78, 79,
140 					  208, 208, 208, 208, 208, 208, 208, 208,	// unused?'
141 					  64, 66, 68, 70, 72, 74, 76, 78,		// dark yellow
142 
143 					  64, 65, 66, 67, 68, 69, 70, 71,		// dark red
144 					  72, 73, 74, 75, 76, 77, 78, 79,
145 					  64, 65, 66, 67, 68, 69, 70, 71,		// grey/tan
146 					  72, 73, 74, 75, 76, 77, 78, 79,
147 
148 					  64, 66, 68, 70, 72, 74, 76, 78,		// chocolate
149 					  68, 67, 66, 65, 64, 65, 66, 67,		// mauve / teal
150 					  68, 69, 70, 71, 72, 73, 74, 75,
151 					  76, 76, 77, 77, 78, 78, 79, 79,
152 
153 					  64, 65, 66, 67, 68, 69, 70, 71,		// more mauve
154 					  72, 73, 74, 75, 76, 77, 78, 79,
155 					  64, 65, 66, 67, 68, 69, 70, 71,		// olive
156 					  72, 73, 74, 75, 76, 77, 78, 79,
157 
158 					  64, 65, 66, 67, 68, 69, 70, 71,		// maroon
159 					  72, 73, 74, 75, 76, 77, 78, 79,
160 					  64, 65, 66, 67, 68, 69, 70, 71,		// sky blue
161 					  72, 73, 74, 75, 76, 77, 78, 79,
162 
163 					  64, 65, 66, 67, 68, 69, 70, 71,		// olive again
164 					  72, 73, 74, 75, 76, 77, 78, 79,
165 					  64, 65, 66, 67, 68, 69, 70, 71,		// nuclear green
166 					  64, 65, 66, 67, 68, 69, 70, 71,		// bright yellow
167 
168 					  64, 65, 66, 67, 68, 69, 70, 71,		// fire colors
169 					  72, 73, 74, 75, 76, 77, 78, 79,
170 					  208, 208, 64, 64, 70, 71, 72, 64,		// mishmash1
171 					  66, 68, 70, 64, 65, 66, 67, 68};		// mishmash2
172 // PGM
173 // ======================
174 
175 /*
176 ================
177 R_PolysetUpdateTables
178 ================
179 */
R_PolysetUpdateTables(void)180 void R_PolysetUpdateTables (void)
181 {
182 	int		i;
183 	byte	*s;
184 
185 	if (r_affinetridesc.skinwidth != skinwidth ||
186 		r_affinetridesc.pskin != skinstart)
187 	{
188 		skinwidth = r_affinetridesc.skinwidth;
189 		skinstart = r_affinetridesc.pskin;
190 		s = skinstart;
191 		for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth)
192 			skintable[i] = s;
193 	}
194 }
195 
196 
197 /*
198 ================
199 R_DrawTriangle
200 ================
201 */
R_DrawTriangle(void)202 void R_DrawTriangle( void )
203 {
204 	spanpackage_t spans[DPS_MAXSPANS];
205 
206 	int dv1_ab, dv0_ac;
207 	int dv0_ab, dv1_ac;
208 
209 	/*
210 	d_xdenom = ( aliastriangleparms.a->v[1] - aliastriangleparms.b->v[1] ) * ( aliastriangleparms.a->v[0] - aliastriangleparms.c->v[0] ) -
211 			   ( aliastriangleparms.a->v[0] - aliastriangleparms.b->v[0] ) * ( aliastriangleparms.a->v[1] - aliastriangleparms.c->v[1] );
212 	*/
213 
214 	dv0_ab = aliastriangleparms.a->u - aliastriangleparms.b->u;
215 	dv1_ab = aliastriangleparms.a->v - aliastriangleparms.b->v;
216 
217 	if ( !( dv0_ab | dv1_ab ) )
218 		return;
219 
220 	dv0_ac = aliastriangleparms.a->u - aliastriangleparms.c->u;
221 	dv1_ac = aliastriangleparms.a->v - aliastriangleparms.c->v;
222 
223 	if ( !( dv0_ac | dv1_ac ) )
224 		return;
225 
226 	d_xdenom = ( dv0_ac * dv1_ab ) - ( dv0_ab * dv1_ac );
227 
228 	if ( d_xdenom < 0 )
229 	{
230 		a_spans = spans;
231 
232 		r_p0[0] = aliastriangleparms.a->u;		// u
233 		r_p0[1] = aliastriangleparms.a->v;		// v
234 		r_p0[2] = aliastriangleparms.a->s;		// s
235 		r_p0[3] = aliastriangleparms.a->t;		// t
236 		r_p0[4] = aliastriangleparms.a->l;		// light
237 		r_p0[5] = aliastriangleparms.a->zi;		// iz
238 
239 		r_p1[0] = aliastriangleparms.b->u;
240 		r_p1[1] = aliastriangleparms.b->v;
241 		r_p1[2] = aliastriangleparms.b->s;
242 		r_p1[3] = aliastriangleparms.b->t;
243 		r_p1[4] = aliastriangleparms.b->l;
244 		r_p1[5] = aliastriangleparms.b->zi;
245 
246 		r_p2[0] = aliastriangleparms.c->u;
247 		r_p2[1] = aliastriangleparms.c->v;
248 		r_p2[2] = aliastriangleparms.c->s;
249 		r_p2[3] = aliastriangleparms.c->t;
250 		r_p2[4] = aliastriangleparms.c->l;
251 		r_p2[5] = aliastriangleparms.c->zi;
252 
253 		R_PolysetSetEdgeTable ();
254 		R_RasterizeAliasPolySmooth ();
255 	}
256 }
257 
258 
259 /*
260 ===================
261 R_PolysetScanLeftEdge_C
262 ====================
263 */
R_PolysetScanLeftEdge_C(int height)264 void R_PolysetScanLeftEdge_C(int height)
265 {
266 	do
267 	{
268 		d_pedgespanpackage->pdest = d_pdest;
269 		d_pedgespanpackage->pz = d_pz;
270 		d_pedgespanpackage->count = d_aspancount;
271 		d_pedgespanpackage->ptex = d_ptex;
272 
273 		d_pedgespanpackage->sfrac = d_sfrac;
274 		d_pedgespanpackage->tfrac = d_tfrac;
275 
276 	// FIXME: need to clamp l, s, t, at both ends?
277 		d_pedgespanpackage->light = d_light;
278 		d_pedgespanpackage->zi = d_zi;
279 
280 		d_pedgespanpackage++;
281 
282 		errorterm += erroradjustup;
283 		if (errorterm >= 0)
284 		{
285 			d_pdest += d_pdestextrastep;
286 			d_pz += d_pzextrastep;
287 			d_aspancount += d_countextrastep;
288 			d_ptex += d_ptexextrastep;
289 			d_sfrac += d_sfracextrastep;
290 			d_ptex += ( d_sfrac >> 16 ) << VID_SHIFT;
291 
292 			d_sfrac &= 0xFFFF;
293 			d_tfrac += d_tfracextrastep;
294 			if (d_tfrac & 0x10000)
295 			{
296 				d_ptex += r_affinetridesc.skinwidth;
297 				d_tfrac &= 0xFFFF;
298 			}
299 			d_light += d_lightextrastep;
300 			d_zi += d_ziextrastep;
301 			errorterm -= erroradjustdown;
302 		}
303 		else
304 		{
305 			d_pdest += d_pdestbasestep;
306 			d_pz += d_pzbasestep;
307 			d_aspancount += ubasestep;
308 			d_ptex += d_ptexbasestep;
309 			d_sfrac += d_sfracbasestep;
310 			d_ptex += ( d_sfrac >> 16 ) << VID_SHIFT;
311 			d_sfrac &= 0xFFFF;
312 			d_tfrac += d_tfracbasestep;
313 			if (d_tfrac & 0x10000)
314 			{
315 				d_ptex += r_affinetridesc.skinwidth;
316 				d_tfrac &= 0xFFFF;
317 			}
318 			d_light += d_lightbasestep;
319 			d_zi += d_zibasestep;
320 		}
321 	} while (--height);
322 }
323 
324 /*
325 ===================
326 FloorDivMod
327 
328 Returns mathematically correct (floor-based) quotient and remainder for
329 numer and denom, both of which should contain no fractional part. The
330 quotient must fit in 32 bits.
331 FIXME: GET RID OF THIS! (FloorDivMod)
332 ====================
333 */
FloorDivMod(float numer,float denom,int * quotient,int * rem)334 void FloorDivMod (float numer, float denom, int *quotient,
335 		int *rem)
336 {
337 	int		q, r;
338 	float	x;
339 
340 	if (numer >= 0.0)
341 	{
342 
343 		x = floor(numer / denom);
344 		q = (int)x;
345 		r = (int)floor(numer - (x * denom));
346 	}
347 	else
348 	{
349 	//
350 	// perform operations with positive values, and fix mod to make floor-based
351 	//
352 		x = floor(-numer / denom);
353 		q = -(int)x;
354 		r = (int)floor(-numer - (x * denom));
355 		if (r != 0)
356 		{
357 			q--;
358 			r = (int)denom - r;
359 		}
360 	}
361 
362 	*quotient = q;
363 	*rem = r;
364 }
365 
366 
367 /*
368 ===================
369 R_PolysetSetUpForLineScan
370 ====================
371 */
R_PolysetSetUpForLineScan(fixed8_t startvertu,fixed8_t startvertv,fixed8_t endvertu,fixed8_t endvertv)372 void R_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
373 		fixed8_t endvertu, fixed8_t endvertv)
374 {
375 	float		dm, dn;
376 	int			tm, tn;
377 	adivtab_t	*ptemp;
378 
379 // TODO: implement x86 version
380 
381 	errorterm = -1;
382 
383 	tm = endvertu - startvertu;
384 	tn = endvertv - startvertv;
385 
386 	if (((tm <= 16) && (tm >= -15)) &&
387 		((tn <= 16) && (tn >= -15)))
388 	{
389 		ptemp = &adivtab[((tm+15) << 5) + (tn+15)];
390 		ubasestep = ptemp->quotient;
391 		erroradjustup = ptemp->remainder;
392 		erroradjustdown = tn;
393 	}
394 	else
395 	{
396 		dm = tm;
397 		dn = tn;
398 
399 		FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
400 
401 		erroradjustdown = dn;
402 	}
403 }
404 
405 
406 
407 /*
408 ================
409 R_PolysetCalcGradients
410 ================
411 */
412 #if id386 && defined _MSC_VER
R_PolysetCalcGradients(int skinwidth)413 void R_PolysetCalcGradients( int skinwidth )
414 {
415 	static float xstepdenominv, ystepdenominv, t0, t1;
416 	static float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
417 	static float one = 1.0F, negative_one = -1.0F;
418 	static unsigned long t0_int, t1_int;
419 
420 	extern unsigned long fpu_sp24_ceil_cw, fpu_ceil_cw, fpu_chop_cw;
421 
422 	/*
423 	p00_minus_p20 = r_p0[0] - r_p2[0];
424 	p01_minus_p21 = r_p0[1] - r_p2[1];
425 	p10_minus_p20 = r_p1[0] - r_p2[0];
426 	p11_minus_p21 = r_p1[1] - r_p2[1];
427 	*/
428 
429 	__asm mov eax, dword ptr [r_p0+0]
430 	__asm mov ebx, dword ptr [r_p0+4]
431 	__asm sub eax, dword ptr [r_p2+0]
432 	__asm sub ebx, dword ptr [r_p2+4]
433 	__asm mov p00_minus_p20, eax
434 	__asm mov p01_minus_p21, ebx
435 	__asm fild dword ptr p00_minus_p20
436 	__asm fild dword ptr p01_minus_p21
437 	__asm mov eax, dword ptr [r_p1+0]
438 	__asm mov ebx, dword ptr [r_p1+4]
439 	__asm sub eax, dword ptr [r_p2+0]
440 	__asm sub ebx, dword ptr [r_p2+4]
441 	__asm fstp p01_minus_p21
442 	__asm fstp p00_minus_p20
443 	__asm mov p10_minus_p20, eax
444 	__asm mov p11_minus_p21, ebx
445 	__asm fild dword ptr p10_minus_p20
446 	__asm fild dword ptr p11_minus_p21
447 	__asm fstp p11_minus_p21
448 	__asm fstp p10_minus_p20
449 
450 	/*
451 	xstepdenominv = 1.0 / (float)d_xdenom;
452 
453 	ystepdenominv = -xstepdenominv;
454 	*/
455 
456 	/*
457 	** put FPU in single precision ceil mode
458 	*/
459 	__asm fldcw word ptr [fpu_sp24_ceil_cw]
460 //	__asm fldcw word ptr [fpu_ceil_cw]
461 
462 	__asm fild  dword ptr d_xdenom    ; d_xdenom
463 	__asm fdivr one                   ; 1 / d_xdenom
464 	__asm fst   xstepdenominv         ;
465 	__asm fmul  negative_one          ; -( 1 / d_xdenom )
466 
467 // ceil () for light so positive steps are exaggerated, negative steps
468 // diminished,  pushing us away from underflow toward overflow. Underflow is
469 // very visible, overflow is very unlikely, because of ambient lighting
470 	/*
471 	t0 = r_p0[4] - r_p2[4];
472 	t1 = r_p1[4] - r_p2[4];
473 	r_lstepx = (int)
474 			ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
475 	r_lstepy = (int)
476 			ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
477 	*/
478 	__asm mov   eax, dword ptr [r_p0+16]
479 	__asm mov   ebx, dword ptr [r_p1+16]
480 	__asm sub   eax, dword ptr [r_p2+16]
481 	__asm sub   ebx, dword ptr [r_p2+16]
482 
483 	__asm fstp  ystepdenominv       ; (empty)
484 
485 	__asm mov   t0_int, eax
486 	__asm mov   t1_int, ebx
487 	__asm fild  t0_int              ; t0
488 	__asm fild  t1_int              ; t1 | t0
489 	__asm fxch  st(1)               ; t0 | t1
490 	__asm fstp  t0                  ; t1
491 	__asm fst   t1                  ; t1
492 	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
493 	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
494 	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
495 	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
496 	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
497 	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
498 	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
499 	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
500 	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
501 	__asm fsubrp st(1), st          ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
502 	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
503 	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
504 	__asm fxch  st(1)
505 	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
506 	__asm fxch  st(1)               ; r_lstepx | r_lstepy
507 	__asm fistp dword ptr [r_lstepx]
508 	__asm fistp dword ptr [r_lstepy]
509 
510 	/*
511 	** put FPU back into extended precision chop mode
512 	*/
513 	__asm fldcw word ptr [fpu_chop_cw]
514 
515 	/*
516 	t0 = r_p0[2] - r_p2[2];
517 	t1 = r_p1[2] - r_p2[2];
518 	r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
519 			xstepdenominv);
520 	r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
521 			ystepdenominv);
522 	*/
523 	__asm mov eax, dword ptr [r_p0+8]
524 	__asm mov ebx, dword ptr [r_p1+8]
525 	__asm sub eax, dword ptr [r_p2+8]
526 	__asm sub ebx, dword ptr [r_p2+8]
527 	__asm mov   t0_int, eax
528 	__asm mov   t1_int, ebx
529 	__asm fild  t0_int              ; t0
530 	__asm fild  t1_int              ; t1 | t0
531 	__asm fxch  st(1)               ; t0 | t1
532 	__asm fstp  t0                  ; t1
533 	__asm fst   t1                  ; (empty)
534 
535 	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
536 	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
537 	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
538 	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
539 	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
540 	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
541 	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
542 	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
543 	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
544 	__asm fsubrp st(1), st           ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
545 	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
546 	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
547 	__asm fxch  st(1)
548 	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
549 	__asm fxch  st(1)               ; r_lstepx | r_lstepy
550 	__asm fistp dword ptr [r_sstepx]
551 	__asm fistp dword ptr [r_sstepy]
552 
553 	/*
554 	t0 = r_p0[3] - r_p2[3];
555 	t1 = r_p1[3] - r_p2[3];
556 	r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
557 			xstepdenominv);
558 	r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
559 			ystepdenominv);
560 	*/
561 	__asm mov eax, dword ptr [r_p0+12]
562 	__asm mov ebx, dword ptr [r_p1+12]
563 	__asm sub eax, dword ptr [r_p2+12]
564 	__asm sub ebx, dword ptr [r_p2+12]
565 
566 	__asm mov   t0_int, eax
567 	__asm mov   t1_int, ebx
568 	__asm fild  t0_int              ; t0
569 	__asm fild  t1_int              ; t1 | t0
570 	__asm fxch  st(1)               ; t0 | t1
571 	__asm fstp  t0                  ; t1
572 	__asm fst   t1                  ; (empty)
573 
574 	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
575 	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
576 	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
577 	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
578 	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
579 	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
580 	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
581 	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
582 	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
583 	__asm fsubrp st(1), st           ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
584 	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
585 	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
586 	__asm fxch  st(1)
587 	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
588 	__asm fxch  st(1)               ; r_lstepx | r_lstepy
589 	__asm fistp dword ptr [r_tstepx]
590 	__asm fistp dword ptr [r_tstepy]
591 
592 	/*
593 	t0 = r_p0[5] - r_p2[5];
594 	t1 = r_p1[5] - r_p2[5];
595 	r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
596 			xstepdenominv);
597 	r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
598 			ystepdenominv);
599 	*/
600 	__asm mov eax, dword ptr [r_p0+20]
601 	__asm mov ebx, dword ptr [r_p1+20]
602 	__asm sub eax, dword ptr [r_p2+20]
603 	__asm sub ebx, dword ptr [r_p2+20]
604 
605 	__asm mov   t0_int, eax
606 	__asm mov   t1_int, ebx
607 	__asm fild  t0_int              ; t0
608 	__asm fild  t1_int              ; t1 | t0
609 	__asm fxch  st(1)               ; t0 | t1
610 	__asm fstp  t0                  ; t1
611 	__asm fst   t1                  ; (empty)
612 
613 	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
614 	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
615 	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
616 	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
617 	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
618 	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
619 	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
620 	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
621 	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
622 	__asm fsubrp st(1), st           ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
623 	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
624 	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
625 	__asm fxch  st(1)
626 	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
627 	__asm fxch  st(1)               ; r_lstepx | r_lstepy
628 	__asm fistp dword ptr [r_zistepx]
629 	__asm fistp dword ptr [r_zistepy]
630 
631 	/*
632 #if	id386ALIAS
633 	a_sstepxfrac = r_sstepx << 16;
634 	a_tstepxfrac = r_tstepx << 16;
635 #else
636 	a_sstepxfrac = r_sstepx & 0xFFFF;
637 	a_tstepxfrac = r_tstepx & 0xFFFF;
638 #endif
639 	*/
640 	__asm mov eax, d_pdrawspans
641 	__asm cmp eax, offset R_PolysetDrawSpans8_Opaque
642 	__asm mov eax, r_sstepx
643 	__asm mov ebx, r_tstepx
644 	__asm jne translucent
645 //#if id386ALIAS
646 	__asm shl eax, 16
647 	__asm shl ebx, 16
648 	__asm jmp done_with_steps
649 //#else
650 translucent:
651 	__asm and eax, 0ffffh
652 	__asm and ebx, 0ffffh
653 //#endif
654 done_with_steps:
655 	__asm mov a_sstepxfrac, eax
656 	__asm mov a_tstepxfrac, ebx
657 
658 	/*
659 	a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
660 	*/
661 	__asm mov ebx, r_tstepx
662 	__asm mov ecx, r_sstepx
663 	__asm sar ebx, 16
664 	__asm mov eax, skinwidth
665 	__asm mul ebx
666 	__asm sar ecx, 16
667 	__asm add eax, ecx
668 	__asm mov a_ststepxwhole, eax
669 }
670 #else
R_PolysetCalcGradients(int skinwidth)671 void R_PolysetCalcGradients (int skinwidth)
672 {
673 	float	xstepdenominv, ystepdenominv, t0, t1;
674 	float	p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
675 
676 	p00_minus_p20 = r_p0[0] - r_p2[0];
677 	p01_minus_p21 = r_p0[1] - r_p2[1];
678 	p10_minus_p20 = r_p1[0] - r_p2[0];
679 	p11_minus_p21 = r_p1[1] - r_p2[1];
680 
681 	xstepdenominv = 1.0 / (float)d_xdenom;
682 
683 	ystepdenominv = -xstepdenominv;
684 
685 // ceil () for light so positive steps are exaggerated, negative steps
686 // diminished,  pushing us away from underflow toward overflow. Underflow is
687 // very visible, overflow is very unlikely, because of ambient lighting
688 	t0 = r_p0[4] - r_p2[4];
689 	t1 = r_p1[4] - r_p2[4];
690 	r_lstepx = (int)
691 			ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
692 	r_lstepy = (int)
693 			ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
694 
695 	t0 = r_p0[2] - r_p2[2];
696 	t1 = r_p1[2] - r_p2[2];
697 	r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
698 			xstepdenominv);
699 	r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
700 			ystepdenominv);
701 
702 	t0 = r_p0[3] - r_p2[3];
703 	t1 = r_p1[3] - r_p2[3];
704 	r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
705 			xstepdenominv);
706 	r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
707 			ystepdenominv);
708 
709 	t0 = r_p0[5] - r_p2[5];
710 	t1 = r_p1[5] - r_p2[5];
711 	r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
712 			xstepdenominv);
713 	r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
714 			ystepdenominv);
715 
716 #if id386
717 	if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
718 	{
719 		a_sstepxfrac = r_sstepx << 16;
720 		a_tstepxfrac = r_tstepx << 16;
721 	}
722 	else
723 #endif
724 	{
725 		a_sstepxfrac = r_sstepx & 0xFFFF;
726 		a_tstepxfrac = r_tstepx & 0xFFFF;
727 	}
728 
729 	a_ststepxwhole = skinwidth * (r_tstepx >> 16) + VID_BYTES * (r_sstepx >> 16);
730 }
731 #endif
732 
733 #ifdef TRUECOLOR_RENDERER
734 
R_PolysetDrawSpansTranslucent(spanpackage_t * pspanpackage)735 void R_PolysetDrawSpansTranslucent( spanpackage_t *pspanpackage ) {
736 	int		lcount;
737 	byte	*lpdest;
738 	byte	*lptex;
739 	int		lsfrac, ltfrac;
740 	int		llight;
741 	int		lzi;
742 	short	*lpz;
743 
744 	do {
745 		lcount = d_aspancount - pspanpackage->count;
746 
747 		errorterm += erroradjustup;
748 		if (errorterm >= 0) {
749 			d_aspancount += d_countextrastep;
750 			errorterm -= erroradjustdown;
751 		} else {
752 			d_aspancount += ubasestep;
753 		}
754 
755 		if (lcount) {
756 			lpdest = pspanpackage->pdest;
757 			lptex = pspanpackage->ptex;
758 			lpz = pspanpackage->pz;
759 			lsfrac = pspanpackage->sfrac;
760 			ltfrac = pspanpackage->tfrac;
761 			llight = pspanpackage->light;
762 			lzi = pspanpackage->zi;
763 
764 			do {
765 				if ((lzi >> 16) >= *lpz) {
766 					lpdest[0] = r_aliasOneMinusAlphaTable[lpdest[0]] + r_aliasAlphaTable[lptex[0]];
767 					lpdest[1] = r_aliasOneMinusAlphaTable[lpdest[1]] + r_aliasAlphaTable[lptex[1]];
768 					lpdest[2] = r_aliasOneMinusAlphaTable[lpdest[2]] + r_aliasAlphaTable[lptex[2]];
769 				}
770 				lpdest += VID_BYTES;
771 				lzi += r_zistepx;
772 				lpz++;
773 				llight += r_lstepx;
774 				lptex += a_ststepxwhole;
775 				lsfrac += a_sstepxfrac;
776 				lptex += ( lsfrac >> 16 ) << VID_SHIFT;
777 				lsfrac &= 0xFFFF;
778 				ltfrac += a_tstepxfrac;
779 				if (ltfrac & 0x10000) {
780 					lptex += r_affinetridesc.skinwidth;
781 					ltfrac &= 0xFFFF;
782 				}
783 			} while (--lcount);
784 		}
785 
786 		pspanpackage++;
787 	} while (pspanpackage->count != -999999);
788 }
789 
R_PolysetDrawSpansOpaque(spanpackage_t * pspanpackage)790 void R_PolysetDrawSpansOpaque( spanpackage_t *pspanpackage ) {
791 	int		lcount;
792 	byte	*lpdest;
793 	byte	*lptex;
794 	int		lsfrac, ltfrac;
795 	int		llight;
796 	int		lzi;
797 	short	*lpz;
798 
799 	do {
800 		lcount = d_aspancount - pspanpackage->count;
801 
802 		errorterm += erroradjustup;
803 		if (errorterm >= 0) {
804 			d_aspancount += d_countextrastep;
805 			errorterm -= erroradjustdown;
806 		} else {
807 			d_aspancount += ubasestep;
808 		}
809 
810 		if (lcount) {
811 			lpdest = pspanpackage->pdest;
812 			lptex = pspanpackage->ptex;
813 			lpz = pspanpackage->pz;
814 			lsfrac = pspanpackage->sfrac;
815 			ltfrac = pspanpackage->tfrac;
816 			llight = pspanpackage->light;
817 			lzi = pspanpackage->zi;
818 
819 			do {
820 				if ((lzi >> 16) >= *lpz) {
821 					*lpz = lzi >> 16;
822 					*( uint32 * )lpdest = *( uint32 * )lptex;
823 				}
824 				lpdest += VID_BYTES;
825 				lzi += r_zistepx;
826 				lpz++;
827 				llight += r_lstepx;
828 				lptex += a_ststepxwhole;
829 				lsfrac += a_sstepxfrac;
830 				lptex += ( lsfrac >> 16 ) << VID_SHIFT;
831 				lsfrac &= 0xFFFF;
832 				ltfrac += a_tstepxfrac;
833 				if (ltfrac & 0x10000) {
834 					lptex += r_affinetridesc.skinwidth;
835 					ltfrac &= 0xFFFF;
836 				}
837 			} while (--lcount);
838 		}
839 
840 		pspanpackage++;
841 	} while (pspanpackage->count != -999999);
842 }
843 
844 #else /* TRUECOLOR_RENDERER */
845 
846 /*
847 ================
848 R_PolysetDrawThreshSpans8
849 
850 Random fizzle fade rasterizer
851 ================
852 */
R_PolysetDrawThreshSpans8(spanpackage_t * pspanpackage)853 void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage)
854 {
855 	int		lcount;
856 	byte	*lpdest;
857 	byte	*lptex;
858 	int		lsfrac, ltfrac;
859 	int		llight;
860 	int		lzi;
861 	short	*lpz;
862 
863 	do
864 	{
865 		lcount = d_aspancount - pspanpackage->count;
866 
867 		errorterm += erroradjustup;
868 		if (errorterm >= 0)
869 		{
870 			d_aspancount += d_countextrastep;
871 			errorterm -= erroradjustdown;
872 		}
873 		else
874 		{
875 			d_aspancount += ubasestep;
876 		}
877 
878 		if (lcount)
879 		{
880 			lpdest = pspanpackage->pdest;
881 			lptex = pspanpackage->ptex;
882 			lpz = pspanpackage->pz;
883 			lsfrac = pspanpackage->sfrac;
884 			ltfrac = pspanpackage->tfrac;
885 			llight = pspanpackage->light;
886 			lzi = pspanpackage->zi;
887 
888 			do
889 			{
890 				if ((lzi >> 16) >= *lpz)
891 				{
892 					rand1k_index = (rand1k_index + 1) & MASK_1K;
893 
894 					if (rand1k[rand1k_index] <= r_affinetridesc.vis_thresh)
895 					{
896 						*lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)];
897 						*lpz = lzi >> 16;
898 					}
899 				}
900 
901 				lpdest++;
902 				lzi += r_zistepx;
903 				lpz++;
904 				llight += r_lstepx;
905 				lptex += a_ststepxwhole;
906 				lsfrac += a_sstepxfrac;
907 				lptex += lsfrac >> 16;
908 				lsfrac &= 0xFFFF;
909 				ltfrac += a_tstepxfrac;
910 				if (ltfrac & 0x10000)
911 				{
912 					lptex += r_affinetridesc.skinwidth;
913 					ltfrac &= 0xFFFF;
914 				}
915 			} while (--lcount);
916 		}
917 
918 		pspanpackage++;
919 	} while (pspanpackage->count != -999999);
920 }
921 
922 
923 /*
924 ================
925 R_PolysetDrawSpans8
926 ================
927 */
R_PolysetDrawSpans8_33(spanpackage_t * pspanpackage)928 void R_PolysetDrawSpans8_33( spanpackage_t *pspanpackage)
929 {
930 	int		lcount;
931 	byte	*lpdest;
932 	byte	*lptex;
933 	int		lsfrac, ltfrac;
934 	int		llight;
935 	int		lzi;
936 	short	*lpz;
937 
938 	do
939 	{
940 		lcount = d_aspancount - pspanpackage->count;
941 
942 		errorterm += erroradjustup;
943 		if (errorterm >= 0)
944 		{
945 			d_aspancount += d_countextrastep;
946 			errorterm -= erroradjustdown;
947 		}
948 		else
949 		{
950 			d_aspancount += ubasestep;
951 		}
952 
953 		if (lcount)
954 		{
955 			lpdest = pspanpackage->pdest;
956 			lptex = pspanpackage->ptex;
957 			lpz = pspanpackage->pz;
958 			lsfrac = pspanpackage->sfrac;
959 			ltfrac = pspanpackage->tfrac;
960 			llight = pspanpackage->light;
961 			lzi = pspanpackage->zi;
962 
963 			do
964 			{
965 				if ((lzi >> 16) >= *lpz)
966 				{
967 					int temp = vid.colormap[*lptex + ( llight & 0xFF00 )];
968 
969 					*lpdest = vid.alphamap[temp+ *lpdest*256];
970 				}
971 				lpdest++;
972 				lzi += r_zistepx;
973 				lpz++;
974 				llight += r_lstepx;
975 				lptex += a_ststepxwhole;
976 				lsfrac += a_sstepxfrac;
977 				lptex += lsfrac >> 16;
978 				lsfrac &= 0xFFFF;
979 				ltfrac += a_tstepxfrac;
980 				if (ltfrac & 0x10000)
981 				{
982 					lptex += r_affinetridesc.skinwidth;
983 					ltfrac &= 0xFFFF;
984 				}
985 			} while (--lcount);
986 		}
987 
988 		pspanpackage++;
989 	} while (pspanpackage->count != -999999);
990 }
991 
R_PolysetDrawSpansConstant8_33(spanpackage_t * pspanpackage)992 void R_PolysetDrawSpansConstant8_33( spanpackage_t *pspanpackage)
993 {
994 	int		lcount;
995 	byte	*lpdest;
996 	int		lzi;
997 	short	*lpz;
998 
999 	do
1000 	{
1001 		lcount = d_aspancount - pspanpackage->count;
1002 
1003 		errorterm += erroradjustup;
1004 		if (errorterm >= 0)
1005 		{
1006 			d_aspancount += d_countextrastep;
1007 			errorterm -= erroradjustdown;
1008 		}
1009 		else
1010 		{
1011 			d_aspancount += ubasestep;
1012 		}
1013 
1014 		if (lcount)
1015 		{
1016 			lpdest = pspanpackage->pdest;
1017 			lpz = pspanpackage->pz;
1018 			lzi = pspanpackage->zi;
1019 
1020 			do
1021 			{
1022 				if ((lzi >> 16) >= *lpz)
1023 				{
1024 					*lpdest = vid.alphamap[r_aliasblendcolor + *lpdest*256];
1025 				}
1026 				lpdest++;
1027 				lzi += r_zistepx;
1028 				lpz++;
1029 			} while (--lcount);
1030 		}
1031 
1032 		pspanpackage++;
1033 	} while (pspanpackage->count != -999999);
1034 }
1035 
R_PolysetDrawSpans8_66(spanpackage_t * pspanpackage)1036 void R_PolysetDrawSpans8_66(spanpackage_t *pspanpackage)
1037 {
1038 	int		lcount;
1039 	byte	*lpdest;
1040 	byte	*lptex;
1041 	int		lsfrac, ltfrac;
1042 	int		llight;
1043 	int		lzi;
1044 	short	*lpz;
1045 
1046 	do
1047 	{
1048 		lcount = d_aspancount - pspanpackage->count;
1049 
1050 		errorterm += erroradjustup;
1051 		if (errorterm >= 0)
1052 		{
1053 			d_aspancount += d_countextrastep;
1054 			errorterm -= erroradjustdown;
1055 		}
1056 		else
1057 		{
1058 			d_aspancount += ubasestep;
1059 		}
1060 
1061 		if (lcount)
1062 		{
1063 			lpdest = pspanpackage->pdest;
1064 			lptex = pspanpackage->ptex;
1065 			lpz = pspanpackage->pz;
1066 			lsfrac = pspanpackage->sfrac;
1067 			ltfrac = pspanpackage->tfrac;
1068 			llight = pspanpackage->light;
1069 			lzi = pspanpackage->zi;
1070 
1071 			do
1072 			{
1073 				if ((lzi >> 16) >= *lpz)
1074 				{
1075 					int temp = vid.colormap[*lptex + ( llight & 0xFF00 )];
1076 
1077 					*lpdest = vid.alphamap[temp*256 + *lpdest];
1078 					*lpz = lzi >> 16;
1079 				}
1080 				lpdest++;
1081 				lzi += r_zistepx;
1082 				lpz++;
1083 				llight += r_lstepx;
1084 				lptex += a_ststepxwhole;
1085 				lsfrac += a_sstepxfrac;
1086 				lptex += lsfrac >> 16;
1087 				lsfrac &= 0xFFFF;
1088 				ltfrac += a_tstepxfrac;
1089 				if (ltfrac & 0x10000)
1090 				{
1091 					lptex += r_affinetridesc.skinwidth;
1092 					ltfrac &= 0xFFFF;
1093 				}
1094 			} while (--lcount);
1095 		}
1096 
1097 		pspanpackage++;
1098 	} while (pspanpackage->count != -999999);
1099 }
1100 
R_PolysetDrawSpansConstant8_66(spanpackage_t * pspanpackage)1101 void R_PolysetDrawSpansConstant8_66( spanpackage_t *pspanpackage)
1102 {
1103 	int		lcount;
1104 	byte	*lpdest;
1105 	int		lzi;
1106 	short	*lpz;
1107 
1108 	do
1109 	{
1110 		lcount = d_aspancount - pspanpackage->count;
1111 
1112 		errorterm += erroradjustup;
1113 		if (errorterm >= 0)
1114 		{
1115 			d_aspancount += d_countextrastep;
1116 			errorterm -= erroradjustdown;
1117 		}
1118 		else
1119 		{
1120 			d_aspancount += ubasestep;
1121 		}
1122 
1123 		if (lcount)
1124 		{
1125 			lpdest = pspanpackage->pdest;
1126 			lpz = pspanpackage->pz;
1127 			lzi = pspanpackage->zi;
1128 
1129 			do
1130 			{
1131 				if ((lzi >> 16) >= *lpz)
1132 				{
1133 					*lpdest = vid.alphamap[r_aliasblendcolor*256 + *lpdest];
1134 				}
1135 				lpdest++;
1136 				lzi += r_zistepx;
1137 				lpz++;
1138 			} while (--lcount);
1139 		}
1140 
1141 		pspanpackage++;
1142 	} while (pspanpackage->count != -999999);
1143 }
1144 
1145 #if !id386
R_PolysetDrawSpans8_Opaque(spanpackage_t * pspanpackage)1146 void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage)
1147 {
1148 	int		lcount;
1149 
1150 	do
1151 	{
1152 		lcount = d_aspancount - pspanpackage->count;
1153 
1154 		errorterm += erroradjustup;
1155 		if (errorterm >= 0)
1156 		{
1157 			d_aspancount += d_countextrastep;
1158 			errorterm -= erroradjustdown;
1159 		}
1160 		else
1161 		{
1162 			d_aspancount += ubasestep;
1163 		}
1164 
1165 		if (lcount)
1166 		{
1167 			int		lsfrac, ltfrac;
1168 			byte	*lpdest;
1169 			byte	*lptex;
1170 			int		llight;
1171 			int		lzi;
1172 			short	*lpz;
1173 
1174 			lpdest = pspanpackage->pdest;
1175 			lptex = pspanpackage->ptex;
1176 			lpz = pspanpackage->pz;
1177 			lsfrac = pspanpackage->sfrac;
1178 			ltfrac = pspanpackage->tfrac;
1179 			llight = pspanpackage->light;
1180 			lzi = pspanpackage->zi;
1181 
1182 			do
1183 			{
1184 				if ((lzi >> 16) >= *lpz)
1185 				{
1186 //PGM
1187 					if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
1188 						*lpdest = ((byte *)vid.colormap)[irtable[*lptex]];
1189 					else
1190 					*lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)];
1191 //PGM
1192 					*lpz = lzi >> 16;
1193 				}
1194 				lpdest++;
1195 				lzi += r_zistepx;
1196 				lpz++;
1197 				llight += r_lstepx;
1198 				lptex += a_ststepxwhole;
1199 				lsfrac += a_sstepxfrac;
1200 				lptex += lsfrac >> 16;
1201 				lsfrac &= 0xFFFF;
1202 				ltfrac += a_tstepxfrac;
1203 				if (ltfrac & 0x10000)
1204 				{
1205 					lptex += r_affinetridesc.skinwidth;
1206 					ltfrac &= 0xFFFF;
1207 				}
1208 			} while (--lcount);
1209 		}
1210 
1211 		pspanpackage++;
1212 	} while (pspanpackage->count != -999999);
1213 }
1214 #endif
1215 
1216 
1217 /*
1218 ================
1219 R_PolysetFillSpans8
1220 ================
1221 */
R_PolysetFillSpans8(spanpackage_t * pspanpackage)1222 void R_PolysetFillSpans8 (spanpackage_t *pspanpackage)
1223 {
1224 	int				color;
1225 
1226 // FIXME: do z buffering
1227 
1228 	color = d_aflatcolor++;
1229 
1230 	while (1)
1231 	{
1232 		int		lcount;
1233 		byte	*lpdest;
1234 
1235 		lcount = pspanpackage->count;
1236 
1237 		if (lcount == -1)
1238 			return;
1239 
1240 		if (lcount)
1241 		{
1242 			lpdest = pspanpackage->pdest;
1243 
1244 			do
1245 			{
1246 				*lpdest++ = color;
1247 			} while (--lcount);
1248 		}
1249 
1250 		pspanpackage++;
1251 	}
1252 }
1253 
1254 #endif /* !TRUECOLOR_RENDERER */
1255 
1256 /*
1257 ================
1258 R_RasterizeAliasPolySmooth
1259 ================
1260 */
R_RasterizeAliasPolySmooth(void)1261 void R_RasterizeAliasPolySmooth (void)
1262 {
1263 	int				initialleftheight, initialrightheight;
1264 	int				*plefttop, *prighttop, *pleftbottom, *prightbottom;
1265 	int				working_lstepx, originalcount;
1266 
1267 	plefttop = pedgetable->pleftedgevert0;
1268 	prighttop = pedgetable->prightedgevert0;
1269 
1270 	pleftbottom = pedgetable->pleftedgevert1;
1271 	prightbottom = pedgetable->prightedgevert1;
1272 
1273 	initialleftheight = pleftbottom[1] - plefttop[1];
1274 	initialrightheight = prightbottom[1] - prighttop[1];
1275 
1276 //
1277 // set the s, t, and light gradients, which are consistent across the triangle
1278 // because being a triangle, things are affine
1279 //
1280 	R_PolysetCalcGradients (r_affinetridesc.skinwidth);
1281 //
1282 // rasterize the polygon
1283 //
1284 
1285 //
1286 // scan out the top (and possibly only) part of the left edge
1287 //
1288 	d_pedgespanpackage = a_spans;
1289 
1290 	ystart = plefttop[1];
1291 	d_aspancount = plefttop[0] - prighttop[0];
1292 
1293 	d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) * VID_BYTES +
1294 			(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
1295 #if id386
1296 	if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
1297 	{
1298 		d_sfrac = (plefttop[2] & 0xFFFF) << 16;
1299 		d_tfrac = (plefttop[3] & 0xFFFF) << 16;
1300 	}
1301 	else
1302 #endif
1303 	{
1304 		d_sfrac = plefttop[2] & 0xFFFF;
1305 		d_tfrac = plefttop[3] & 0xFFFF;
1306 	}
1307 	d_light = plefttop[4];
1308 	d_zi = plefttop[5];
1309 
1310 	d_pdest = (byte *)d_viewbuffer +
1311 			ystart * r_screenwidth + plefttop[0] * VID_BYTES;
1312 	d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
1313 
1314 	if (initialleftheight == 1)
1315 	{
1316 		d_pedgespanpackage->pdest = d_pdest;
1317 		d_pedgespanpackage->pz = d_pz;
1318 		d_pedgespanpackage->count = d_aspancount;
1319 		d_pedgespanpackage->ptex = d_ptex;
1320 
1321 		d_pedgespanpackage->sfrac = d_sfrac;
1322 		d_pedgespanpackage->tfrac = d_tfrac;
1323 
1324 	// FIXME: need to clamp l, s, t, at both ends?
1325 		d_pedgespanpackage->light = d_light;
1326 		d_pedgespanpackage->zi = d_zi;
1327 
1328 		d_pedgespanpackage++;
1329 	}
1330 	else
1331 	{
1332 		R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
1333 							  pleftbottom[0], pleftbottom[1]);
1334 
1335 #if id386
1336 		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
1337 		{
1338 			d_pzbasestep = (d_zwidth + ubasestep) << 1;
1339 			d_pzextrastep = d_pzbasestep + 2;
1340 		}
1341 		else
1342 #endif
1343 		{
1344 			d_pzbasestep = d_zwidth + ubasestep;
1345 			d_pzextrastep = d_pzbasestep + 1;
1346 		}
1347 
1348 		d_pdestbasestep = r_screenwidth + ( ubasestep << VID_SHIFT );
1349 		d_pdestextrastep = d_pdestbasestep + VID_BYTES;
1350 
1351 	// TODO: can reuse partial expressions here
1352 
1353 	// for negative steps in x along left edge, bias toward overflow rather than
1354 	// underflow (sort of turning the floor () we did in the gradient calcs into
1355 	// ceil (), but plus a little bit)
1356 		if (ubasestep < 0)
1357 			working_lstepx = r_lstepx - 1;
1358 		else
1359 			working_lstepx = r_lstepx;
1360 
1361 		d_countextrastep = ubasestep + 1;
1362 		d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) * VID_BYTES +
1363 				((r_tstepy + r_tstepx * ubasestep) >> 16) *
1364 				r_affinetridesc.skinwidth;
1365 #if id386
1366 		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
1367 		{
1368 			d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
1369 			d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
1370 		}
1371 		else
1372 #endif
1373 		{
1374 			d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
1375 			d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
1376 		}
1377 		d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
1378 		d_zibasestep = r_zistepy + r_zistepx * ubasestep;
1379 
1380 		d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) * VID_BYTES +
1381 				((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
1382 				r_affinetridesc.skinwidth;
1383 #if id386
1384 		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
1385 		{
1386 			d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16;
1387 			d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16;
1388 		}
1389 		else
1390 #endif
1391 		{
1392 			d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF;
1393 			d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF;
1394 		}
1395 		d_lightextrastep = d_lightbasestep + working_lstepx;
1396 		d_ziextrastep = d_zibasestep + r_zistepx;
1397 
1398 #if id386
1399 		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
1400 		{
1401 			R_PolysetScanLeftEdge (initialleftheight);
1402 		}
1403 		else
1404 #endif
1405 		{
1406 			R_PolysetScanLeftEdge_C(initialleftheight);
1407 		}
1408 	}
1409 
1410 //
1411 // scan out the bottom part of the left edge, if it exists
1412 //
1413 	if (pedgetable->numleftedges == 2)
1414 	{
1415 		int		height;
1416 
1417 		plefttop = pleftbottom;
1418 		pleftbottom = pedgetable->pleftedgevert2;
1419 
1420 		height = pleftbottom[1] - plefttop[1];
1421 
1422 // TODO: make this a function; modularize this function in general
1423 
1424 		ystart = plefttop[1];
1425 		d_aspancount = plefttop[0] - prighttop[0];
1426 		d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) * VID_BYTES +
1427 				(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
1428 		d_sfrac = 0;
1429 		d_tfrac = 0;
1430 		d_light = plefttop[4];
1431 		d_zi = plefttop[5];
1432 
1433 		d_pdest = (byte *)d_viewbuffer + ystart * r_screenwidth + ( plefttop[0] << VID_SHIFT );
1434 		d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
1435 
1436 		if (height == 1)
1437 		{
1438 			d_pedgespanpackage->pdest = d_pdest;
1439 			d_pedgespanpackage->pz = d_pz;
1440 			d_pedgespanpackage->count = d_aspancount;
1441 			d_pedgespanpackage->ptex = d_ptex;
1442 
1443 			d_pedgespanpackage->sfrac = d_sfrac;
1444 			d_pedgespanpackage->tfrac = d_tfrac;
1445 
1446 		// FIXME: need to clamp l, s, t, at both ends?
1447 			d_pedgespanpackage->light = d_light;
1448 			d_pedgespanpackage->zi = d_zi;
1449 
1450 			d_pedgespanpackage++;
1451 		}
1452 		else
1453 		{
1454 			R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
1455 								  pleftbottom[0], pleftbottom[1]);
1456 
1457 			d_pdestbasestep = r_screenwidth + ( ubasestep << VID_SHIFT );
1458 			d_pdestextrastep = d_pdestbasestep + VID_BYTES;
1459 
1460 #if id386
1461 			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
1462 			{
1463 				d_pzbasestep = (d_zwidth + ubasestep) << 1;
1464 				d_pzextrastep = d_pzbasestep + 2;
1465 			}
1466 			else
1467 #endif
1468 			{
1469 				d_pzbasestep = d_zwidth + ubasestep;
1470 				d_pzextrastep = d_pzbasestep + 1;
1471 			}
1472 
1473 			if (ubasestep < 0)
1474 				working_lstepx = r_lstepx - 1;
1475 			else
1476 				working_lstepx = r_lstepx;
1477 
1478 			d_countextrastep = ubasestep + 1;
1479 			d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) * VID_BYTES +
1480 					((r_tstepy + r_tstepx * ubasestep) >> 16) *
1481 					r_affinetridesc.skinwidth;
1482 #if id386
1483 			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
1484 			{
1485 				d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
1486 				d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
1487 			}
1488 			else
1489 #endif
1490 			{
1491 				d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
1492 				d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
1493 			}
1494 			d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
1495 			d_zibasestep = r_zistepy + r_zistepx * ubasestep;
1496 
1497 			d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) * VID_BYTES +
1498 					((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
1499 					r_affinetridesc.skinwidth;
1500 #if id386
1501 			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
1502 			{
1503 				d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16;
1504 				d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16;
1505 			}
1506 			else
1507 #endif
1508 			{
1509 				d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF;
1510 				d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF;
1511 			}
1512 			d_lightextrastep = d_lightbasestep + working_lstepx;
1513 			d_ziextrastep = d_zibasestep + r_zistepx;
1514 
1515 #if id386
1516 			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
1517 			{
1518 				R_PolysetScanLeftEdge (height);
1519 			}
1520 			else
1521 #endif
1522 			{
1523 				R_PolysetScanLeftEdge_C(height);
1524 			}
1525 		}
1526 	}
1527 
1528 // scan out the top (and possibly only) part of the right edge, updating the
1529 // count field
1530 	d_pedgespanpackage = a_spans;
1531 
1532 	R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
1533 						  prightbottom[0], prightbottom[1]);
1534 	d_aspancount = 0;
1535 	d_countextrastep = ubasestep + 1;
1536 	originalcount = a_spans[initialrightheight].count;
1537 	a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
1538 	(*d_pdrawspans) (a_spans);
1539 
1540 // scan out the bottom part of the right edge, if it exists
1541 	if (pedgetable->numrightedges == 2)
1542 	{
1543 		int				height;
1544 		spanpackage_t	*pstart;
1545 
1546 		pstart = a_spans + initialrightheight;
1547 		pstart->count = originalcount;
1548 
1549 		d_aspancount = prightbottom[0] - prighttop[0];
1550 
1551 		prighttop = prightbottom;
1552 		prightbottom = pedgetable->prightedgevert2;
1553 
1554 		height = prightbottom[1] - prighttop[1];
1555 
1556 		R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
1557 							  prightbottom[0], prightbottom[1]);
1558 
1559 		d_countextrastep = ubasestep + 1;
1560 		a_spans[initialrightheight + height].count = -999999;
1561 											// mark end of the spanpackages
1562 		(*d_pdrawspans) (pstart);
1563 	}
1564 }
1565 
1566 
1567 /*
1568 ================
1569 R_PolysetSetEdgeTable
1570 ================
1571 */
R_PolysetSetEdgeTable(void)1572 void R_PolysetSetEdgeTable (void)
1573 {
1574 	int			edgetableindex;
1575 
1576 	edgetableindex = 0;	// assume the vertices are already in
1577 						//  top to bottom order
1578 
1579 //
1580 // determine which edges are right & left, and the order in which
1581 // to rasterize them
1582 //
1583 	if (r_p0[1] >= r_p1[1])
1584 	{
1585 		if (r_p0[1] == r_p1[1])
1586 		{
1587 			if (r_p0[1] < r_p2[1])
1588 				pedgetable = &edgetables[2];
1589 			else
1590 				pedgetable = &edgetables[5];
1591 
1592 			return;
1593 		}
1594 		else
1595 		{
1596 			edgetableindex = 1;
1597 		}
1598 	}
1599 
1600 	if (r_p0[1] == r_p2[1])
1601 	{
1602 		if (edgetableindex)
1603 			pedgetable = &edgetables[8];
1604 		else
1605 			pedgetable = &edgetables[9];
1606 
1607 		return;
1608 	}
1609 	else if (r_p1[1] == r_p2[1])
1610 	{
1611 		if (edgetableindex)
1612 			pedgetable = &edgetables[10];
1613 		else
1614 			pedgetable = &edgetables[11];
1615 
1616 		return;
1617 	}
1618 
1619 	if (r_p0[1] > r_p2[1])
1620 		edgetableindex += 2;
1621 
1622 	if (r_p1[1] > r_p2[1])
1623 		edgetableindex += 4;
1624 
1625 	pedgetable = &edgetables[edgetableindex];
1626 }
1627 
1628 
1629