r_alias.c (34793B)
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 // r_alias.c: routines for setting up to draw alias models 21 22 /* 23 ** use a real variable to control lerping 24 */ 25 #include "r_local.h" 26 27 #define LIGHT_MIN 5 // lowest light value we'll allow, to avoid the 28 // need for inner-loop light clamping 29 30 //PGM 31 extern byte iractive; 32 //PGM 33 34 int r_amodels_drawn; 35 36 affinetridesc_t r_affinetridesc; 37 38 vec3_t r_plightvec; 39 vec3_t r_lerped[1024]; 40 vec3_t r_lerp_frontv, r_lerp_backv, r_lerp_move; 41 42 int r_ambientlight; 43 int r_aliasblendcolor; 44 float r_shadelight; 45 46 47 daliasframe_t *r_thisframe, *r_lastframe; 48 dmdl_t *s_pmdl; 49 50 float aliastransform[3][4]; 51 float aliasworldtransform[3][4]; 52 float aliasoldworldtransform[3][4]; 53 54 static float s_ziscale; 55 static vec3_t s_alias_forward, s_alias_right, s_alias_up; 56 57 58 #define NUMVERTEXNORMALS 162 59 60 float r_avertexnormals[NUMVERTEXNORMALS][3] = { 61 #include "anorms.h" 62 }; 63 64 65 void R_AliasSetUpLerpData( dmdl_t *pmdl, float backlerp ); 66 void R_AliasSetUpTransform (void); 67 void R_AliasTransformVector (vec3_t in, vec3_t out, float m[3][4] ); 68 void R_AliasProjectAndClipTestFinalVert (finalvert_t *fv); 69 70 void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv ); 71 72 void R_AliasLerpFrames( dmdl_t *paliashdr, float backlerp ); 73 74 /* 75 ================ 76 R_AliasCheckBBox 77 ================ 78 */ 79 typedef struct { 80 int index0; 81 int index1; 82 } aedge_t; 83 84 static aedge_t aedges[12] = { 85 {0, 1}, {1, 2}, {2, 3}, {3, 0}, 86 {4, 5}, {5, 6}, {6, 7}, {7, 4}, 87 {0, 5}, {1, 4}, {2, 7}, {3, 6} 88 }; 89 90 #define BBOX_TRIVIAL_ACCEPT 0 91 #define BBOX_MUST_CLIP_XY 1 92 #define BBOX_MUST_CLIP_Z 2 93 #define BBOX_TRIVIAL_REJECT 8 94 95 /* 96 ** R_AliasCheckFrameBBox 97 ** 98 ** Checks a specific alias frame bounding box 99 */ 100 unsigned long R_AliasCheckFrameBBox( daliasframe_t *frame, float worldxf[3][4] ) 101 { 102 unsigned long aggregate_and_clipcode = ~0U, 103 aggregate_or_clipcode = 0; 104 int i; 105 vec3_t mins, maxs; 106 vec3_t transformed_min, transformed_max; 107 qboolean zclipped = false, zfullyclipped = true; 108 float minz = 9999.0F; 109 110 /* 111 ** get the exact frame bounding box 112 */ 113 for (i=0 ; i<3 ; i++) 114 { 115 mins[i] = frame->translate[i]; 116 maxs[i] = mins[i] + frame->scale[i]*255; 117 } 118 119 /* 120 ** transform the min and max values into view space 121 */ 122 R_AliasTransformVector( mins, transformed_min, aliastransform ); 123 R_AliasTransformVector( maxs, transformed_max, aliastransform ); 124 125 if ( transformed_min[2] >= ALIAS_Z_CLIP_PLANE ) 126 zfullyclipped = false; 127 if ( transformed_max[2] >= ALIAS_Z_CLIP_PLANE ) 128 zfullyclipped = false; 129 130 if ( zfullyclipped ) 131 { 132 return BBOX_TRIVIAL_REJECT; 133 } 134 if ( zclipped ) 135 { 136 return ( BBOX_MUST_CLIP_XY | BBOX_MUST_CLIP_Z ); 137 } 138 139 /* 140 ** build a transformed bounding box from the given min and max 141 */ 142 for ( i = 0; i < 8; i++ ) 143 { 144 int j; 145 vec3_t tmp, transformed; 146 unsigned long clipcode = 0; 147 148 if ( i & 1 ) 149 tmp[0] = mins[0]; 150 else 151 tmp[0] = maxs[0]; 152 153 if ( i & 2 ) 154 tmp[1] = mins[1]; 155 else 156 tmp[1] = maxs[1]; 157 158 if ( i & 4 ) 159 tmp[2] = mins[2]; 160 else 161 tmp[2] = maxs[2]; 162 163 R_AliasTransformVector( tmp, transformed, worldxf ); 164 165 for ( j = 0; j < 4; j++ ) 166 { 167 float dp = DotProduct( transformed, view_clipplanes[j].normal ); 168 169 if ( ( dp - view_clipplanes[j].dist ) < 0.0F ) 170 clipcode |= 1 << j; 171 } 172 173 aggregate_and_clipcode &= clipcode; 174 aggregate_or_clipcode |= clipcode; 175 } 176 177 if ( aggregate_and_clipcode ) 178 { 179 return BBOX_TRIVIAL_REJECT; 180 } 181 if ( !aggregate_or_clipcode ) 182 { 183 return BBOX_TRIVIAL_ACCEPT; 184 } 185 186 return BBOX_MUST_CLIP_XY; 187 } 188 189 qboolean R_AliasCheckBBox (void) 190 { 191 unsigned long ccodes[2] = { 0, 0 }; 192 193 ccodes[0] = R_AliasCheckFrameBBox( r_thisframe, aliasworldtransform ); 194 195 /* 196 ** non-lerping model 197 */ 198 if ( currententity->backlerp == 0 ) 199 { 200 if ( ccodes[0] == BBOX_TRIVIAL_ACCEPT ) 201 return BBOX_TRIVIAL_ACCEPT; 202 else if ( ccodes[0] & BBOX_TRIVIAL_REJECT ) 203 return BBOX_TRIVIAL_REJECT; 204 else 205 return ( ccodes[0] & ~BBOX_TRIVIAL_REJECT ); 206 } 207 208 ccodes[1] = R_AliasCheckFrameBBox( r_lastframe, aliasoldworldtransform ); 209 210 if ( ( ccodes[0] | ccodes[1] ) == BBOX_TRIVIAL_ACCEPT ) 211 return BBOX_TRIVIAL_ACCEPT; 212 else if ( ( ccodes[0] & ccodes[1] ) & BBOX_TRIVIAL_REJECT ) 213 return BBOX_TRIVIAL_REJECT; 214 else 215 return ( ccodes[0] | ccodes[1] ) & ~BBOX_TRIVIAL_REJECT; 216 } 217 218 219 /* 220 ================ 221 R_AliasTransformVector 222 ================ 223 */ 224 void R_AliasTransformVector(vec3_t in, vec3_t out, float xf[3][4] ) 225 { 226 out[0] = DotProduct(in, xf[0]) + xf[0][3]; 227 out[1] = DotProduct(in, xf[1]) + xf[1][3]; 228 out[2] = DotProduct(in, xf[2]) + xf[2][3]; 229 } 230 231 232 /* 233 ================ 234 R_AliasPreparePoints 235 236 General clipped case 237 ================ 238 */ 239 typedef struct 240 { 241 int num_points; 242 dtrivertx_t *last_verts; // verts from the last frame 243 dtrivertx_t *this_verts; // verts from this frame 244 finalvert_t *dest_verts; // destination for transformed verts 245 } aliasbatchedtransformdata_t; 246 247 aliasbatchedtransformdata_t aliasbatchedtransformdata; 248 249 void R_AliasPreparePoints (void) 250 { 251 int i; 252 dstvert_t *pstverts; 253 dtriangle_t *ptri; 254 finalvert_t *pfv[3]; 255 finalvert_t finalverts[MAXALIASVERTS + 256 ((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 3]; 257 finalvert_t *pfinalverts; 258 259 //PGM 260 iractive = (r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE); 261 // iractive = 0; 262 // if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE) 263 // iractive = 1; 264 //PGM 265 266 // put work vertexes on stack, cache aligned 267 pfinalverts = (finalvert_t *) 268 (((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); 269 270 aliasbatchedtransformdata.num_points = s_pmdl->num_xyz; 271 aliasbatchedtransformdata.last_verts = r_lastframe->verts; 272 aliasbatchedtransformdata.this_verts = r_thisframe->verts; 273 aliasbatchedtransformdata.dest_verts = pfinalverts; 274 275 R_AliasTransformFinalVerts( aliasbatchedtransformdata.num_points, 276 aliasbatchedtransformdata.dest_verts, 277 aliasbatchedtransformdata.last_verts, 278 aliasbatchedtransformdata.this_verts ); 279 280 // clip and draw all triangles 281 // 282 pstverts = (dstvert_t *)((byte *)s_pmdl + s_pmdl->ofs_st); 283 ptri = (dtriangle_t *)((byte *)s_pmdl + s_pmdl->ofs_tris); 284 285 if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) ) 286 { 287 for (i=0 ; i<s_pmdl->num_tris ; i++, ptri++) 288 { 289 pfv[0] = &pfinalverts[ptri->index_xyz[0]]; 290 pfv[1] = &pfinalverts[ptri->index_xyz[1]]; 291 pfv[2] = &pfinalverts[ptri->index_xyz[2]]; 292 293 if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags ) 294 continue; // completely clipped 295 296 // insert s/t coordinates 297 pfv[0]->s = pstverts[ptri->index_st[0]].s << 16; 298 pfv[0]->t = pstverts[ptri->index_st[0]].t << 16; 299 300 pfv[1]->s = pstverts[ptri->index_st[1]].s << 16; 301 pfv[1]->t = pstverts[ptri->index_st[1]].t << 16; 302 303 pfv[2]->s = pstverts[ptri->index_st[2]].s << 16; 304 pfv[2]->t = pstverts[ptri->index_st[2]].t << 16; 305 306 if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) ) 307 { // totally unclipped 308 aliastriangleparms.a = pfv[2]; 309 aliastriangleparms.b = pfv[1]; 310 aliastriangleparms.c = pfv[0]; 311 312 R_DrawTriangle(); 313 } 314 else 315 { 316 R_AliasClipTriangle (pfv[2], pfv[1], pfv[0]); 317 } 318 } 319 } 320 else 321 { 322 for (i=0 ; i<s_pmdl->num_tris ; i++, ptri++) 323 { 324 pfv[0] = &pfinalverts[ptri->index_xyz[0]]; 325 pfv[1] = &pfinalverts[ptri->index_xyz[1]]; 326 pfv[2] = &pfinalverts[ptri->index_xyz[2]]; 327 328 if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags ) 329 continue; // completely clipped 330 331 // insert s/t coordinates 332 pfv[0]->s = pstverts[ptri->index_st[0]].s << 16; 333 pfv[0]->t = pstverts[ptri->index_st[0]].t << 16; 334 335 pfv[1]->s = pstverts[ptri->index_st[1]].s << 16; 336 pfv[1]->t = pstverts[ptri->index_st[1]].t << 16; 337 338 pfv[2]->s = pstverts[ptri->index_st[2]].s << 16; 339 pfv[2]->t = pstverts[ptri->index_st[2]].t << 16; 340 341 if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) ) 342 { // totally unclipped 343 aliastriangleparms.a = pfv[0]; 344 aliastriangleparms.b = pfv[1]; 345 aliastriangleparms.c = pfv[2]; 346 347 R_DrawTriangle(); 348 } 349 else 350 { // partially clipped 351 R_AliasClipTriangle (pfv[0], pfv[1], pfv[2]); 352 } 353 } 354 } 355 } 356 357 358 /* 359 ================ 360 R_AliasSetUpTransform 361 ================ 362 */ 363 void R_AliasSetUpTransform (void) 364 { 365 int i; 366 static float viewmatrix[3][4]; 367 vec3_t angles; 368 369 // TODO: should really be stored with the entity instead of being reconstructed 370 // TODO: should use a look-up table 371 // TODO: could cache lazily, stored in the entity 372 // 373 angles[ROLL] = currententity->angles[ROLL]; 374 angles[PITCH] = currententity->angles[PITCH]; 375 angles[YAW] = currententity->angles[YAW]; 376 AngleVectors( angles, s_alias_forward, s_alias_right, s_alias_up ); 377 378 // TODO: can do this with simple matrix rearrangement 379 380 memset( aliasworldtransform, 0, sizeof( aliasworldtransform ) ); 381 memset( aliasoldworldtransform, 0, sizeof( aliasworldtransform ) ); 382 383 for (i=0 ; i<3 ; i++) 384 { 385 aliasoldworldtransform[i][0] = aliasworldtransform[i][0] = s_alias_forward[i]; 386 aliasoldworldtransform[i][0] = aliasworldtransform[i][1] = -s_alias_right[i]; 387 aliasoldworldtransform[i][0] = aliasworldtransform[i][2] = s_alias_up[i]; 388 } 389 390 aliasworldtransform[0][3] = currententity->origin[0]-r_origin[0]; 391 aliasworldtransform[1][3] = currententity->origin[1]-r_origin[1]; 392 aliasworldtransform[2][3] = currententity->origin[2]-r_origin[2]; 393 394 aliasoldworldtransform[0][3] = currententity->oldorigin[0]-r_origin[0]; 395 aliasoldworldtransform[1][3] = currententity->oldorigin[1]-r_origin[1]; 396 aliasoldworldtransform[2][3] = currententity->oldorigin[2]-r_origin[2]; 397 398 // FIXME: can do more efficiently than full concatenation 399 // memcpy( rotationmatrix, t2matrix, sizeof( rotationmatrix ) ); 400 401 // R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix); 402 403 // TODO: should be global, set when vright, etc., set 404 VectorCopy (vright, viewmatrix[0]); 405 VectorCopy (vup, viewmatrix[1]); 406 VectorInverse (viewmatrix[1]); 407 VectorCopy (vpn, viewmatrix[2]); 408 409 viewmatrix[0][3] = 0; 410 viewmatrix[1][3] = 0; 411 viewmatrix[2][3] = 0; 412 413 // memcpy( aliasworldtransform, rotationmatrix, sizeof( aliastransform ) ); 414 415 R_ConcatTransforms (viewmatrix, aliasworldtransform, aliastransform); 416 417 aliasworldtransform[0][3] = currententity->origin[0]; 418 aliasworldtransform[1][3] = currententity->origin[1]; 419 aliasworldtransform[2][3] = currententity->origin[2]; 420 421 aliasoldworldtransform[0][3] = currententity->oldorigin[0]; 422 aliasoldworldtransform[1][3] = currententity->oldorigin[1]; 423 aliasoldworldtransform[2][3] = currententity->oldorigin[2]; 424 } 425 426 427 /* 428 ================ 429 R_AliasTransformFinalVerts 430 ================ 431 */ 432 #if id386 && !defined __linux__ 433 void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv ) 434 { 435 float lightcos; 436 float lerped_vert[3]; 437 int byte_to_dword_ptr_var; 438 int tmpint; 439 440 float one = 1.0F; 441 float zi; 442 443 static float FALIAS_Z_CLIP_PLANE = ALIAS_Z_CLIP_PLANE; 444 static float PS_SCALE = POWERSUIT_SCALE; 445 446 __asm mov ecx, numpoints 447 448 /* 449 lerped_vert[0] = r_lerp_move[0] + oldv->v[0]*r_lerp_backv[0] + newv->v[0]*r_lerp_frontv[0]; 450 lerped_vert[1] = r_lerp_move[1] + oldv->v[1]*r_lerp_backv[1] + newv->v[1]*r_lerp_frontv[1]; 451 lerped_vert[2] = r_lerp_move[2] + oldv->v[2]*r_lerp_backv[2] + newv->v[2]*r_lerp_frontv[2]; 452 */ 453 top_of_loop: 454 455 __asm mov esi, oldv 456 __asm mov edi, newv 457 458 __asm xor ebx, ebx 459 460 __asm mov bl, byte ptr [esi+DTRIVERTX_V0] 461 __asm mov byte_to_dword_ptr_var, ebx 462 __asm fild dword ptr byte_to_dword_ptr_var 463 __asm fmul dword ptr [r_lerp_backv+0] ; oldv[0]*rlb[0] 464 465 __asm mov bl, byte ptr [esi+DTRIVERTX_V1] 466 __asm mov byte_to_dword_ptr_var, ebx 467 __asm fild dword ptr byte_to_dword_ptr_var 468 __asm fmul dword ptr [r_lerp_backv+4] ; oldv[1]*rlb[1] | oldv[0]*rlb[0] 469 470 __asm mov bl, byte ptr [esi+DTRIVERTX_V2] 471 __asm mov byte_to_dword_ptr_var, ebx 472 __asm fild dword ptr byte_to_dword_ptr_var 473 __asm fmul dword ptr [r_lerp_backv+8] ; oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0] 474 475 __asm mov bl, byte ptr [edi+DTRIVERTX_V0] 476 __asm mov byte_to_dword_ptr_var, ebx 477 __asm fild dword ptr byte_to_dword_ptr_var 478 __asm fmul dword ptr [r_lerp_frontv+0] ; newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0] 479 480 __asm mov bl, byte ptr [edi+DTRIVERTX_V1] 481 __asm mov byte_to_dword_ptr_var, ebx 482 __asm fild dword ptr byte_to_dword_ptr_var 483 __asm fmul dword ptr [r_lerp_frontv+4] ; newv[1]*rlf[1] | newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0] 484 485 __asm mov bl, byte ptr [edi+DTRIVERTX_V2] 486 __asm mov byte_to_dword_ptr_var, ebx 487 __asm fild dword ptr byte_to_dword_ptr_var 488 __asm fmul dword ptr [r_lerp_frontv+8] ; newv[2]*rlf[2] | newv[1]*rlf[1] | newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0] 489 490 __asm fxch st(5) ; oldv[0]*rlb[0] | newv[1]*rlf[1] | newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | newv[2]*rlf[2] 491 __asm faddp st(2), st ; newv[1]*rlf[1] | oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | newv[2]*rlf[2] 492 __asm faddp st(3), st ; oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] + newv[1]*rlf[1] | newv[2]*rlf[2] 493 __asm fxch st(1) ; oldv[2]*rlb[2] | oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[1]*rlb[1] + newv[1]*rlf[1] | newv[2]*rlf[2] 494 __asm faddp st(3), st ; oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[1]*rlb[1] + newv[1]*rlf[1] | oldv[2]*rlb[2] + newv[2]*rlf[2] 495 __asm fadd dword ptr [r_lerp_move+0] ; lv0 | oldv[1]*rlb[1] + newv[1]*rlf[1] | oldv[2]*rlb[2] + newv[2]*rlf[2] 496 __asm fxch st(1) ; oldv[1]*rlb[1] + newv[1]*rlf[1] | lv0 | oldv[2]*rlb[2] + newv[2]*rlf[2] 497 __asm fadd dword ptr [r_lerp_move+4] ; lv1 | lv0 | oldv[2]*rlb[2] + newv[2]*rlf[2] 498 __asm fxch st(2) ; oldv[2]*rlb[2] + newv[2]*rlf[2] | lv0 | lv1 499 __asm fadd dword ptr [r_lerp_move+8] ; lv2 | lv0 | lv1 500 __asm fxch st(1) ; lv0 | lv2 | lv1 501 __asm fstp dword ptr [lerped_vert+0] ; lv2 | lv1 502 __asm fstp dword ptr [lerped_vert+8] ; lv2 503 __asm fstp dword ptr [lerped_vert+4] ; (empty) 504 505 __asm mov eax, currententity 506 __asm mov eax, dword ptr [eax+ENTITY_FLAGS] 507 __asm mov ebx, RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM 508 __asm and eax, ebx 509 __asm jz not_powersuit 510 511 /* 512 ** lerped_vert[0] += lightnormal[0] * POWERSUIT_SCALE 513 ** lerped_vert[1] += lightnormal[1] * POWERSUIT_SCALE 514 ** lerped_vert[2] += lightnormal[2] * POWERSUIT_SCALE 515 */ 516 517 __asm xor ebx, ebx 518 __asm mov bl, byte ptr [edi+DTRIVERTX_LNI] 519 __asm mov eax, 12 520 __asm mul ebx 521 __asm lea eax, [r_avertexnormals+eax] 522 523 __asm fld dword ptr [eax+0] ; n[0] 524 __asm fmul PS_SCALE ; n[0] * PS 525 __asm fld dword ptr [eax+4] ; n[1] | n[0] * PS 526 __asm fmul PS_SCALE ; n[1] * PS | n[0] * PS 527 __asm fld dword ptr [eax+8] ; n[2] | n[1] * PS | n[0] * PS 528 __asm fmul PS_SCALE ; n[2] * PS | n[1] * PS | n[0] * PS 529 __asm fld dword ptr [lerped_vert+0] ; lv0 | n[2] * PS | n[1] * PS | n[0] * PS 530 __asm faddp st(3), st ; n[2] * PS | n[1] * PS | n[0] * PS + lv0 531 __asm fld dword ptr [lerped_vert+4] ; lv1 | n[2] * PS | n[1] * PS | n[0] * PS + lv0 532 __asm faddp st(2), st ; n[2] * PS | n[1] * PS + lv1 | n[0] * PS + lv0 533 __asm fadd dword ptr [lerped_vert+8] ; n[2] * PS + lv2 | n[1] * PS + lv1 | n[0] * PS + lv0 534 __asm fxch st(2) ; LV0 | LV1 | LV2 535 __asm fstp dword ptr [lerped_vert+0] ; LV1 | LV2 536 __asm fstp dword ptr [lerped_vert+4] ; LV2 537 __asm fstp dword ptr [lerped_vert+8] ; (empty) 538 539 not_powersuit: 540 541 /* 542 fv->flags = 0; 543 544 fv->xyz[0] = DotProduct(lerped_vert, aliastransform[0]) + aliastransform[0][3]; 545 fv->xyz[1] = DotProduct(lerped_vert, aliastransform[1]) + aliastransform[1][3]; 546 fv->xyz[2] = DotProduct(lerped_vert, aliastransform[2]) + aliastransform[2][3]; 547 */ 548 __asm mov eax, fv 549 __asm mov dword ptr [eax+FINALVERT_FLAGS], 0 550 551 __asm fld dword ptr [lerped_vert+0] ; lv0 552 __asm fmul dword ptr [aliastransform+0] ; lv0*at[0][0] 553 __asm fld dword ptr [lerped_vert+4] ; lv1 | lv0*at[0][0] 554 __asm fmul dword ptr [aliastransform+4] ; lv1*at[0][1] | lv0*at[0][0] 555 __asm fld dword ptr [lerped_vert+8] ; lv2 | lv1*at[0][1] | lv0*at[0][0] 556 __asm fmul dword ptr [aliastransform+8] ; lv2*at[0][2] | lv1*at[0][1] | lv0*at[0][0] 557 __asm fxch st(2) ; lv0*at[0][0] | lv1*at[0][1] | lv2*at[0][2] 558 __asm faddp st(1), st ; lv0*at[0][0] + lv1*at[0][1] | lv2*at[0][2] 559 __asm faddp st(1), st ; lv0*at[0][0] + lv1*at[0][1] + lv2*at[0][2] 560 __asm fadd dword ptr [aliastransform+12] ; FV.X 561 562 __asm fld dword ptr [lerped_vert+0] ; lv0 563 __asm fmul dword ptr [aliastransform+16] ; lv0*at[1][0] 564 __asm fld dword ptr [lerped_vert+4] ; lv1 | lv0*at[1][0] 565 __asm fmul dword ptr [aliastransform+20] ; lv1*at[1][1] | lv0*at[1][0] 566 __asm fld dword ptr [lerped_vert+8] ; lv2 | lv1*at[1][1] | lv0*at[1][0] 567 __asm fmul dword ptr [aliastransform+24] ; lv2*at[1][2] | lv1*at[1][1] | lv0*at[1][0] 568 __asm fxch st(2) ; lv0*at[1][0] | lv1*at[1][1] | lv2*at[1][2] 569 __asm faddp st(1), st ; lv0*at[1][0] + lv1*at[1][1] | lv2*at[1][2] 570 __asm faddp st(1), st ; lv0*at[1][0] + lv1*at[1][1] + lv2*at[1][2] 571 __asm fadd dword ptr [aliastransform+28] ; FV.Y | FV.X 572 __asm fxch st(1) ; FV.X | FV.Y 573 __asm fstp dword ptr [eax+FINALVERT_X] ; FV.Y 574 575 __asm fld dword ptr [lerped_vert+0] ; lv0 576 __asm fmul dword ptr [aliastransform+32] ; lv0*at[2][0] 577 __asm fld dword ptr [lerped_vert+4] ; lv1 | lv0*at[2][0] 578 __asm fmul dword ptr [aliastransform+36] ; lv1*at[2][1] | lv0*at[2][0] 579 __asm fld dword ptr [lerped_vert+8] ; lv2 | lv1*at[2][1] | lv0*at[2][0] 580 __asm fmul dword ptr [aliastransform+40] ; lv2*at[2][2] | lv1*at[2][1] | lv0*at[2][0] 581 __asm fxch st(2) ; lv0*at[2][0] | lv1*at[2][1] | lv2*at[2][2] 582 __asm faddp st(1), st ; lv0*at[2][0] + lv1*at[2][1] | lv2*at[2][2] 583 __asm faddp st(1), st ; lv0*at[2][0] + lv1*at[2][1] + lv2*at[2][2] 584 __asm fadd dword ptr [aliastransform+44] ; FV.Z | FV.Y 585 __asm fxch st(1) ; FV.Y | FV.Z 586 __asm fstp dword ptr [eax+FINALVERT_Y] ; FV.Z 587 __asm fstp dword ptr [eax+FINALVERT_Z] ; (empty) 588 589 /* 590 ** lighting 591 ** 592 ** plightnormal = r_avertexnormals[newv->lightnormalindex]; 593 ** lightcos = DotProduct (plightnormal, r_plightvec); 594 ** temp = r_ambientlight; 595 */ 596 __asm xor ebx, ebx 597 __asm mov bl, byte ptr [edi+DTRIVERTX_LNI] 598 __asm mov eax, 12 599 __asm mul ebx 600 __asm lea eax, [r_avertexnormals+eax] 601 __asm lea ebx, r_plightvec 602 603 __asm fld dword ptr [eax+0] 604 __asm fmul dword ptr [ebx+0] 605 __asm fld dword ptr [eax+4] 606 __asm fmul dword ptr [ebx+4] 607 __asm fld dword ptr [eax+8] 608 __asm fmul dword ptr [ebx+8] 609 __asm fxch st(2) 610 __asm faddp st(1), st 611 __asm faddp st(1), st 612 __asm fstp dword ptr lightcos 613 __asm mov eax, lightcos 614 __asm mov ebx, r_ambientlight 615 616 /* 617 if (lightcos < 0) 618 { 619 temp += (int)(r_shadelight * lightcos); 620 621 // clamp; because we limited the minimum ambient and shading light, we 622 // don't have to clamp low light, just bright 623 if (temp < 0) 624 temp = 0; 625 } 626 627 fv->v[4] = temp; 628 */ 629 __asm or eax, eax 630 __asm jns store_fv4 631 632 __asm fld dword ptr r_shadelight 633 __asm fmul dword ptr lightcos 634 __asm fistp dword ptr tmpint 635 __asm add ebx, tmpint 636 637 __asm or ebx, ebx 638 __asm jns store_fv4 639 __asm mov ebx, 0 640 641 store_fv4: 642 __asm mov edi, fv 643 __asm mov dword ptr [edi+FINALVERT_V4], ebx 644 645 __asm mov edx, dword ptr [edi+FINALVERT_FLAGS] 646 647 /* 648 ** do clip testing and projection here 649 */ 650 /* 651 if ( dest_vert->xyz[2] < ALIAS_Z_CLIP_PLANE ) 652 { 653 dest_vert->flags |= ALIAS_Z_CLIP; 654 } 655 else 656 { 657 R_AliasProjectAndClipTestFinalVert( dest_vert ); 658 } 659 */ 660 __asm mov eax, dword ptr [edi+FINALVERT_Z] 661 __asm and eax, eax 662 __asm js alias_z_clip 663 __asm cmp eax, FALIAS_Z_CLIP_PLANE 664 __asm jl alias_z_clip 665 666 /* 667 This is the code to R_AliasProjectAndClipTestFinalVert 668 669 float zi; 670 float x, y, z; 671 672 x = fv->xyz[0]; 673 y = fv->xyz[1]; 674 z = fv->xyz[2]; 675 zi = 1.0 / z; 676 677 fv->v[5] = zi * s_ziscale; 678 679 fv->v[0] = (x * aliasxscale * zi) + aliasxcenter; 680 fv->v[1] = (y * aliasyscale * zi) + aliasycenter; 681 */ 682 __asm fld one ; 1 683 __asm fdiv dword ptr [edi+FINALVERT_Z] ; zi 684 685 __asm mov eax, dword ptr [edi+32] 686 __asm mov eax, dword ptr [edi+64] 687 688 __asm fst zi ; zi 689 __asm fmul s_ziscale ; fv5 690 __asm fld dword ptr [edi+FINALVERT_X] ; x | fv5 691 __asm fmul aliasxscale ; x * aliasxscale | fv5 692 __asm fld dword ptr [edi+FINALVERT_Y] ; y | x * aliasxscale | fv5 693 __asm fmul aliasyscale ; y * aliasyscale | x * aliasxscale | fv5 694 __asm fxch st(1) ; x * aliasxscale | y * aliasyscale | fv5 695 __asm fmul zi ; x * asx * zi | y * asy | fv5 696 __asm fadd aliasxcenter ; fv0 | y * asy | fv5 697 __asm fxch st(1) ; y * asy | fv0 | fv5 698 __asm fmul zi ; y * asy * zi | fv0 | fv5 699 __asm fadd aliasycenter ; fv1 | fv0 | fv5 700 __asm fxch st(2) ; fv5 | fv0 | fv1 701 __asm fistp dword ptr [edi+FINALVERT_V5] ; fv0 | fv1 702 __asm fistp dword ptr [edi+FINALVERT_V0] ; fv1 703 __asm fistp dword ptr [edi+FINALVERT_V1] ; (empty) 704 705 /* 706 if (fv->v[0] < r_refdef.aliasvrect.x) 707 fv->flags |= ALIAS_LEFT_CLIP; 708 if (fv->v[1] < r_refdef.aliasvrect.y) 709 fv->flags |= ALIAS_TOP_CLIP; 710 if (fv->v[0] > r_refdef.aliasvrectright) 711 fv->flags |= ALIAS_RIGHT_CLIP; 712 if (fv->v[1] > r_refdef.aliasvrectbottom) 713 fv->flags |= ALIAS_BOTTOM_CLIP; 714 */ 715 __asm mov eax, dword ptr [edi+FINALVERT_V0] 716 __asm mov ebx, dword ptr [edi+FINALVERT_V1] 717 718 __asm cmp eax, r_refdef.aliasvrect.x 719 __asm jge ct_alias_top 720 __asm or edx, ALIAS_LEFT_CLIP 721 ct_alias_top: 722 __asm cmp ebx, r_refdef.aliasvrect.y 723 __asm jge ct_alias_right 724 __asm or edx, ALIAS_TOP_CLIP 725 ct_alias_right: 726 __asm cmp eax, r_refdef.aliasvrectright 727 __asm jle ct_alias_bottom 728 __asm or edx, ALIAS_RIGHT_CLIP 729 ct_alias_bottom: 730 __asm cmp ebx, r_refdef.aliasvrectbottom 731 __asm jle end_of_loop 732 __asm or edx, ALIAS_BOTTOM_CLIP 733 734 __asm jmp end_of_loop 735 736 alias_z_clip: 737 __asm or edx, ALIAS_Z_CLIP 738 739 end_of_loop: 740 741 __asm mov dword ptr [edi+FINALVERT_FLAGS], edx 742 __asm add oldv, DTRIVERTX_SIZE 743 __asm add newv, DTRIVERTX_SIZE 744 __asm add fv, FINALVERT_SIZE 745 746 __asm dec ecx 747 __asm jnz top_of_loop 748 } 749 #else 750 void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv ) 751 { 752 int i; 753 754 for ( i = 0; i < numpoints; i++, fv++, oldv++, newv++ ) 755 { 756 int temp; 757 float lightcos, *plightnormal; 758 vec3_t lerped_vert; 759 760 lerped_vert[0] = r_lerp_move[0] + oldv->v[0]*r_lerp_backv[0] + newv->v[0]*r_lerp_frontv[0]; 761 lerped_vert[1] = r_lerp_move[1] + oldv->v[1]*r_lerp_backv[1] + newv->v[1]*r_lerp_frontv[1]; 762 lerped_vert[2] = r_lerp_move[2] + oldv->v[2]*r_lerp_backv[2] + newv->v[2]*r_lerp_frontv[2]; 763 764 plightnormal = r_avertexnormals[newv->lightnormalindex]; 765 766 // PMM - added double damage shell 767 if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) 768 { 769 lerped_vert[0] += plightnormal[0] * POWERSUIT_SCALE; 770 lerped_vert[1] += plightnormal[1] * POWERSUIT_SCALE; 771 lerped_vert[2] += plightnormal[2] * POWERSUIT_SCALE; 772 } 773 774 fv->xyz[0] = DotProduct(lerped_vert, aliastransform[0]) + aliastransform[0][3]; 775 fv->xyz[1] = DotProduct(lerped_vert, aliastransform[1]) + aliastransform[1][3]; 776 fv->xyz[2] = DotProduct(lerped_vert, aliastransform[2]) + aliastransform[2][3]; 777 778 fv->flags = 0; 779 780 // lighting 781 lightcos = DotProduct (plightnormal, r_plightvec); 782 temp = r_ambientlight; 783 784 if (lightcos < 0) 785 { 786 temp += (int)(r_shadelight * lightcos); 787 788 // clamp; because we limited the minimum ambient and shading light, we 789 // don't have to clamp low light, just bright 790 if (temp < 0) 791 temp = 0; 792 } 793 794 fv->l = temp; 795 796 if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE ) 797 { 798 fv->flags |= ALIAS_Z_CLIP; 799 } 800 else 801 { 802 R_AliasProjectAndClipTestFinalVert( fv ); 803 } 804 } 805 } 806 807 #endif 808 809 /* 810 ================ 811 R_AliasProjectAndClipTestFinalVert 812 ================ 813 */ 814 void R_AliasProjectAndClipTestFinalVert( finalvert_t *fv ) 815 { 816 float zi; 817 float x, y, z; 818 819 // project points 820 x = fv->xyz[0]; 821 y = fv->xyz[1]; 822 z = fv->xyz[2]; 823 zi = 1.0 / z; 824 825 fv->zi = zi * s_ziscale; 826 827 fv->u = (x * aliasxscale * zi) + aliasxcenter; 828 fv->v = (y * aliasyscale * zi) + aliasycenter; 829 830 if (fv->u < r_refdef.aliasvrect.x) 831 fv->flags |= ALIAS_LEFT_CLIP; 832 if (fv->v < r_refdef.aliasvrect.y) 833 fv->flags |= ALIAS_TOP_CLIP; 834 if (fv->u > r_refdef.aliasvrectright) 835 fv->flags |= ALIAS_RIGHT_CLIP; 836 if (fv->v > r_refdef.aliasvrectbottom) 837 fv->flags |= ALIAS_BOTTOM_CLIP; 838 } 839 840 /* 841 =============== 842 R_AliasSetupSkin 843 =============== 844 */ 845 static qboolean R_AliasSetupSkin (void) 846 { 847 int skinnum; 848 image_t *pskindesc; 849 850 if (currententity->skin) 851 pskindesc = currententity->skin; 852 else 853 { 854 skinnum = currententity->skinnum; 855 if ((skinnum >= s_pmdl->num_skins) || (skinnum < 0)) 856 { 857 ri.Con_Printf (PRINT_ALL, "R_AliasSetupSkin %s: no such skin # %d\n", 858 currentmodel->name, skinnum); 859 skinnum = 0; 860 } 861 862 pskindesc = currentmodel->skins[skinnum]; 863 } 864 865 if ( !pskindesc ) 866 return false; 867 868 r_affinetridesc.pskin = pskindesc->pixels[0]; 869 r_affinetridesc.skinwidth = pskindesc->width; 870 r_affinetridesc.skinheight = pskindesc->height; 871 872 R_PolysetUpdateTables (); // FIXME: precalc edge lookups 873 874 return true; 875 } 876 877 878 /* 879 ================ 880 R_AliasSetupLighting 881 882 FIXME: put lighting into tables 883 ================ 884 */ 885 void R_AliasSetupLighting (void) 886 { 887 alight_t lighting; 888 float lightvec[3] = {-1, 0, 0}; 889 vec3_t light; 890 int i, j; 891 892 // all components of light should be identical in software 893 if ( currententity->flags & RF_FULLBRIGHT ) 894 { 895 for (i=0 ; i<3 ; i++) 896 light[i] = 1.0; 897 } 898 else 899 { 900 R_LightPoint (currententity->origin, light); 901 } 902 903 // save off light value for server to look at (BIG HACK!) 904 if ( currententity->flags & RF_WEAPONMODEL ) 905 r_lightlevel->value = 150.0 * light[0]; 906 907 908 if ( currententity->flags & RF_MINLIGHT ) 909 { 910 for (i=0 ; i<3 ; i++) 911 if (light[i] < 0.1) 912 light[i] = 0.1; 913 } 914 915 if ( currententity->flags & RF_GLOW ) 916 { // bonus items will pulse with time 917 float scale; 918 float min; 919 920 scale = 0.1 * sin(r_newrefdef.time*7); 921 for (i=0 ; i<3 ; i++) 922 { 923 min = light[i] * 0.8; 924 light[i] += scale; 925 if (light[i] < min) 926 light[i] = min; 927 } 928 } 929 930 j = (light[0] + light[1] + light[2])*0.3333*255; 931 932 lighting.ambientlight = j; 933 lighting.shadelight = j; 934 935 lighting.plightvec = lightvec; 936 937 // clamp lighting so it doesn't overbright as much 938 if (lighting.ambientlight > 128) 939 lighting.ambientlight = 128; 940 if (lighting.ambientlight + lighting.shadelight > 192) 941 lighting.shadelight = 192 - lighting.ambientlight; 942 943 // guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have 944 // to clamp off the bottom 945 r_ambientlight = lighting.ambientlight; 946 947 if (r_ambientlight < LIGHT_MIN) 948 r_ambientlight = LIGHT_MIN; 949 950 r_ambientlight = (255 - r_ambientlight) << VID_CBITS; 951 952 if (r_ambientlight < LIGHT_MIN) 953 r_ambientlight = LIGHT_MIN; 954 955 r_shadelight = lighting.shadelight; 956 957 if (r_shadelight < 0) 958 r_shadelight = 0; 959 960 r_shadelight *= VID_GRADES; 961 962 // rotate the lighting vector into the model's frame of reference 963 r_plightvec[0] = DotProduct( lighting.plightvec, s_alias_forward ); 964 r_plightvec[1] = -DotProduct( lighting.plightvec, s_alias_right ); 965 r_plightvec[2] = DotProduct( lighting.plightvec, s_alias_up ); 966 } 967 968 969 /* 970 ================= 971 R_AliasSetupFrames 972 973 ================= 974 */ 975 void R_AliasSetupFrames( dmdl_t *pmdl ) 976 { 977 int thisframe = currententity->frame; 978 int lastframe = currententity->oldframe; 979 980 if ( ( thisframe >= pmdl->num_frames ) || ( thisframe < 0 ) ) 981 { 982 ri.Con_Printf (PRINT_ALL, "R_AliasSetupFrames %s: no such thisframe %d\n", 983 currentmodel->name, thisframe); 984 thisframe = 0; 985 } 986 if ( ( lastframe >= pmdl->num_frames ) || ( lastframe < 0 ) ) 987 { 988 ri.Con_Printf (PRINT_ALL, "R_AliasSetupFrames %s: no such lastframe %d\n", 989 currentmodel->name, lastframe); 990 lastframe = 0; 991 } 992 993 r_thisframe = (daliasframe_t *)((byte *)pmdl + pmdl->ofs_frames 994 + thisframe * pmdl->framesize); 995 996 r_lastframe = (daliasframe_t *)((byte *)pmdl + pmdl->ofs_frames 997 + lastframe * pmdl->framesize); 998 } 999 1000 /* 1001 ** R_AliasSetUpLerpData 1002 ** 1003 ** Precomputes lerp coefficients used for the whole frame. 1004 */ 1005 void R_AliasSetUpLerpData( dmdl_t *pmdl, float backlerp ) 1006 { 1007 float frontlerp; 1008 vec3_t translation, vectors[3]; 1009 int i; 1010 1011 frontlerp = 1.0F - backlerp; 1012 1013 /* 1014 ** convert entity's angles into discrete vectors for R, U, and F 1015 */ 1016 AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]); 1017 1018 /* 1019 ** translation is the vector from last position to this position 1020 */ 1021 VectorSubtract (currententity->oldorigin, currententity->origin, translation); 1022 1023 /* 1024 ** move should be the delta back to the previous frame * backlerp 1025 */ 1026 r_lerp_move[0] = DotProduct(translation, vectors[0]); // forward 1027 r_lerp_move[1] = -DotProduct(translation, vectors[1]); // left 1028 r_lerp_move[2] = DotProduct(translation, vectors[2]); // up 1029 1030 VectorAdd( r_lerp_move, r_lastframe->translate, r_lerp_move ); 1031 1032 for (i=0 ; i<3 ; i++) 1033 { 1034 r_lerp_move[i] = backlerp*r_lerp_move[i] + frontlerp * r_thisframe->translate[i]; 1035 } 1036 1037 for (i=0 ; i<3 ; i++) 1038 { 1039 r_lerp_frontv[i] = frontlerp * r_thisframe->scale[i]; 1040 r_lerp_backv[i] = backlerp * r_lastframe->scale[i]; 1041 } 1042 } 1043 1044 /* 1045 ================ 1046 R_AliasDrawModel 1047 ================ 1048 */ 1049 void R_AliasDrawModel (void) 1050 { 1051 extern void (*d_pdrawspans)(void *); 1052 extern void R_PolysetDrawSpans8_Opaque( void * ); 1053 extern void R_PolysetDrawSpans8_33( void * ); 1054 extern void R_PolysetDrawSpans8_66( void * ); 1055 extern void R_PolysetDrawSpansConstant8_33( void * ); 1056 extern void R_PolysetDrawSpansConstant8_66( void * ); 1057 1058 s_pmdl = (dmdl_t *)currentmodel->extradata; 1059 1060 if ( r_lerpmodels->value == 0 ) 1061 currententity->backlerp = 0; 1062 1063 if ( currententity->flags & RF_WEAPONMODEL ) 1064 { 1065 if ( r_lefthand->value == 1.0F ) 1066 aliasxscale = -aliasxscale; 1067 else if ( r_lefthand->value == 2.0F ) 1068 return; 1069 } 1070 1071 /* 1072 ** we have to set our frame pointers and transformations before 1073 ** doing any real work 1074 */ 1075 R_AliasSetupFrames( s_pmdl ); 1076 R_AliasSetUpTransform(); 1077 1078 // see if the bounding box lets us trivially reject, also sets 1079 // trivial accept status 1080 if ( R_AliasCheckBBox() == BBOX_TRIVIAL_REJECT ) 1081 { 1082 if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) ) 1083 { 1084 aliasxscale = -aliasxscale; 1085 } 1086 return; 1087 } 1088 1089 // set up the skin and verify it exists 1090 if ( !R_AliasSetupSkin () ) 1091 { 1092 ri.Con_Printf( PRINT_ALL, "R_AliasDrawModel %s: NULL skin found\n", 1093 currentmodel->name); 1094 return; 1095 } 1096 1097 r_amodels_drawn++; 1098 R_AliasSetupLighting (); 1099 1100 /* 1101 ** select the proper span routine based on translucency 1102 */ 1103 // PMM - added double damage shell 1104 // PMM - reordered to handle blending 1105 if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) 1106 { 1107 int color; 1108 1109 // PMM - added double 1110 color = currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM); 1111 // PMM - reordered, old code first 1112 /* 1113 if ( color == RF_SHELL_RED ) 1114 r_aliasblendcolor = SHELL_RED_COLOR; 1115 else if ( color == RF_SHELL_GREEN ) 1116 r_aliasblendcolor = SHELL_GREEN_COLOR; 1117 else if ( color == RF_SHELL_BLUE ) 1118 r_aliasblendcolor = SHELL_BLUE_COLOR; 1119 else if ( color == (RF_SHELL_RED | RF_SHELL_GREEN) ) 1120 r_aliasblendcolor = SHELL_RG_COLOR; 1121 else if ( color == (RF_SHELL_RED | RF_SHELL_BLUE) ) 1122 r_aliasblendcolor = SHELL_RB_COLOR; 1123 else if ( color == (RF_SHELL_BLUE | RF_SHELL_GREEN) ) 1124 r_aliasblendcolor = SHELL_BG_COLOR; 1125 // PMM - added this .. it's yellowish 1126 else if ( color == (RF_SHELL_DOUBLE) ) 1127 r_aliasblendcolor = SHELL_DOUBLE_COLOR; 1128 else if ( color == (RF_SHELL_HALF_DAM) ) 1129 r_aliasblendcolor = SHELL_HALF_DAM_COLOR; 1130 // pmm 1131 else 1132 r_aliasblendcolor = SHELL_WHITE_COLOR; 1133 */ 1134 if ( color & RF_SHELL_RED ) 1135 { 1136 if ( ( color & RF_SHELL_BLUE) && ( color & RF_SHELL_GREEN) ) 1137 r_aliasblendcolor = SHELL_WHITE_COLOR; 1138 else if ( color & (RF_SHELL_BLUE | RF_SHELL_DOUBLE)) 1139 r_aliasblendcolor = SHELL_RB_COLOR; 1140 else 1141 r_aliasblendcolor = SHELL_RED_COLOR; 1142 } 1143 else if ( color & RF_SHELL_BLUE) 1144 { 1145 if ( color & RF_SHELL_DOUBLE ) 1146 r_aliasblendcolor = SHELL_CYAN_COLOR; 1147 else 1148 r_aliasblendcolor = SHELL_BLUE_COLOR; 1149 } 1150 else if ( color & (RF_SHELL_DOUBLE) ) 1151 r_aliasblendcolor = SHELL_DOUBLE_COLOR; 1152 else if ( color & (RF_SHELL_HALF_DAM) ) 1153 r_aliasblendcolor = SHELL_HALF_DAM_COLOR; 1154 else if ( color & RF_SHELL_GREEN ) 1155 r_aliasblendcolor = SHELL_GREEN_COLOR; 1156 else 1157 r_aliasblendcolor = SHELL_WHITE_COLOR; 1158 1159 1160 if ( currententity->alpha > 0.33 ) 1161 d_pdrawspans = R_PolysetDrawSpansConstant8_66; 1162 else 1163 d_pdrawspans = R_PolysetDrawSpansConstant8_33; 1164 } 1165 else if ( currententity->flags & RF_TRANSLUCENT ) 1166 { 1167 if ( currententity->alpha > 0.66 ) 1168 d_pdrawspans = R_PolysetDrawSpans8_Opaque; 1169 else if ( currententity->alpha > 0.33 ) 1170 d_pdrawspans = R_PolysetDrawSpans8_66; 1171 else 1172 d_pdrawspans = R_PolysetDrawSpans8_33; 1173 } 1174 else 1175 { 1176 d_pdrawspans = R_PolysetDrawSpans8_Opaque; 1177 } 1178 1179 /* 1180 ** compute this_frame and old_frame addresses 1181 */ 1182 R_AliasSetUpLerpData( s_pmdl, currententity->backlerp ); 1183 1184 if (currententity->flags & RF_DEPTHHACK) 1185 s_ziscale = (float)0x8000 * (float)0x10000 * 3.0; 1186 else 1187 s_ziscale = (float)0x8000 * (float)0x10000; 1188 1189 R_AliasPreparePoints (); 1190 1191 if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) ) 1192 { 1193 aliasxscale = -aliasxscale; 1194 } 1195 } 1196 1197 1198