diff options
Diffstat (limited to 'apps/plugins/sdl/progs/quake/d_polyse.c')
-rw-r--r-- | apps/plugins/sdl/progs/quake/d_polyse.c | 1111 |
1 files changed, 1111 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/d_polyse.c b/apps/plugins/sdl/progs/quake/d_polyse.c new file mode 100644 index 0000000000..9acd34b102 --- /dev/null +++ b/apps/plugins/sdl/progs/quake/d_polyse.c | |||
@@ -0,0 +1,1111 @@ | |||
1 | /* | ||
2 | Copyright (C) 1996-1997 Id Software, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU General Public License | ||
6 | as published by the Free Software Foundation; either version 2 | ||
7 | of the License, or (at your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
12 | |||
13 | See the GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the Free Software | ||
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | */ | ||
20 | // d_polyset.c: routines for drawing sets of polygons sharing the same | ||
21 | // texture (used for Alias models) | ||
22 | |||
23 | #include "quakedef.h" | ||
24 | #include "r_local.h" | ||
25 | #include "d_local.h" | ||
26 | |||
27 | // TODO: put in span spilling to shrink list size | ||
28 | // !!! if this is changed, it must be changed in d_polysa.s too !!! | ||
29 | #define DPS_MAXSPANS MAXHEIGHT+1 | ||
30 | // 1 extra for spanpackage that marks end | ||
31 | |||
32 | // !!! if this is changed, it must be changed in asm_draw.h too !!! | ||
33 | typedef struct { | ||
34 | void *pdest; | ||
35 | short *pz; | ||
36 | int count; | ||
37 | byte *ptex; | ||
38 | int sfrac, tfrac, light, zi; | ||
39 | } spanpackage_t; | ||
40 | |||
41 | typedef struct { | ||
42 | int isflattop; | ||
43 | int numleftedges; | ||
44 | int *pleftedgevert0; | ||
45 | int *pleftedgevert1; | ||
46 | int *pleftedgevert2; | ||
47 | int numrightedges; | ||
48 | int *prightedgevert0; | ||
49 | int *prightedgevert1; | ||
50 | int *prightedgevert2; | ||
51 | } edgetable; | ||
52 | |||
53 | int r_p0[6], r_p1[6], r_p2[6]; | ||
54 | |||
55 | byte *d_pcolormap; | ||
56 | |||
57 | int d_aflatcolor; | ||
58 | int d_xdenom; | ||
59 | |||
60 | edgetable *pedgetable; | ||
61 | |||
62 | edgetable edgetables[12] = { | ||
63 | {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 }, | ||
64 | {0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL}, | ||
65 | {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL}, | ||
66 | {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 }, | ||
67 | {0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL}, | ||
68 | {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL}, | ||
69 | {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 }, | ||
70 | {0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL}, | ||
71 | {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL}, | ||
72 | {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL}, | ||
73 | {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL}, | ||
74 | {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL}, | ||
75 | }; | ||
76 | |||
77 | // FIXME: some of these can become statics | ||
78 | int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole; | ||
79 | int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy; | ||
80 | int r_zistepx, r_zistepy; | ||
81 | int d_aspancount, d_countextrastep; | ||
82 | |||
83 | spanpackage_t *a_spans; | ||
84 | spanpackage_t *d_pedgespanpackage; | ||
85 | static int ystart; | ||
86 | byte *d_pdest, *d_ptex; | ||
87 | short *d_pz; | ||
88 | int d_sfrac, d_tfrac, d_light, d_zi; | ||
89 | int d_ptexextrastep, d_sfracextrastep; | ||
90 | int d_tfracextrastep, d_lightextrastep, d_pdestextrastep; | ||
91 | int d_lightbasestep, d_pdestbasestep, d_ptexbasestep; | ||
92 | int d_sfracbasestep, d_tfracbasestep; | ||
93 | int d_ziextrastep, d_zibasestep; | ||
94 | int d_pzextrastep, d_pzbasestep; | ||
95 | |||
96 | typedef struct { | ||
97 | int quotient; | ||
98 | int remainder; | ||
99 | } adivtab_t; | ||
100 | |||
101 | static adivtab_t adivtab[32*32] = { | ||
102 | #include "adivtab.h" | ||
103 | }; | ||
104 | |||
105 | byte *skintable[MAX_LBM_HEIGHT]; | ||
106 | int skinwidth; | ||
107 | byte *skinstart; | ||
108 | |||
109 | void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage); | ||
110 | void D_PolysetCalcGradients (int skinwidth); | ||
111 | void D_DrawSubdiv (void); | ||
112 | void D_DrawNonSubdiv (void); | ||
113 | void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3); | ||
114 | void D_PolysetSetEdgeTable (void); | ||
115 | void D_RasterizeAliasPolySmooth (void); | ||
116 | void D_PolysetScanLeftEdge (int height); | ||
117 | |||
118 | #if !id386 | ||
119 | |||
120 | /* | ||
121 | ================ | ||
122 | D_PolysetDraw | ||
123 | ================ | ||
124 | */ | ||
125 | void D_PolysetDraw (void) | ||
126 | { | ||
127 | spanpackage_t spans[DPS_MAXSPANS + 1 + | ||
128 | ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1]; | ||
129 | // one extra because of cache line pretouching | ||
130 | |||
131 | a_spans = (spanpackage_t *) | ||
132 | (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); | ||
133 | |||
134 | if (r_affinetridesc.drawtype) | ||
135 | { | ||
136 | D_DrawSubdiv (); | ||
137 | } | ||
138 | else | ||
139 | { | ||
140 | D_DrawNonSubdiv (); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | |||
145 | /* | ||
146 | ================ | ||
147 | D_PolysetDrawFinalVerts | ||
148 | ================ | ||
149 | */ | ||
150 | void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts) | ||
151 | { | ||
152 | int i, z; | ||
153 | short *zbuf; | ||
154 | |||
155 | for (i=0 ; i<numverts ; i++, fv++) | ||
156 | { | ||
157 | // valid triangle coordinates for filling can include the bottom and | ||
158 | // right clip edges, due to the fill rule; these shouldn't be drawn | ||
159 | if ((fv->v[0] < r_refdef.vrectright) && | ||
160 | (fv->v[1] < r_refdef.vrectbottom)) | ||
161 | { | ||
162 | z = fv->v[5]>>16; | ||
163 | zbuf = zspantable[fv->v[1]] + fv->v[0]; | ||
164 | if (z >= *zbuf) | ||
165 | { | ||
166 | int pix; | ||
167 | |||
168 | *zbuf = z; | ||
169 | pix = skintable[fv->v[3]>>16][fv->v[2]>>16]; | ||
170 | pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00) ]; | ||
171 | d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix; | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | |||
178 | /* | ||
179 | ================ | ||
180 | D_DrawSubdiv | ||
181 | ================ | ||
182 | */ | ||
183 | void D_DrawSubdiv (void) | ||
184 | { | ||
185 | mtriangle_t *ptri; | ||
186 | finalvert_t *pfv, *index0, *index1, *index2; | ||
187 | int i; | ||
188 | int lnumtriangles; | ||
189 | |||
190 | pfv = r_affinetridesc.pfinalverts; | ||
191 | ptri = r_affinetridesc.ptriangles; | ||
192 | lnumtriangles = r_affinetridesc.numtriangles; | ||
193 | |||
194 | for (i=0 ; i<lnumtriangles ; i++) | ||
195 | { | ||
196 | index0 = pfv + ptri[i].vertindex[0]; | ||
197 | index1 = pfv + ptri[i].vertindex[1]; | ||
198 | index2 = pfv + ptri[i].vertindex[2]; | ||
199 | |||
200 | if (((index0->v[1]-index1->v[1]) * | ||
201 | (index0->v[0]-index2->v[0]) - | ||
202 | (index0->v[0]-index1->v[0]) * | ||
203 | (index0->v[1]-index2->v[1])) >= 0) | ||
204 | { | ||
205 | continue; | ||
206 | } | ||
207 | |||
208 | d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00]; | ||
209 | |||
210 | if (ptri[i].facesfront) | ||
211 | { | ||
212 | D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); | ||
213 | } | ||
214 | else | ||
215 | { | ||
216 | int s0, s1, s2; | ||
217 | |||
218 | s0 = index0->v[2]; | ||
219 | s1 = index1->v[2]; | ||
220 | s2 = index2->v[2]; | ||
221 | |||
222 | if (index0->flags & ALIAS_ONSEAM) | ||
223 | index0->v[2] += r_affinetridesc.seamfixupX16; | ||
224 | if (index1->flags & ALIAS_ONSEAM) | ||
225 | index1->v[2] += r_affinetridesc.seamfixupX16; | ||
226 | if (index2->flags & ALIAS_ONSEAM) | ||
227 | index2->v[2] += r_affinetridesc.seamfixupX16; | ||
228 | |||
229 | D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); | ||
230 | |||
231 | index0->v[2] = s0; | ||
232 | index1->v[2] = s1; | ||
233 | index2->v[2] = s2; | ||
234 | } | ||
235 | } | ||
236 | } | ||
237 | |||
238 | |||
239 | /* | ||
240 | ================ | ||
241 | D_DrawNonSubdiv | ||
242 | ================ | ||
243 | */ | ||
244 | void D_DrawNonSubdiv (void) | ||
245 | { | ||
246 | mtriangle_t *ptri; | ||
247 | finalvert_t *pfv, *index0, *index1, *index2; | ||
248 | int i; | ||
249 | int lnumtriangles; | ||
250 | |||
251 | pfv = r_affinetridesc.pfinalverts; | ||
252 | ptri = r_affinetridesc.ptriangles; | ||
253 | lnumtriangles = r_affinetridesc.numtriangles; | ||
254 | |||
255 | for (i=0 ; i<lnumtriangles ; i++, ptri++) | ||
256 | { | ||
257 | index0 = pfv + ptri->vertindex[0]; | ||
258 | index1 = pfv + ptri->vertindex[1]; | ||
259 | index2 = pfv + ptri->vertindex[2]; | ||
260 | |||
261 | d_xdenom = (index0->v[1]-index1->v[1]) * | ||
262 | (index0->v[0]-index2->v[0]) - | ||
263 | (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]); | ||
264 | |||
265 | if (d_xdenom >= 0) | ||
266 | { | ||
267 | continue; | ||
268 | } | ||
269 | |||
270 | r_p0[0] = index0->v[0]; // u | ||
271 | r_p0[1] = index0->v[1]; // v | ||
272 | r_p0[2] = index0->v[2]; // s | ||
273 | r_p0[3] = index0->v[3]; // t | ||
274 | r_p0[4] = index0->v[4]; // light | ||
275 | r_p0[5] = index0->v[5]; // iz | ||
276 | |||
277 | r_p1[0] = index1->v[0]; | ||
278 | r_p1[1] = index1->v[1]; | ||
279 | r_p1[2] = index1->v[2]; | ||
280 | r_p1[3] = index1->v[3]; | ||
281 | r_p1[4] = index1->v[4]; | ||
282 | r_p1[5] = index1->v[5]; | ||
283 | |||
284 | r_p2[0] = index2->v[0]; | ||
285 | r_p2[1] = index2->v[1]; | ||
286 | r_p2[2] = index2->v[2]; | ||
287 | r_p2[3] = index2->v[3]; | ||
288 | r_p2[4] = index2->v[4]; | ||
289 | r_p2[5] = index2->v[5]; | ||
290 | |||
291 | if (!ptri->facesfront) | ||
292 | { | ||
293 | if (index0->flags & ALIAS_ONSEAM) | ||
294 | r_p0[2] += r_affinetridesc.seamfixupX16; | ||
295 | if (index1->flags & ALIAS_ONSEAM) | ||
296 | r_p1[2] += r_affinetridesc.seamfixupX16; | ||
297 | if (index2->flags & ALIAS_ONSEAM) | ||
298 | r_p2[2] += r_affinetridesc.seamfixupX16; | ||
299 | } | ||
300 | |||
301 | D_PolysetSetEdgeTable (); | ||
302 | D_RasterizeAliasPolySmooth (); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | |||
307 | /* | ||
308 | ================ | ||
309 | D_PolysetRecursiveTriangle | ||
310 | ================ | ||
311 | */ | ||
312 | void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3) | ||
313 | { | ||
314 | int *temp; | ||
315 | int d; | ||
316 | int new[6]; | ||
317 | int z; | ||
318 | short *zbuf; | ||
319 | |||
320 | d = lp2[0] - lp1[0]; | ||
321 | if (d < -1 || d > 1) | ||
322 | goto split; | ||
323 | d = lp2[1] - lp1[1]; | ||
324 | if (d < -1 || d > 1) | ||
325 | goto split; | ||
326 | |||
327 | d = lp3[0] - lp2[0]; | ||
328 | if (d < -1 || d > 1) | ||
329 | goto split2; | ||
330 | d = lp3[1] - lp2[1]; | ||
331 | if (d < -1 || d > 1) | ||
332 | goto split2; | ||
333 | |||
334 | d = lp1[0] - lp3[0]; | ||
335 | if (d < -1 || d > 1) | ||
336 | goto split3; | ||
337 | d = lp1[1] - lp3[1]; | ||
338 | if (d < -1 || d > 1) | ||
339 | { | ||
340 | split3: | ||
341 | temp = lp1; | ||
342 | lp1 = lp3; | ||
343 | lp3 = lp2; | ||
344 | lp2 = temp; | ||
345 | |||
346 | goto split; | ||
347 | } | ||
348 | |||
349 | return; // entire tri is filled | ||
350 | |||
351 | split2: | ||
352 | temp = lp1; | ||
353 | lp1 = lp2; | ||
354 | lp2 = lp3; | ||
355 | lp3 = temp; | ||
356 | |||
357 | split: | ||
358 | // split this edge | ||
359 | new[0] = (lp1[0] + lp2[0]) >> 1; | ||
360 | new[1] = (lp1[1] + lp2[1]) >> 1; | ||
361 | new[2] = (lp1[2] + lp2[2]) >> 1; | ||
362 | new[3] = (lp1[3] + lp2[3]) >> 1; | ||
363 | new[5] = (lp1[5] + lp2[5]) >> 1; | ||
364 | |||
365 | // draw the point if splitting a leading edge | ||
366 | if (lp2[1] > lp1[1]) | ||
367 | goto nodraw; | ||
368 | if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0])) | ||
369 | goto nodraw; | ||
370 | |||
371 | |||
372 | z = new[5]>>16; | ||
373 | zbuf = zspantable[new[1]] + new[0]; | ||
374 | if (z >= *zbuf) | ||
375 | { | ||
376 | int pix; | ||
377 | |||
378 | *zbuf = z; | ||
379 | pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; | ||
380 | d_viewbuffer[d_scantable[new[1]] + new[0]] = pix; | ||
381 | } | ||
382 | |||
383 | nodraw: | ||
384 | // recursively continue | ||
385 | D_PolysetRecursiveTriangle (lp3, lp1, new); | ||
386 | D_PolysetRecursiveTriangle (lp3, new, lp2); | ||
387 | } | ||
388 | |||
389 | #endif // !id386 | ||
390 | |||
391 | |||
392 | /* | ||
393 | ================ | ||
394 | D_PolysetUpdateTables | ||
395 | ================ | ||
396 | */ | ||
397 | void D_PolysetUpdateTables (void) | ||
398 | { | ||
399 | int i; | ||
400 | byte *s; | ||
401 | |||
402 | if (r_affinetridesc.skinwidth != skinwidth || | ||
403 | r_affinetridesc.pskin != skinstart) | ||
404 | { | ||
405 | skinwidth = r_affinetridesc.skinwidth; | ||
406 | skinstart = r_affinetridesc.pskin; | ||
407 | s = skinstart; | ||
408 | for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth) | ||
409 | skintable[i] = s; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | |||
414 | #if !id386 | ||
415 | |||
416 | /* | ||
417 | =================== | ||
418 | D_PolysetScanLeftEdge | ||
419 | ==================== | ||
420 | */ | ||
421 | void D_PolysetScanLeftEdge (int height) | ||
422 | { | ||
423 | |||
424 | do | ||
425 | { | ||
426 | d_pedgespanpackage->pdest = d_pdest; | ||
427 | d_pedgespanpackage->pz = d_pz; | ||
428 | d_pedgespanpackage->count = d_aspancount; | ||
429 | d_pedgespanpackage->ptex = d_ptex; | ||
430 | |||
431 | d_pedgespanpackage->sfrac = d_sfrac; | ||
432 | d_pedgespanpackage->tfrac = d_tfrac; | ||
433 | |||
434 | // FIXME: need to clamp l, s, t, at both ends? | ||
435 | d_pedgespanpackage->light = d_light; | ||
436 | d_pedgespanpackage->zi = d_zi; | ||
437 | |||
438 | d_pedgespanpackage++; | ||
439 | |||
440 | errorterm += erroradjustup; | ||
441 | if (errorterm >= 0) | ||
442 | { | ||
443 | d_pdest += d_pdestextrastep; | ||
444 | d_pz += d_pzextrastep; | ||
445 | d_aspancount += d_countextrastep; | ||
446 | d_ptex += d_ptexextrastep; | ||
447 | d_sfrac += d_sfracextrastep; | ||
448 | d_ptex += d_sfrac >> 16; | ||
449 | |||
450 | d_sfrac &= 0xFFFF; | ||
451 | d_tfrac += d_tfracextrastep; | ||
452 | if (d_tfrac & 0x10000) | ||
453 | { | ||
454 | d_ptex += r_affinetridesc.skinwidth; | ||
455 | d_tfrac &= 0xFFFF; | ||
456 | } | ||
457 | d_light += d_lightextrastep; | ||
458 | d_zi += d_ziextrastep; | ||
459 | errorterm -= erroradjustdown; | ||
460 | } | ||
461 | else | ||
462 | { | ||
463 | d_pdest += d_pdestbasestep; | ||
464 | d_pz += d_pzbasestep; | ||
465 | d_aspancount += ubasestep; | ||
466 | d_ptex += d_ptexbasestep; | ||
467 | d_sfrac += d_sfracbasestep; | ||
468 | d_ptex += d_sfrac >> 16; | ||
469 | d_sfrac &= 0xFFFF; | ||
470 | d_tfrac += d_tfracbasestep; | ||
471 | if (d_tfrac & 0x10000) | ||
472 | { | ||
473 | d_ptex += r_affinetridesc.skinwidth; | ||
474 | d_tfrac &= 0xFFFF; | ||
475 | } | ||
476 | d_light += d_lightbasestep; | ||
477 | d_zi += d_zibasestep; | ||
478 | } | ||
479 | } while (--height); | ||
480 | } | ||
481 | |||
482 | #endif // !id386 | ||
483 | |||
484 | |||
485 | /* | ||
486 | =================== | ||
487 | D_PolysetSetUpForLineScan | ||
488 | ==================== | ||
489 | */ | ||
490 | void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, | ||
491 | fixed8_t endvertu, fixed8_t endvertv) | ||
492 | { | ||
493 | double dm, dn; | ||
494 | int tm, tn; | ||
495 | adivtab_t *ptemp; | ||
496 | |||
497 | // TODO: implement x86 version | ||
498 | |||
499 | errorterm = -1; | ||
500 | |||
501 | tm = endvertu - startvertu; | ||
502 | tn = endvertv - startvertv; | ||
503 | |||
504 | if (((tm <= 16) && (tm >= -15)) && | ||
505 | ((tn <= 16) && (tn >= -15))) | ||
506 | { | ||
507 | ptemp = &adivtab[((tm+15) << 5) + (tn+15)]; | ||
508 | ubasestep = ptemp->quotient; | ||
509 | erroradjustup = ptemp->remainder; | ||
510 | erroradjustdown = tn; | ||
511 | } | ||
512 | else | ||
513 | { | ||
514 | dm = (double)tm; | ||
515 | dn = (double)tn; | ||
516 | |||
517 | FloorDivMod (dm, dn, &ubasestep, &erroradjustup); | ||
518 | |||
519 | erroradjustdown = dn; | ||
520 | } | ||
521 | } | ||
522 | |||
523 | |||
524 | #if !id386 | ||
525 | |||
526 | /* | ||
527 | ================ | ||
528 | D_PolysetCalcGradients | ||
529 | ================ | ||
530 | */ | ||
531 | void D_PolysetCalcGradients (int skinwidth) | ||
532 | { | ||
533 | float xstepdenominv, ystepdenominv, t0, t1; | ||
534 | float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20; | ||
535 | |||
536 | p00_minus_p20 = r_p0[0] - r_p2[0]; | ||
537 | p01_minus_p21 = r_p0[1] - r_p2[1]; | ||
538 | p10_minus_p20 = r_p1[0] - r_p2[0]; | ||
539 | p11_minus_p21 = r_p1[1] - r_p2[1]; | ||
540 | |||
541 | xstepdenominv = 1.0 / (float)d_xdenom; | ||
542 | |||
543 | ystepdenominv = -xstepdenominv; | ||
544 | |||
545 | // ceil () for light so positive steps are exaggerated, negative steps | ||
546 | // diminished, pushing us away from underflow toward overflow. Underflow is | ||
547 | // very visible, overflow is very unlikely, because of ambient lighting | ||
548 | t0 = r_p0[4] - r_p2[4]; | ||
549 | t1 = r_p1[4] - r_p2[4]; | ||
550 | r_lstepx = (int) | ||
551 | ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); | ||
552 | r_lstepy = (int) | ||
553 | ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); | ||
554 | |||
555 | t0 = r_p0[2] - r_p2[2]; | ||
556 | t1 = r_p1[2] - r_p2[2]; | ||
557 | r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * | ||
558 | xstepdenominv); | ||
559 | r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) * | ||
560 | ystepdenominv); | ||
561 | |||
562 | t0 = r_p0[3] - r_p2[3]; | ||
563 | t1 = r_p1[3] - r_p2[3]; | ||
564 | r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * | ||
565 | xstepdenominv); | ||
566 | r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * | ||
567 | ystepdenominv); | ||
568 | |||
569 | t0 = r_p0[5] - r_p2[5]; | ||
570 | t1 = r_p1[5] - r_p2[5]; | ||
571 | r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * | ||
572 | xstepdenominv); | ||
573 | r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * | ||
574 | ystepdenominv); | ||
575 | |||
576 | #if id386 | ||
577 | a_sstepxfrac = r_sstepx << 16; | ||
578 | a_tstepxfrac = r_tstepx << 16; | ||
579 | #else | ||
580 | a_sstepxfrac = r_sstepx & 0xFFFF; | ||
581 | a_tstepxfrac = r_tstepx & 0xFFFF; | ||
582 | #endif | ||
583 | |||
584 | a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16); | ||
585 | } | ||
586 | |||
587 | #endif // !id386 | ||
588 | |||
589 | |||
590 | #if 0 | ||
591 | byte gelmap[256]; | ||
592 | void InitGel (byte *palette) | ||
593 | { | ||
594 | int i; | ||
595 | int r; | ||
596 | |||
597 | for (i=0 ; i<256 ; i++) | ||
598 | { | ||
599 | // r = (palette[i*3]>>4); | ||
600 | r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3); | ||
601 | gelmap[i] = /* 64 */ 0 + r; | ||
602 | } | ||
603 | } | ||
604 | #endif | ||
605 | |||
606 | |||
607 | #if !id386 | ||
608 | |||
609 | /* | ||
610 | ================ | ||
611 | D_PolysetDrawSpans8 | ||
612 | ================ | ||
613 | */ | ||
614 | void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage) | ||
615 | { | ||
616 | int lcount; | ||
617 | byte *lpdest; | ||
618 | byte *lptex; | ||
619 | int lsfrac, ltfrac; | ||
620 | int llight; | ||
621 | int lzi; | ||
622 | short *lpz; | ||
623 | |||
624 | do | ||
625 | { | ||
626 | lcount = d_aspancount - pspanpackage->count; | ||
627 | |||
628 | errorterm += erroradjustup; | ||
629 | if (errorterm >= 0) | ||
630 | { | ||
631 | d_aspancount += d_countextrastep; | ||
632 | errorterm -= erroradjustdown; | ||
633 | } | ||
634 | else | ||
635 | { | ||
636 | d_aspancount += ubasestep; | ||
637 | } | ||
638 | |||
639 | if (lcount) | ||
640 | { | ||
641 | lpdest = pspanpackage->pdest; | ||
642 | lptex = pspanpackage->ptex; | ||
643 | lpz = pspanpackage->pz; | ||
644 | lsfrac = pspanpackage->sfrac; | ||
645 | ltfrac = pspanpackage->tfrac; | ||
646 | llight = pspanpackage->light; | ||
647 | lzi = pspanpackage->zi; | ||
648 | |||
649 | do | ||
650 | { | ||
651 | if ((lzi >> 16) >= *lpz) | ||
652 | { | ||
653 | *lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)]; | ||
654 | // gel mapping *lpdest = gelmap[*lpdest]; | ||
655 | *lpz = lzi >> 16; | ||
656 | } | ||
657 | lpdest++; | ||
658 | lzi += r_zistepx; | ||
659 | lpz++; | ||
660 | llight += r_lstepx; | ||
661 | lptex += a_ststepxwhole; | ||
662 | lsfrac += a_sstepxfrac; | ||
663 | lptex += lsfrac >> 16; | ||
664 | lsfrac &= 0xFFFF; | ||
665 | ltfrac += a_tstepxfrac; | ||
666 | if (ltfrac & 0x10000) | ||
667 | { | ||
668 | lptex += r_affinetridesc.skinwidth; | ||
669 | ltfrac &= 0xFFFF; | ||
670 | } | ||
671 | } while (--lcount); | ||
672 | } | ||
673 | |||
674 | pspanpackage++; | ||
675 | } while (pspanpackage->count != -999999); | ||
676 | } | ||
677 | #endif // !id386 | ||
678 | |||
679 | |||
680 | /* | ||
681 | ================ | ||
682 | D_PolysetFillSpans8 | ||
683 | ================ | ||
684 | */ | ||
685 | void D_PolysetFillSpans8 (spanpackage_t *pspanpackage) | ||
686 | { | ||
687 | int color; | ||
688 | |||
689 | // FIXME: do z buffering | ||
690 | |||
691 | color = d_aflatcolor++; | ||
692 | |||
693 | while (1) | ||
694 | { | ||
695 | int lcount; | ||
696 | byte *lpdest; | ||
697 | |||
698 | lcount = pspanpackage->count; | ||
699 | |||
700 | if (lcount == -1) | ||
701 | return; | ||
702 | |||
703 | if (lcount) | ||
704 | { | ||
705 | lpdest = pspanpackage->pdest; | ||
706 | |||
707 | do | ||
708 | { | ||
709 | *lpdest++ = color; | ||
710 | } while (--lcount); | ||
711 | } | ||
712 | |||
713 | pspanpackage++; | ||
714 | } | ||
715 | } | ||
716 | |||
717 | /* | ||
718 | ================ | ||
719 | D_RasterizeAliasPolySmooth | ||
720 | ================ | ||
721 | */ | ||
722 | void D_RasterizeAliasPolySmooth (void) | ||
723 | { | ||
724 | int initialleftheight, initialrightheight; | ||
725 | int *plefttop, *prighttop, *pleftbottom, *prightbottom; | ||
726 | int working_lstepx, originalcount; | ||
727 | |||
728 | plefttop = pedgetable->pleftedgevert0; | ||
729 | prighttop = pedgetable->prightedgevert0; | ||
730 | |||
731 | pleftbottom = pedgetable->pleftedgevert1; | ||
732 | prightbottom = pedgetable->prightedgevert1; | ||
733 | |||
734 | initialleftheight = pleftbottom[1] - plefttop[1]; | ||
735 | initialrightheight = prightbottom[1] - prighttop[1]; | ||
736 | |||
737 | // | ||
738 | // set the s, t, and light gradients, which are consistent across the triangle | ||
739 | // because being a triangle, things are affine | ||
740 | // | ||
741 | D_PolysetCalcGradients (r_affinetridesc.skinwidth); | ||
742 | |||
743 | // | ||
744 | // rasterize the polygon | ||
745 | // | ||
746 | |||
747 | // | ||
748 | // scan out the top (and possibly only) part of the left edge | ||
749 | // | ||
750 | d_pedgespanpackage = a_spans; | ||
751 | |||
752 | ystart = plefttop[1]; | ||
753 | d_aspancount = plefttop[0] - prighttop[0]; | ||
754 | |||
755 | d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + | ||
756 | (plefttop[3] >> 16) * r_affinetridesc.skinwidth; | ||
757 | #if id386 | ||
758 | d_sfrac = (plefttop[2] & 0xFFFF) << 16; | ||
759 | d_tfrac = (plefttop[3] & 0xFFFF) << 16; | ||
760 | #else | ||
761 | d_sfrac = plefttop[2] & 0xFFFF; | ||
762 | d_tfrac = plefttop[3] & 0xFFFF; | ||
763 | #endif | ||
764 | d_light = plefttop[4]; | ||
765 | d_zi = plefttop[5]; | ||
766 | |||
767 | d_pdest = (byte *)d_viewbuffer + | ||
768 | ystart * screenwidth + plefttop[0]; | ||
769 | d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; | ||
770 | |||
771 | if (initialleftheight == 1) | ||
772 | { | ||
773 | d_pedgespanpackage->pdest = d_pdest; | ||
774 | d_pedgespanpackage->pz = d_pz; | ||
775 | d_pedgespanpackage->count = d_aspancount; | ||
776 | d_pedgespanpackage->ptex = d_ptex; | ||
777 | |||
778 | d_pedgespanpackage->sfrac = d_sfrac; | ||
779 | d_pedgespanpackage->tfrac = d_tfrac; | ||
780 | |||
781 | // FIXME: need to clamp l, s, t, at both ends? | ||
782 | d_pedgespanpackage->light = d_light; | ||
783 | d_pedgespanpackage->zi = d_zi; | ||
784 | |||
785 | d_pedgespanpackage++; | ||
786 | } | ||
787 | else | ||
788 | { | ||
789 | D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], | ||
790 | pleftbottom[0], pleftbottom[1]); | ||
791 | |||
792 | #if id386 | ||
793 | d_pzbasestep = (d_zwidth + ubasestep) << 1; | ||
794 | d_pzextrastep = d_pzbasestep + 2; | ||
795 | #else | ||
796 | d_pzbasestep = d_zwidth + ubasestep; | ||
797 | d_pzextrastep = d_pzbasestep + 1; | ||
798 | #endif | ||
799 | |||
800 | d_pdestbasestep = screenwidth + ubasestep; | ||
801 | d_pdestextrastep = d_pdestbasestep + 1; | ||
802 | |||
803 | // TODO: can reuse partial expressions here | ||
804 | |||
805 | // for negative steps in x along left edge, bias toward overflow rather than | ||
806 | // underflow (sort of turning the floor () we did in the gradient calcs into | ||
807 | // ceil (), but plus a little bit) | ||
808 | if (ubasestep < 0) | ||
809 | working_lstepx = r_lstepx - 1; | ||
810 | else | ||
811 | working_lstepx = r_lstepx; | ||
812 | |||
813 | d_countextrastep = ubasestep + 1; | ||
814 | d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + | ||
815 | ((r_tstepy + r_tstepx * ubasestep) >> 16) * | ||
816 | r_affinetridesc.skinwidth; | ||
817 | #if id386 | ||
818 | d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; | ||
819 | d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; | ||
820 | #else | ||
821 | d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; | ||
822 | d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; | ||
823 | #endif | ||
824 | d_lightbasestep = r_lstepy + working_lstepx * ubasestep; | ||
825 | d_zibasestep = r_zistepy + r_zistepx * ubasestep; | ||
826 | |||
827 | d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + | ||
828 | ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * | ||
829 | r_affinetridesc.skinwidth; | ||
830 | #if id386 | ||
831 | d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16; | ||
832 | d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16; | ||
833 | #else | ||
834 | d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF; | ||
835 | d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF; | ||
836 | #endif | ||
837 | d_lightextrastep = d_lightbasestep + working_lstepx; | ||
838 | d_ziextrastep = d_zibasestep + r_zistepx; | ||
839 | |||
840 | D_PolysetScanLeftEdge (initialleftheight); | ||
841 | } | ||
842 | |||
843 | // | ||
844 | // scan out the bottom part of the left edge, if it exists | ||
845 | // | ||
846 | if (pedgetable->numleftedges == 2) | ||
847 | { | ||
848 | int height; | ||
849 | |||
850 | plefttop = pleftbottom; | ||
851 | pleftbottom = pedgetable->pleftedgevert2; | ||
852 | |||
853 | height = pleftbottom[1] - plefttop[1]; | ||
854 | |||
855 | // TODO: make this a function; modularize this function in general | ||
856 | |||
857 | ystart = plefttop[1]; | ||
858 | d_aspancount = plefttop[0] - prighttop[0]; | ||
859 | d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + | ||
860 | (plefttop[3] >> 16) * r_affinetridesc.skinwidth; | ||
861 | d_sfrac = 0; | ||
862 | d_tfrac = 0; | ||
863 | d_light = plefttop[4]; | ||
864 | d_zi = plefttop[5]; | ||
865 | |||
866 | d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0]; | ||
867 | d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; | ||
868 | |||
869 | if (height == 1) | ||
870 | { | ||
871 | d_pedgespanpackage->pdest = d_pdest; | ||
872 | d_pedgespanpackage->pz = d_pz; | ||
873 | d_pedgespanpackage->count = d_aspancount; | ||
874 | d_pedgespanpackage->ptex = d_ptex; | ||
875 | |||
876 | d_pedgespanpackage->sfrac = d_sfrac; | ||
877 | d_pedgespanpackage->tfrac = d_tfrac; | ||
878 | |||
879 | // FIXME: need to clamp l, s, t, at both ends? | ||
880 | d_pedgespanpackage->light = d_light; | ||
881 | d_pedgespanpackage->zi = d_zi; | ||
882 | |||
883 | d_pedgespanpackage++; | ||
884 | } | ||
885 | else | ||
886 | { | ||
887 | D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], | ||
888 | pleftbottom[0], pleftbottom[1]); | ||
889 | |||
890 | d_pdestbasestep = screenwidth + ubasestep; | ||
891 | d_pdestextrastep = d_pdestbasestep + 1; | ||
892 | |||
893 | #if id386 | ||
894 | d_pzbasestep = (d_zwidth + ubasestep) << 1; | ||
895 | d_pzextrastep = d_pzbasestep + 2; | ||
896 | #else | ||
897 | d_pzbasestep = d_zwidth + ubasestep; | ||
898 | d_pzextrastep = d_pzbasestep + 1; | ||
899 | #endif | ||
900 | |||
901 | if (ubasestep < 0) | ||
902 | working_lstepx = r_lstepx - 1; | ||
903 | else | ||
904 | working_lstepx = r_lstepx; | ||
905 | |||
906 | d_countextrastep = ubasestep + 1; | ||
907 | d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + | ||
908 | ((r_tstepy + r_tstepx * ubasestep) >> 16) * | ||
909 | r_affinetridesc.skinwidth; | ||
910 | #if id386 | ||
911 | d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; | ||
912 | d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; | ||
913 | #else | ||
914 | d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; | ||
915 | d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; | ||
916 | #endif | ||
917 | d_lightbasestep = r_lstepy + working_lstepx * ubasestep; | ||
918 | d_zibasestep = r_zistepy + r_zistepx * ubasestep; | ||
919 | |||
920 | d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + | ||
921 | ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * | ||
922 | r_affinetridesc.skinwidth; | ||
923 | #if id386 | ||
924 | d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16; | ||
925 | d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16; | ||
926 | #else | ||
927 | d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF; | ||
928 | d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF; | ||
929 | #endif | ||
930 | d_lightextrastep = d_lightbasestep + working_lstepx; | ||
931 | d_ziextrastep = d_zibasestep + r_zistepx; | ||
932 | |||
933 | D_PolysetScanLeftEdge (height); | ||
934 | } | ||
935 | } | ||
936 | |||
937 | // scan out the top (and possibly only) part of the right edge, updating the | ||
938 | // count field | ||
939 | d_pedgespanpackage = a_spans; | ||
940 | |||
941 | D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], | ||
942 | prightbottom[0], prightbottom[1]); | ||
943 | d_aspancount = 0; | ||
944 | d_countextrastep = ubasestep + 1; | ||
945 | originalcount = a_spans[initialrightheight].count; | ||
946 | a_spans[initialrightheight].count = -999999; // mark end of the spanpackages | ||
947 | D_PolysetDrawSpans8 (a_spans); | ||
948 | |||
949 | // scan out the bottom part of the right edge, if it exists | ||
950 | if (pedgetable->numrightedges == 2) | ||
951 | { | ||
952 | int height; | ||
953 | spanpackage_t *pstart; | ||
954 | |||
955 | pstart = a_spans + initialrightheight; | ||
956 | pstart->count = originalcount; | ||
957 | |||
958 | d_aspancount = prightbottom[0] - prighttop[0]; | ||
959 | |||
960 | prighttop = prightbottom; | ||
961 | prightbottom = pedgetable->prightedgevert2; | ||
962 | |||
963 | height = prightbottom[1] - prighttop[1]; | ||
964 | |||
965 | D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], | ||
966 | prightbottom[0], prightbottom[1]); | ||
967 | |||
968 | d_countextrastep = ubasestep + 1; | ||
969 | a_spans[initialrightheight + height].count = -999999; | ||
970 | // mark end of the spanpackages | ||
971 | D_PolysetDrawSpans8 (pstart); | ||
972 | } | ||
973 | } | ||
974 | |||
975 | |||
976 | /* | ||
977 | ================ | ||
978 | D_PolysetSetEdgeTable | ||
979 | ================ | ||
980 | */ | ||
981 | void D_PolysetSetEdgeTable (void) | ||
982 | { | ||
983 | int edgetableindex; | ||
984 | |||
985 | edgetableindex = 0; // assume the vertices are already in | ||
986 | // top to bottom order | ||
987 | |||
988 | // | ||
989 | // determine which edges are right & left, and the order in which | ||
990 | // to rasterize them | ||
991 | // | ||
992 | if (r_p0[1] >= r_p1[1]) | ||
993 | { | ||
994 | if (r_p0[1] == r_p1[1]) | ||
995 | { | ||
996 | if (r_p0[1] < r_p2[1]) | ||
997 | pedgetable = &edgetables[2]; | ||
998 | else | ||
999 | pedgetable = &edgetables[5]; | ||
1000 | |||
1001 | return; | ||
1002 | } | ||
1003 | else | ||
1004 | { | ||
1005 | edgetableindex = 1; | ||
1006 | } | ||
1007 | } | ||
1008 | |||
1009 | if (r_p0[1] == r_p2[1]) | ||
1010 | { | ||
1011 | if (edgetableindex) | ||
1012 | pedgetable = &edgetables[8]; | ||
1013 | else | ||
1014 | pedgetable = &edgetables[9]; | ||
1015 | |||
1016 | return; | ||
1017 | } | ||
1018 | else if (r_p1[1] == r_p2[1]) | ||
1019 | { | ||
1020 | if (edgetableindex) | ||
1021 | pedgetable = &edgetables[10]; | ||
1022 | else | ||
1023 | pedgetable = &edgetables[11]; | ||
1024 | |||
1025 | return; | ||
1026 | } | ||
1027 | |||
1028 | if (r_p0[1] > r_p2[1]) | ||
1029 | edgetableindex += 2; | ||
1030 | |||
1031 | if (r_p1[1] > r_p2[1]) | ||
1032 | edgetableindex += 4; | ||
1033 | |||
1034 | pedgetable = &edgetables[edgetableindex]; | ||
1035 | } | ||
1036 | |||
1037 | |||
1038 | #if 0 | ||
1039 | |||
1040 | void D_PolysetRecursiveDrawLine (int *lp1, int *lp2) | ||
1041 | { | ||
1042 | int d; | ||
1043 | int new[6]; | ||
1044 | int ofs; | ||
1045 | |||
1046 | d = lp2[0] - lp1[0]; | ||
1047 | if (d < -1 || d > 1) | ||
1048 | goto split; | ||
1049 | d = lp2[1] - lp1[1]; | ||
1050 | if (d < -1 || d > 1) | ||
1051 | goto split; | ||
1052 | |||
1053 | return; // line is completed | ||
1054 | |||
1055 | split: | ||
1056 | // split this edge | ||
1057 | new[0] = (lp1[0] + lp2[0]) >> 1; | ||
1058 | new[1] = (lp1[1] + lp2[1]) >> 1; | ||
1059 | new[5] = (lp1[5] + lp2[5]) >> 1; | ||
1060 | new[2] = (lp1[2] + lp2[2]) >> 1; | ||
1061 | new[3] = (lp1[3] + lp2[3]) >> 1; | ||
1062 | new[4] = (lp1[4] + lp2[4]) >> 1; | ||
1063 | |||
1064 | // draw the point | ||
1065 | ofs = d_scantable[new[1]] + new[0]; | ||
1066 | if (new[5] > d_pzbuffer[ofs]) | ||
1067 | { | ||
1068 | int pix; | ||
1069 | |||
1070 | d_pzbuffer[ofs] = new[5]; | ||
1071 | pix = skintable[new[3]>>16][new[2]>>16]; | ||
1072 | // pix = ((byte *)acolormap)[pix + (new[4] & 0xFF00)]; | ||
1073 | d_viewbuffer[ofs] = pix; | ||
1074 | } | ||
1075 | |||
1076 | // recursively continue | ||
1077 | D_PolysetRecursiveDrawLine (lp1, new); | ||
1078 | D_PolysetRecursiveDrawLine (new, lp2); | ||
1079 | } | ||
1080 | |||
1081 | void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3) | ||
1082 | { | ||
1083 | int d; | ||
1084 | int new[4]; | ||
1085 | |||
1086 | d = lp2[0] - lp1[0]; | ||
1087 | if (d < -1 || d > 1) | ||
1088 | goto split; | ||
1089 | d = lp2[1] - lp1[1]; | ||
1090 | if (d < -1 || d > 1) | ||
1091 | goto split; | ||
1092 | return; | ||
1093 | |||
1094 | split: | ||
1095 | // split this edge | ||
1096 | new[0] = (lp1[0] + lp2[0]) >> 1; | ||
1097 | new[1] = (lp1[1] + lp2[1]) >> 1; | ||
1098 | new[5] = (lp1[5] + lp2[5]) >> 1; | ||
1099 | new[2] = (lp1[2] + lp2[2]) >> 1; | ||
1100 | new[3] = (lp1[3] + lp2[3]) >> 1; | ||
1101 | new[4] = (lp1[4] + lp2[4]) >> 1; | ||
1102 | |||
1103 | D_PolysetRecursiveDrawLine (new, lp3); | ||
1104 | |||
1105 | // recursively continue | ||
1106 | D_PolysetRecursiveTriangle (lp1, new, lp3); | ||
1107 | D_PolysetRecursiveTriangle (new, lp2, lp3); | ||
1108 | } | ||
1109 | |||
1110 | #endif | ||
1111 | |||