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