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