r_alias.c 34 KB

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