int DrawTriangleToBuffer( char* buff )//returns 0, if no output triangles { const int vertex_size= sizeof(int)*3 + ( (color_mode==COLOR_PER_VERTEX)? 4 : 0 ) + ( (texture_mode==TEXTURE_NONE)? 0 : 2*sizeof(int) ) + ( (lighting_mode==LIGHTING_FROM_LIGHTMAP)? 2*sizeof(int) : 0 ) + ( (lighting_mode==LIGHTING_PER_VERTEX)? sizeof(int) : 0 ) + ( (lighting_mode==LIGHTING_PER_VERTEX_COLORED) ? 4 : 0 ); // if( triangle_in_vertex_xy[1] == triangle_in_vertex_xy[3] && triangle_in_vertex_xy[1] == triangle_in_vertex_xy[5] ) // return 0;//nothing to draw, triangle is flat, works for far small triangles int vertex_indeces_from_upper[3]= { 0, 1, 2 }; int vertex_y_from_upper[3]= { triangle_in_vertex_xy[1], triangle_in_vertex_xy[3], triangle_in_vertex_xy[5] }; fixed16_t triangle_in_vertex_inv_z[]= { Fixed16Invert(triangle_in_vertex_z[0] ), Fixed16Invert(triangle_in_vertex_z[1] ), Fixed16Invert(triangle_in_vertex_z[2] ) }; //sort vertices from upper to lower, using bubble-sorting register int tmp; if( vertex_y_from_upper[0] < vertex_y_from_upper[1] ) { tmp= vertex_y_from_upper[0]; vertex_y_from_upper[0]= vertex_y_from_upper[1]; vertex_y_from_upper[1]= tmp; tmp= vertex_indeces_from_upper[0]; vertex_indeces_from_upper[0]= vertex_indeces_from_upper[1]; vertex_indeces_from_upper[1]= tmp; } if( vertex_y_from_upper[0] < vertex_y_from_upper[2] ) { tmp= vertex_y_from_upper[0]; vertex_y_from_upper[0]= vertex_y_from_upper[2]; vertex_y_from_upper[2]= tmp; tmp= vertex_indeces_from_upper[0]; vertex_indeces_from_upper[0]= vertex_indeces_from_upper[2]; vertex_indeces_from_upper[2]= tmp; } if( vertex_y_from_upper[1] < vertex_y_from_upper[2] ) { tmp= vertex_y_from_upper[2]; vertex_y_from_upper[2]= vertex_y_from_upper[1]; vertex_y_from_upper[1]= tmp; tmp= vertex_indeces_from_upper[2]; vertex_indeces_from_upper[2]= vertex_indeces_from_upper[1]; vertex_indeces_from_upper[1]= tmp; } //end of sorting fixed16_t div= triangle_in_vertex_xy[ vertex_indeces_from_upper[0]*2 + 1 ] - triangle_in_vertex_xy[ vertex_indeces_from_upper[2]*2 + 1 ]; if( div < 4 ) return 0;//triangle is so small fixed16_t k0= Fixed16Div( triangle_in_vertex_xy[ vertex_indeces_from_upper[0]*2 + 1 ] - triangle_in_vertex_xy[ vertex_indeces_from_upper[1]*2 + 1 ], div ); fixed16_t k1= (1<<16) - k0; fixed16_t up_down_line_x= Fixed16Mul( triangle_in_vertex_xy[ vertex_indeces_from_upper[0]<<1 ], k1 ) + Fixed16Mul( triangle_in_vertex_xy[ vertex_indeces_from_upper[2]<<1 ], k0 ); char* v= buff; //write lower vertex attributes ((int*)v)[0]= triangle_in_vertex_xy[ vertex_indeces_from_upper[2]<<1 ]; ((int*)v)[1]= triangle_in_vertex_xy[ (vertex_indeces_from_upper[2]<<1)+1 ]; ((int*)v)[2]= triangle_in_vertex_z[ vertex_indeces_from_upper[2] ]; v+= 3 * sizeof(int); if( color_mode == COLOR_PER_VERTEX || lighting_mode == LIGHTING_PER_VERTEX_COLORED ) { Byte4Copy( v, triangle_in_color + (vertex_indeces_from_upper[2]<<2) ); v+=4; } if( texture_mode != TEXTURE_NONE ) { ((int*)v)[0]= triangle_in_tex_coord[ vertex_indeces_from_upper[2]<<1 ]; ((int*)v)[1]= triangle_in_tex_coord[ (vertex_indeces_from_upper[2]<<1)+1 ]; v+=sizeof(fixed16_t)*2; } if( lighting_mode == LIGHTING_PER_VERTEX ) { ((int*)v)[0]= triangle_in_light[ vertex_indeces_from_upper[2] ]; v+= sizeof(fixed16_t); } if( lighting_mode == LIGHTING_FROM_LIGHTMAP ) { ((int*)v)[0]= triangle_in_lightmap_tex_coord[ vertex_indeces_from_upper[2]<<1 ]; ((int*)v)[1]= triangle_in_lightmap_tex_coord[ (vertex_indeces_from_upper[2]<<1)+1 ]; v+=sizeof(fixed16_t)*2; } //write middle vertices bool invert_vertex_order= triangle_in_vertex_xy[ vertex_indeces_from_upper[1]<<1 ] <= up_down_line_x; if( invert_vertex_order ) v+= vertex_size; //write interpolated vertex fixed16_t final_z; ((int*)v)[0]= up_down_line_x; ((int*)v)[1]= triangle_in_vertex_xy[ (vertex_indeces_from_upper[1]<<1)+1 ];//y - from middle vertex ((int*)v)[2]= Fixed16Invert ( Fixed16Mul( triangle_in_vertex_inv_z[ vertex_indeces_from_upper[0] ], k1 ) + Fixed16Mul( triangle_in_vertex_inv_z[ vertex_indeces_from_upper[2] ], k0 ) );//interpolate inv_z final_z= ((int*)v)[2]; v+= 3 * sizeof(int); if( color_mode == COLOR_PER_VERTEX || lighting_mode == LIGHTING_PER_VERTEX_COLORED ) { fixed16_t inv_z0= triangle_in_vertex_inv_z[ vertex_indeces_from_upper[0] ]; fixed16_t inv_z2= triangle_in_vertex_inv_z[ vertex_indeces_from_upper[2] ]; for( int i= 0; i< 4; i++ ) { //convert in color to fixed16_t format and divede by z fixed16_t div_c0= triangle_in_color[ i + (vertex_indeces_from_upper[0]<<2) ] * inv_z0; fixed16_t div_c2= triangle_in_color[ i + (vertex_indeces_from_upper[2]<<2) ] * inv_z2; ((unsigned char*)v)[i]= Fixed16MulResultToInt( ( Fixed16Mul( div_c0, k1 ) + Fixed16Mul( div_c2, k0 ) ), final_z );//make interpolation and write result } v+=4; } if( texture_mode != TEXTURE_NONE ) { fixed16_t inv_z0= triangle_in_vertex_inv_z[ vertex_indeces_from_upper[0] ]; fixed16_t inv_z2= triangle_in_vertex_inv_z[ vertex_indeces_from_upper[2] ]; fixed16_t div_tc0= Fixed16Mul( triangle_in_tex_coord[ (vertex_indeces_from_upper[0]<<1) ], inv_z0 ); fixed16_t div_tc2= Fixed16Mul( triangle_in_tex_coord[ (vertex_indeces_from_upper[2]<<1) ], inv_z2 ); ((int*)v)[0]= Fixed16Mul( Fixed16Mul( div_tc0, k1 ) + Fixed16Mul( div_tc2, k0 ), final_z ); div_tc0= Fixed16Mul( triangle_in_tex_coord[ 1+(vertex_indeces_from_upper[0]<<1) ], inv_z0 ); div_tc2= Fixed16Mul( triangle_in_tex_coord[ 1+(vertex_indeces_from_upper[2]<<1) ], inv_z2 ); ((int*)v)[1]= Fixed16Mul( Fixed16Mul( div_tc0, k1 ) + Fixed16Mul( div_tc2, k0 ), final_z ); v+=2*sizeof(int); } if( lighting_mode == LIGHTING_PER_VERTEX ) { fixed16_t div_l0= triangle_in_light[ vertex_indeces_from_upper[0] ] * triangle_in_vertex_inv_z[ vertex_indeces_from_upper[0] ]; fixed16_t div_l2= triangle_in_light[ vertex_indeces_from_upper[2] ] * triangle_in_vertex_inv_z[ vertex_indeces_from_upper[2] ]; ((int*)v)[0]= Fixed16MulResultToInt( Fixed16Mul( div_l0, k1 ) + Fixed16Mul( div_l2, k0 ), final_z ); v+=sizeof(int); } if( lighting_mode == LIGHTING_FROM_LIGHTMAP ) { fixed16_t inv_z0= triangle_in_vertex_inv_z[ vertex_indeces_from_upper[0] ]; fixed16_t inv_z2= triangle_in_vertex_inv_z[ vertex_indeces_from_upper[2] ]; fixed16_t div_tc0= Fixed16Mul( triangle_in_lightmap_tex_coord[ (vertex_indeces_from_upper[0]<<1) ], inv_z0 ); fixed16_t div_tc2= Fixed16Mul( triangle_in_lightmap_tex_coord[ (vertex_indeces_from_upper[2]<<1) ], inv_z2 ); ((int*)v)[0]= Fixed16Mul( Fixed16Mul( div_tc0, k1 ) + Fixed16Mul( div_tc2, k0 ), final_z ); div_tc0= Fixed16Mul( triangle_in_lightmap_tex_coord[ 1+(vertex_indeces_from_upper[0]<<1) ], inv_z0 ); div_tc2= Fixed16Mul( triangle_in_lightmap_tex_coord[ 1+(vertex_indeces_from_upper[2]<<1) ], inv_z2 ); ((int*)v)[1]= Fixed16Mul( Fixed16Mul( div_tc0, k1 ) + Fixed16Mul( div_tc2, k0 ), final_z ); v+=2*sizeof(int); } if( invert_vertex_order ) v-= 2*vertex_size; //write middle vertex ((int*)v)[0]= triangle_in_vertex_xy[ vertex_indeces_from_upper[1]<<1 ]; ((int*)v)[1]= triangle_in_vertex_xy[ (vertex_indeces_from_upper[1]<<1)+1 ]; ((int*)v)[2]= triangle_in_vertex_z[ vertex_indeces_from_upper[1] ]; v+= 3 * sizeof(int); if( color_mode == COLOR_PER_VERTEX || lighting_mode == LIGHTING_PER_VERTEX_COLORED ) { Byte4Copy( v, triangle_in_color + (vertex_indeces_from_upper[1]<<2) ); v+=4; } if( texture_mode != TEXTURE_NONE ) { ((int*)v)[0]= triangle_in_tex_coord[ vertex_indeces_from_upper[1]<<1 ]; ((int*)v)[1]= triangle_in_tex_coord[ (vertex_indeces_from_upper[1]<<1)+1 ]; v+=sizeof(fixed16_t)*2; } if( lighting_mode == LIGHTING_PER_VERTEX ) { ((int*)v)[0]= triangle_in_light[ vertex_indeces_from_upper[1] ]; v+= sizeof(fixed16_t); } if( lighting_mode == LIGHTING_FROM_LIGHTMAP ) { ((int*)v)[0]= triangle_in_lightmap_tex_coord[ vertex_indeces_from_upper[1]<<1 ]; ((int*)v)[1]= triangle_in_lightmap_tex_coord[ (vertex_indeces_from_upper[1]<<1)+1 ]; v+=sizeof(fixed16_t)*2; } if( invert_vertex_order ) v+= vertex_size; //write upper vertex attributes ((int*)v)[0]= triangle_in_vertex_xy[ vertex_indeces_from_upper[0]<<1 ]; ((int*)v)[1]= triangle_in_vertex_xy[ (vertex_indeces_from_upper[0]<<1)+1 ]; ((int*)v)[2]= triangle_in_vertex_z[ vertex_indeces_from_upper[0] ]; v+= 3 * sizeof(int); if( color_mode == COLOR_PER_VERTEX || lighting_mode == LIGHTING_PER_VERTEX_COLORED ) { Byte4Copy( v, triangle_in_color + (vertex_indeces_from_upper[0]<<2) ); v+=4; } if( texture_mode != TEXTURE_NONE ) { ((int*)v)[0]= triangle_in_tex_coord[ vertex_indeces_from_upper[0]<<1 ]; ((int*)v)[1]= triangle_in_tex_coord[ (vertex_indeces_from_upper[0]<<1)+1 ]; v+=sizeof(fixed16_t)*2; } if( lighting_mode == LIGHTING_PER_VERTEX ) { ((int*)v)[0]= triangle_in_light[ vertex_indeces_from_upper[0] ]; v+= sizeof(fixed16_t); } if( lighting_mode == LIGHTING_FROM_LIGHTMAP ) { ((int*)v)[0]= triangle_in_lightmap_tex_coord[ vertex_indeces_from_upper[0]<<1 ]; ((int*)v)[1]= triangle_in_lightmap_tex_coord[ (vertex_indeces_from_upper[0]<<1)+1 ]; v+=sizeof(fixed16_t)*2; } return 4; }
/* =============== UI_DrawPlayer =============== */ void UI_DrawPlayer( float x, float y, float w, float h, uiPlayerInfo_t *pi, int time ) { refdef_t refdef; refEntity_t legs = {0}; refEntity_t torso = {0}; refEntity_t head = {0}; refEntity_t gun = {0}; refEntity_t barrel = {0}; refEntity_t flash = {0}; vec3_t origin; int renderfx; vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; float len; float xx; float xscale; float yscale; if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) { return; } // this allows the ui to cache the player model on the main menu if (w == 0 || h == 0) { return; } dp_realtime = time; if ( pi->pendingWeapon != WP_NUM_WEAPONS && dp_realtime > pi->weaponTimer ) { pi->weapon = pi->pendingWeapon; pi->lastWeapon = pi->pendingWeapon; pi->pendingWeapon = WP_NUM_WEAPONS; pi->weaponTimer = 0; if( pi->currentWeapon != pi->weapon ) { trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL ); } } CG_AdjustFrom640( &x, &y, &w, &h ); y -= jumpHeight; memset( &refdef, 0, sizeof( refdef ) ); memset( &legs, 0, sizeof(legs) ); memset( &torso, 0, sizeof(torso) ); memset( &head, 0, sizeof(head) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; if ( ui_stretch.integer ) { xscale = cgs.screenXScaleStretch; yscale = cgs.screenYScaleStretch; } else { xscale = cgs.screenXScale; yscale = cgs.screenYScale; } refdef.fov_x = (int)((float)refdef.width / xscale / 640.0f * 90.0f); xx = refdef.width / xscale / tan( refdef.fov_x / 360 * M_PI ); refdef.fov_y = atan2( refdef.height / yscale, xx ); refdef.fov_y *= ( 360 / (float)M_PI ); // calculate distance so the player nearly fills the box len = 0.7 * ( maxs[2] - mins[2] ); origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 ); origin[1] = 0.5 * ( mins[1] + maxs[1] ); origin[2] = -0.5 * ( mins[2] + maxs[2] ); refdef.time = dp_realtime; trap_R_ClearScene(); // get the rotation information UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis ); // get the animation state (after rotation, to allow feet shuffle) UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp, &torso.oldframe, &torso.frame, &torso.backlerp ); renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; // // add the legs // legs.hModel = pi->legsModel; legs.customSkin = CG_AddSkinToFrame( &pi->modelSkin ); VectorCopy( origin, legs.origin ); VectorCopy( origin, legs.lightingOrigin ); legs.renderfx = renderfx; VectorCopy (legs.origin, legs.oldorigin); Byte4Copy( pi->c1RGBA, legs.shaderRGBA ); CG_AddRefEntityWithMinLight( &legs ); if (!legs.hModel) { return; } // // add the torso // torso.hModel = pi->torsoModel; if (!torso.hModel) { return; } torso.customSkin = legs.customSkin; VectorCopy( origin, torso.lightingOrigin ); UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso"); torso.renderfx = renderfx; Byte4Copy( pi->c1RGBA, torso.shaderRGBA ); CG_AddRefEntityWithMinLight( &torso ); // // add the head // head.hModel = pi->headModel; if (!head.hModel) { return; } head.customSkin = legs.customSkin; VectorCopy( origin, head.lightingOrigin ); UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head"); head.renderfx = renderfx; Byte4Copy( pi->c1RGBA, head.shaderRGBA ); CG_AddRefEntityWithMinLight( &head ); // // add the gun // if ( pi->currentWeapon != WP_NONE ) { memset( &gun, 0, sizeof(gun) ); gun.hModel = pi->weaponModel; Byte4Copy( pi->c1RGBA, gun.shaderRGBA ); VectorCopy( origin, gun.lightingOrigin ); UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon"); gun.renderfx = renderfx; CG_AddRefEntityWithMinLight( &gun ); } // // add the spinning barrel // if ( pi->barrelModel ) { vec3_t angles; memset( &barrel, 0, sizeof(barrel) ); VectorCopy( origin, barrel.lightingOrigin ); barrel.renderfx = renderfx; barrel.hModel = pi->barrelModel; angles[YAW] = 0; angles[PITCH] = 0; angles[ROLL] = UI_MachinegunSpinAngle( pi ); AnglesToAxis( angles, barrel.axis ); UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel"); CG_AddRefEntityWithMinLight( &barrel ); } // // add muzzle flash // if ( dp_realtime <= pi->muzzleFlashTime ) { if ( pi->flashModel ) { memset( &flash, 0, sizeof(flash) ); flash.hModel = pi->flashModel; Byte4Copy( pi->c1RGBA, flash.shaderRGBA ); VectorCopy( origin, flash.lightingOrigin ); UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash"); flash.renderfx = renderfx; CG_AddRefEntityWithMinLight( &flash ); } // make a dlight for the flash if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { trap_R_AddJuniorLightToScene( flash.origin, 200 + (rand()&31), 1.0f, pi->flashDlightColor[0], pi->flashDlightColor[1], pi->flashDlightColor[2] ); } } // // add the chat icon // if ( pi->chat ) { UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) ); } // // add an accent light // origin[0] -= 100; // + = behind, - = in front origin[1] += 100; // + = left, - = right origin[2] += 100; // + = above, - = below trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 1.0, 1.0 ); origin[0] -= 100; origin[1] -= 100; origin[2] -= 100; trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 0.0, 0.0 ); trap_R_RenderScene( &refdef ); }
/* =============== UI_DrawPlayer =============== */ void UI_DrawPlayer( float x, float y, float w, float h, uiPlayerInfo_t *pi, int time ) { refdef_t refdef; refEntity_t legs = {0}; refEntity_t torso = {0}; refEntity_t head = {0}; #ifdef TA_WEAPSYS refEntity_t gun[MAX_HANDS] = {{0}}; #else refEntity_t gun = {0}; #endif refEntity_t barrel = {0}; refEntity_t flash = {0}; vec3_t origin; int renderfx; vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; float len; float xx; float xscale; float yscale; #ifdef TA_WEAPSYS int i; vec3_t angles; #ifdef TURTLEARENA // PLAYERS char *newTagNames[3] = { "tag_hand_primary", "tag_hand_secondary", NULL }; #endif char *originalTagNames[3] = { "tag_weapon", "tag_flag", NULL }; #endif if ( !pi->legsModel || !pi->torsoModel || !pi->headModel #ifdef TA_PLAYERSYS || !pi->playercfg.animations[0].numFrames ) { #else || !pi->animations[0].numFrames ) { #endif return; } dp_realtime = time; if ( pi->pendingWeapon != WP_NUM_WEAPONS && dp_realtime > pi->weaponTimer ) { pi->weapon = pi->pendingWeapon; pi->lastWeapon = pi->pendingWeapon; pi->pendingWeapon = WP_NUM_WEAPONS; pi->weaponTimer = 0; #ifndef TA_WEAPSYS_EX if( pi->currentWeapon != pi->weapon ) { trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL ); } #endif } CG_AdjustFrom640( &x, &y, &w, &h ); y -= jumpHeight; memset( &refdef, 0, sizeof( refdef ) ); memset( &legs, 0, sizeof(legs) ); memset( &torso, 0, sizeof(torso) ); memset( &head, 0, sizeof(head) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; if ( ui_stretch.integer ) { xscale = cgs.screenXScaleStretch; yscale = cgs.screenYScaleStretch; } else { xscale = cgs.screenXScale; yscale = cgs.screenYScale; } refdef.fov_x = (int)((float)refdef.width / xscale / 640.0f * 90.0f); xx = refdef.width / xscale / tan( refdef.fov_x / 360 * M_PI ); refdef.fov_y = atan2( refdef.height / yscale, xx ); refdef.fov_y *= ( 360 / M_PI ); // calculate distance so the player nearly fills the box len = 0.7 * ( maxs[2] - mins[2] ); origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 ); origin[1] = 0.5 * ( mins[1] + maxs[1] ); origin[2] = -0.5 * ( mins[2] + maxs[2] ); refdef.time = dp_realtime; trap_R_ClearScene(); // get the rotation information UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis ); // get the animation state (after rotation, to allow feet shuffle) UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp, &torso.oldframe, &torso.frame, &torso.backlerp ); renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; // // add the legs // legs.hModel = pi->legsModel; legs.customSkin = CG_AddSkinToFrame( &pi->modelSkin ); VectorCopy( origin, legs.origin ); VectorCopy( origin, legs.lightingOrigin ); legs.renderfx = renderfx; VectorCopy (legs.origin, legs.oldorigin); Byte4Copy( pi->c1RGBA, legs.shaderRGBA ); CG_AddRefEntityWithMinLight( &legs ); if (!legs.hModel) { return; } // // add the torso // torso.hModel = pi->torsoModel; if (!torso.hModel) { return; } torso.customSkin = legs.customSkin; VectorCopy( origin, torso.lightingOrigin ); UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, NULL, "tag_torso"); torso.renderfx = renderfx; Byte4Copy( pi->c1RGBA, torso.shaderRGBA ); CG_AddRefEntityWithMinLight( &torso ); // // add the head // head.hModel = pi->headModel; if (!head.hModel) { return; } head.customSkin = legs.customSkin; VectorCopy( origin, head.lightingOrigin ); UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, NULL, "tag_head"); head.renderfx = renderfx; Byte4Copy( pi->c1RGBA, head.shaderRGBA ); CG_AddRefEntityWithMinLight( &head ); // // add the gun // if ( pi->currentWeapon != WP_NONE ) { #ifdef TA_WEAPSYS // get hands from cent for (i = 0; i < MAX_HANDS; i++) { memset( &gun[i], 0, sizeof(gun[i]) ); gun[i].hModel = pi->weaponModel[i]; VectorCopy( origin, gun[i].lightingOrigin ); gun[i].renderfx = renderfx; Byte4Copy( pi->c1RGBA, gun[i].shaderRGBA ); if (!originalTagNames[i] #ifdef TURTLEARENA // PLAYERS || !newTagNames[i] #endif ) { break; } if (!gun[i].hModel) { continue; } if ( #ifdef TURTLEARENA // PLAYERS !UI_PositionEntityOnTag( &gun[i], &torso, pi->torsoModel, NULL, newTagNames[i]) && #endif !UI_PositionEntityOnTag( &gun[i], &torso, pi->torsoModel, NULL, originalTagNames[i])) { // Failed to find tag continue; } CG_AddRefEntityWithMinLight( &gun[i] ); } #else memset( &gun, 0, sizeof(gun) ); gun.hModel = pi->weaponModel; Byte4Copy( pi->c1RGBA, gun.shaderRGBA ); VectorCopy( origin, gun.lightingOrigin ); UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, NULL, "tag_weapon"); gun.renderfx = renderfx; CG_AddRefEntityWithMinLight( &gun ); #endif } // // add the spinning barrel // #ifdef TA_WEAPSYS for (i = 0; i < MAX_HANDS; i++) #else if ( pi->barrelModel ) #endif { #ifdef TA_WEAPSYS if (!pi->barrelModel[i]) continue; #else vec3_t angles; #endif memset( &barrel, 0, sizeof(barrel) ); VectorCopy( origin, barrel.lightingOrigin ); barrel.renderfx = renderfx; #ifdef TA_WEAPSYS barrel.hModel = pi->barrelModel[i]; VectorClear(angles); if (bg_weapongroupinfo[pi->realWeapon].weapon[i]->barrelSpin != BS_NONE) { if (i & 1) angles[bg_weapongroupinfo[pi->realWeapon].weapon[i]->barrelSpin] = 360-UI_MachinegunSpinAngle( pi ); else angles[bg_weapongroupinfo[pi->realWeapon].weapon[i]->barrelSpin] = UI_MachinegunSpinAngle( pi ); } #else barrel.hModel = pi->barrelModel; angles[YAW] = 0; angles[PITCH] = 0; angles[ROLL] = UI_MachinegunSpinAngle( pi ); #endif AnglesToAxis( angles, barrel.axis ); #ifdef TA_WEAPSYS UI_PositionRotatedEntityOnTag( &barrel, &gun[i], pi->weaponModel[i], NULL, "tag_barrel"); #else UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, NULL, "tag_barrel"); #endif CG_AddRefEntityWithMinLight( &barrel ); } // // add muzzle flash // if ( dp_realtime <= pi->muzzleFlashTime ) { #ifdef TA_WEAPSYS vec3_t *flashDlightColor; for (i = 0; i < MAX_HANDS; i++) { memset( &flash, 0, sizeof(flash) ); flash.hModel = pi->flashModel[i]; flashDlightColor = &pi->flashDlightColor[i]; Byte4Copy( pi->c1RGBA, flash.shaderRGBA ); if (!flash.hModel) continue; VectorCopy( origin, flash.lightingOrigin ); UI_PositionEntityOnTag( &flash, &gun[i], pi->weaponModel[i], NULL, "tag_flash"); flash.renderfx = renderfx; trap_R_AddRefEntityToScene( &flash ); // make a dlight for the flash if ( *flashDlightColor[0] || *flashDlightColor[1] || *flashDlightColor[2] ) { trap_R_AddJuniorLightToScene( flash.origin, 200 + (rand()&31), 1.0f, *flashDlightColor[0], *flashDlightColor[1], *flashDlightColor[2] ); } } #else if ( pi->flashModel ) { memset( &flash, 0, sizeof(flash) ); flash.hModel = pi->flashModel; Byte4Copy( pi->c1RGBA, flash.shaderRGBA ); VectorCopy( origin, flash.lightingOrigin ); UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, NULL, "tag_flash"); flash.renderfx = renderfx; CG_AddRefEntityWithMinLight( &flash ); } // make a dlight for the flash if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { trap_R_AddJuniorLightToScene( flash.origin, 200 + (rand()&31), 1.0f, pi->flashDlightColor[0], pi->flashDlightColor[1], pi->flashDlightColor[2] ); } #endif } // // add the chat icon // if ( pi->chat ) { #ifdef TA_DATA // shaders UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/talkBalloon" ) ); #else UI_PlayerFloatSprite( pi, torso.origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) ); #endif } // // add an accent light // origin[0] -= 100; // + = behind, - = in front origin[1] += 100; // + = left, - = right origin[2] += 100; // + = above, - = below trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 1.0, 1.0 ); origin[0] -= 100; origin[1] -= 100; origin[2] -= 100; trap_R_AddJuniorLightToScene( origin, 500, 1.0, 1.0, 0.0, 0.0 ); trap_R_RenderScene( &refdef ); } /* ========================== UI_FileExists ========================== */ static qboolean UI_FileExists(const char *filename) { int len; len = trap_FS_FOpenFile( filename, NULL, FS_READ ); if (len>0) { return qtrue; } return qfalse; }