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