/* ===================== CG_DrawActive Perform all drawing needed to completely fill the screen ===================== */ void CG_DrawActive() { // optionally draw the info screen instead if ( !cg.snap ) { return; } // clear around the rendered view if sized down CG_TileClear(); CG_DrawBinaryShadersFinalPhases(); // draw 3D view trap_R_RenderScene( &cg.refdef ); // first person blend blobs, done after AnglesToAxis if ( !cg.renderingThirdPerson ) { CG_PainBlend(); } // draw status bar and other floating elements CG_Draw2D(); }
/* ============== CG_DrawSkyBoxPortal ============== */ void CG_DrawSkyBoxPortal( void ) { refdef_t backuprefdef; if ( !cg_skybox.integer || !cg.hasSkyPortal ) { return; } backuprefdef = cg.refdef; VectorCopy( cg.skyPortalOrigin, cg.refdef.vieworg ); if ( cg.skyPortalFogDepthForOpaque > 0 ) { cg.refdef.fogType = FT_LINEAR; cg.refdef.fogDensity = 1.0f; cg.refdef.fogDepthForOpaque = cg.skyPortalFogDepthForOpaque; cg.refdef.farClip = 0; } VectorCopy( cg.skyPortalFogColor, cg.refdef.fogColor ); cg.refdef.skyAlpha = cg.skyAlpha; cg.refdef.time = cg.time; if ( cg_skybox.integer == 2 ) { cg.refdef.rdflags |= RDF_ONLYSKY; } // draw the skybox trap_R_RenderScene( &cg.refdef ); cg.refdef = backuprefdef; cg.refdef.rdflags |= RDF_NOSKY; }
/* ===================== CG_DrawActive Perform all drawing needed to completely fill the screen ===================== */ void CG_DrawActive( stereoFrame_t stereoView ) { float separation; vec3_t baseOrg; // optionally draw the info screen instead if ( !cg.snap ) { return; } switch ( stereoView ) { case STEREO_CENTER: separation = 0; break; default: separation = 0; CG_Error( "CG_DrawActive: Undefined stereoView" ); } // clear around the rendered view if sized down CG_TileClear(); // offset vieworg appropriately if we're doing stereo separation VectorCopy( cg.refdef.vieworg, baseOrg ); if ( separation != 0 ) { VectorMA( cg.refdef.vieworg, -separation, cg.refdef.viewaxis[ 1 ], cg.refdef.vieworg ); } CG_DrawBinaryShadersFinalPhases(); // draw 3D view trap_R_RenderScene( &cg.refdef ); // restore original viewpoint if running stereo if ( separation != 0 ) { VectorCopy( baseOrg, cg.refdef.vieworg ); } // first person blend blobs, done after AnglesToAxis if ( !cg.renderingThirdPerson ) { CG_PainBlend(); } // draw status bar and other floating elements CG_Draw2D(); }
static JSBool sys_renderscene(JSContext *cx, unsigned argc, jsval *vp) { JSObject *obj; refdef_t refdef; memset(&refdef, 0, sizeof(refdef_t)); if (!JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "o", &obj)) return JS_FALSE; JS_Object_ParseRefDef(cx, obj, &refdef); trap_R_RenderScene(&refdef); return JS_TRUE; }
/* * CG_DrawModel */ static void CG_DrawModel( int x, int y, int align, int w, int h, struct model_s *model, struct shader_s *shader, vec3_t origin, vec3_t angles, bool outline ) { refdef_t refdef; entity_t entity; if( !model ) return; x = CG_HorizontalAlignForWidth( x, align, w ); y = CG_VerticalAlignForHeight( y, align, h ); memset( &refdef, 0, sizeof( refdef ) ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.fov_x = 30; refdef.fov_y = CalcFov( refdef.fov_x, w, h ); refdef.time = cg.time; refdef.rdflags = RDF_NOWORLDMODEL; Matrix3_Copy( axis_identity, refdef.viewaxis ); refdef.scissor_x = x; refdef.scissor_y = y; refdef.scissor_width = w; refdef.scissor_height = h; memset( &entity, 0, sizeof( entity ) ); entity.model = model; entity.customShader = shader; entity.scale = 1.0f; entity.renderfx = RF_FULLBRIGHT | RF_NOSHADOW | RF_FORCENOLOD; VectorCopy( origin, entity.origin ); VectorCopy( entity.origin, entity.origin2 ); AnglesToAxis( angles, entity.axis ); if( outline ) { entity.outlineHeight = DEFAULT_OUTLINE_HEIGHT; Vector4Set( entity.outlineRGBA, 0, 0, 0, 255 ); } trap_R_ClearScene(); CG_SetBoneposesForTemporaryEntity( &entity ); CG_AddEntityToScene( &entity ); trap_R_RenderScene( &refdef ); }
void CG_Draw3DModel( float x, float y, float w, float h, qhandle_t model, qhandle_t skin, vec3_t origin, vec3_t angles ) { refdef_t refdef; refEntity_t ent; if ( !cg_draw3dIcons.integer || !cg_drawIcons.integer ) { return; } CG_AdjustFrom640( &x, &y, &w, &h ); memset( &refdef, 0, sizeof( refdef ) ); memset( &ent, 0, sizeof( ent ) ); AnglesToAxis( angles, ent.axis ); VectorCopy( origin, ent.origin ); ent.hModel = model; ent.customSkin = skin; ent.renderfx = RF_NOSHADOW; // no stencil shadows refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); refdef.fov_x = 30; refdef.fov_y = 30; refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.time = cg.time; trap_R_ClearScene(); trap_R_AddRefEntityToScene( &ent ); trap_MME_TimeFraction(cg.timeFraction); trap_R_RenderScene( &refdef ); }
/* ================ CG_Draw3DModel ================ */ void CG_Draw3DModel( float x, float y, float w, float h, qhandle_t model, qhandle_t skin, vec3_t origin, vec3_t angles ) { refdef_t refdef; refEntity_t ent; CG_AdjustFrom640( &x, &y, &w, &h,qtrue); memset( &refdef, 0, sizeof( refdef ) ); memset( &ent, 0, sizeof( ent ) ); AnglesToAxis( angles, ent.axis ); VectorCopy( origin, ent.origin ); ent.hModel = model; ent.customSkin = skin; ent.renderfx = RF_NOSHADOW | RF_DEPTHHACK | RF_LIGHTING_ORIGIN; refdef.rdflags = RDF_NOWORLDMODEL; AxisClear(refdef.viewaxis); refdef.fov_x = 30; refdef.fov_y = 30; refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.time = cg.time; trap_R_ClearScene(); trap_R_AddRefEntityToScene(&ent); trap_R_RenderScene(&refdef); }
/* ============== CG_DrawSkyBoxPortal ============== */ void CG_DrawSkyBoxPortal( void ) { static float lastfov = 90; // for transitions back from zoomed in modes refdef_t backuprefdef; float fov_x; float fov_y; float x; char *cstr; char *token; float zoomFov; float f; static qboolean foginited = qfalse; // only set the portal fog values once if ( !( cstr = (char *)CG_ConfigString( CS_SKYBOXORG ) ) || !strlen( cstr ) ) { // no skybox in this map return; } // if they are waiting at the mission stats screen, show the stats if ( cg_gameType.integer == GT_SINGLE_PLAYER ) { if ( strlen( cg_missionStats.string ) > 1 ) { return; } } backuprefdef = cg.refdef; if ( cg_skybox.integer ) { token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" ); } cg.refdef.vieworg[0] = atof( token ); token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" ); } cg.refdef.vieworg[1] = atof( token ); token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" ); } cg.refdef.vieworg[2] = atof( token ); token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring\n" ); } fov_x = atoi( token ); if ( !fov_x ) { fov_x = 90; } // setup fog the first time, ignore this part of the configstring after that token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog state\n" ); } else { vec4_t fogColor; int fogStart, fogEnd; if ( atoi( token ) ) { // this camera has fog if ( 1 ) { token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog[0]\n" ); } fogColor[0] = atof( token ); token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog[1]\n" ); } fogColor[1] = atof( token ); token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { CG_Error( "CG_DrawSkyBoxPortal: error parsing skybox configstring. No fog[2]\n" ); } fogColor[2] = atof( token ); token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { fogStart = 0; } else { fogStart = atoi( token ); } token = COM_ParseExt( &cstr, qfalse ); if ( !token || !token[0] ) { fogEnd = 0; } else { fogEnd = atoi( token ); } trap_R_SetFog( FOG_PORTALVIEW, fogStart, fogEnd, fogColor[0], fogColor[1], fogColor[2], 1.1 ); foginited = qtrue; } } else { if ( !foginited ) { trap_R_SetFog( FOG_PORTALVIEW, 0,0,0,0,0,0 ); // init to null foginited = qtrue; } } } //----(SA) end if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { // if in intermission, use a fixed value fov_x = 90; } else { // user selectable if ( cgs.dmflags & DF_FIXED_FOV ) { // dmflag to prevent wide fov for all clients fov_x = 90; } else { fov_x = cg_fov.value; if ( fov_x < 1 ) { fov_x = 1; } else if ( fov_x > 160 ) { fov_x = 160; } } // account for zooms if ( cg.zoomval ) { zoomFov = cg.zoomval; // (SA) use user scrolled amount if ( zoomFov < 1 ) { zoomFov = 1; } else if ( zoomFov > 160 ) { zoomFov = 160; } } else { zoomFov = lastfov; } // do smooth transitions for the binocs if ( cg.zoomedBinoc ) { // binoc zooming in f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME; if ( f > 1.0 ) { fov_x = zoomFov; } else { fov_x = fov_x + f * ( zoomFov - fov_x ); } lastfov = fov_x; } else if ( cg.zoomval ) { // zoomed by sniper/snooper fov_x = cg.zoomval; lastfov = fov_x; } else { // binoc zooming out f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME; if ( f <= 1.0 ) { fov_x = zoomFov + f * ( fov_x - zoomFov ); } } } if ( cg.weaponSelect == WP_SNOOPERSCOPE ) { cg.refdef.rdflags |= RDF_SNOOPERVIEW; } else { cg.refdef.rdflags &= ~RDF_SNOOPERVIEW; } if ( cg.snap->ps.persistant[PERS_HWEAPON_USE] ) { fov_x = 55; } x = cg.refdef.width / tan( fov_x / 360 * M_PI ); fov_y = atan2( cg.refdef.height, x ); fov_y = fov_y * 360 / M_PI; cg.refdef.fov_x = fov_x; cg.refdef.fov_y = fov_y; cg.refdef.rdflags |= RDF_SKYBOXPORTAL; cg.refdef.rdflags |= RDF_DRAWSKYBOX; } else { // end if(cg_skybox.integer) cg.refdef.rdflags |= RDF_SKYBOXPORTAL; cg.refdef.rdflags &= ~RDF_DRAWSKYBOX; } cg.refdef.time = cg.time; // draw the skybox trap_R_RenderScene( &cg.refdef ); cg.refdef = backuprefdef; }
static void Main_MenuDraw( void ) { refdef_t refdef; //refEntity_t ent; //vec3_t origin; //vec3_t angles; float adjust; float x, y, w, h; vec4_t color = {1, 1, 1, 1}; int sy; // setup the refdef memset( &refdef, 0, sizeof( refdef ) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); x = 0; y = 0; w = 640; h = 120; UI_AdjustFrom640( &x, &y, &w, &h ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 ); refdef.fov_x = 60 + adjust; refdef.fov_y = 19.6875 + adjust; refdef.time = uis.realtime; //origin[0] = 300; //origin[1] = 0; //origin[2] = -32; trap_R_ClearScene(); #if 0 // add the model memset( &ent, 0, sizeof(ent) ); adjust = 5.0 * sin( (float)uis.realtime / 5000 ); VectorSet( angles, 0, 180 + adjust, 0 ); AnglesToAxis( angles, ent.axis ); ent.hModel = s_main.bannerModel; VectorCopy( origin, ent.origin ); VectorCopy( origin, ent.lightingOrigin ); ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; VectorCopy( ent.origin, ent.oldorigin ); //trap_R_AddRefEntityToScene( &ent ); #endif trap_R_RenderScene( &refdef ); //UI_DrawProportionalString( 320, 372, "DEMO FOR MATURE AUDIENCES DEMO", UI_CENTER|UI_SMALLFONT, color ); if (uis.showErrorMenu) { //UI_DrawProportionalString(0, 0, "You need to copy quakelive's baseq3 directory into ", UI_SMALLFONT, color); sy = 0; sy += 2 * SMALLCHAR_HEIGHT; UI_DrawString(0, sy, " Installation is incomplete.", UI_SMALLFONT, color); sy += 2 * SMALLCHAR_HEIGHT; UI_DrawString(0, sy, " You need to copy the files in quakelive's baseq3 directory", UI_SMALLFONT, color); sy += SMALLCHAR_HEIGHT; UI_DrawString(0, sy, " (the files ending with .pk3) into wolfcam's baseq3 directory.", UI_SMALLFONT, color); //return; } if (strlen(s_errorMessage.errorMessage)) { UI_DrawProportionalString_AutoWrapped( 320, 192, 600, 20, s_errorMessage.errorMessage, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); } else { // standard menu drawing Menu_Draw( &s_main.menu ); } #if 0 if (uis.demoversion) { UI_DrawProportionalString( 320, 372, "DEMO FOR MATURE AUDIENCES DEMO", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); } else { UI_DrawString( 320, 450, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); } #endif }
static void Main_MenuDraw( void ) { refdef_t refdef; refEntity_t ent; vec3_t origin; vec3_t angles; float adjust; float x, y, w, h; vec4_t color = {0.5, 0, 0, 1}; // setup the refdef memset( &refdef, 0, sizeof( refdef ) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); x = 0; y = 0; w = 640; h = 120; CG_AdjustFrom640( &x, &y, &w, &h ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 ); refdef.fov_x = 60 + adjust; refdef.fov_y = 19.6875 + adjust; refdef.time = uis.realtime; origin[0] = 300; origin[1] = 0; origin[2] = -32; trap_R_ClearScene(); // add the model memset( &ent, 0, sizeof(ent) ); adjust = 5.0 * sin( (float)uis.realtime / 5000 ); VectorSet( angles, 0, 180 + adjust, 0 ); AnglesToAxis( angles, ent.axis ); ent.hModel = s_main.bannerModel; VectorCopy( origin, ent.origin ); VectorCopy( origin, ent.lightingOrigin ); ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; VectorCopy( ent.origin, ent.oldorigin ); CG_AddRefEntityWithMinLight( &ent ); trap_R_RenderScene( &refdef ); if (strlen(s_errorMessage.errorMessage)) { UI_DrawProportionalString_AutoWrapped( 320, 192, 600, 20, s_errorMessage.errorMessage, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); } else { // standard menu drawing Menu_Draw( &s_main.menu ); } if (uis.demoversion) { UI_DrawProportionalString( 320, 372, "DEMO FOR MATURE AUDIENCES DEMO", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); } else if (uis.demotestversion) { UI_DrawProportionalString( 320, 372, "DEMOTEST FOR MATURE AUDIENCES DEMOTEST", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 428, "This test may only be distributed electronically. Physical media (e.g. CD-ROM's, floppies, etc.) redistribution of the demo test is prohibited. Refer to the End User License Agreement for further details.", UI_CENTER|UI_SMALLFONT, color ); } else { UI_DrawString( 320, 450, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); } }
/* =============== 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; } // 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; #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 / (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 ) { #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, newTagNames[i]) && #endif !UI_PositionEntityOnTag( &gun[i], &torso, pi->torsoModel, 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, "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[0]->barrelSpin != BS_NONE) { angles[bg_weapongroupinfo[pi->realWeapon].weapon[0]->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], "tag_barrel"); #else UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "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], "tag_flash"); flash.renderfx = renderfx; trap_R_AddRefEntityToScene( &flash ); // make a dlight for the flash if ( *flashDlightColor[0] || *flashDlightColor[1] || *flashDlightColor[2] ) { trap_R_AddLightToScene( 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, "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; }
/* =============== Main_MenuDraw =============== */ static void Main_MenuDraw( void ) { refdef_t refdef; refEntity_t ent; vec3_t origin; vec3_t angles; float adjust; float x, y, w, h; vec4_t color = {0.5, 0, 0, 1}; // setup the refdef memset( &refdef, 0, sizeof( refdef ) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); x = 0; y = 0; w = 640; h = 120; UI_AdjustFrom640( &x, &y, &w, &h ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 ); refdef.fov_x = 70 + adjust; refdef.fov_y = 19.6875 + adjust; refdef.time = uis.realtime; origin[0] = 300; origin[1] = 0; origin[2] = -32; trap_R_ClearScene(); // add the model memset( &ent, 0, sizeof(ent) ); adjust = 20.0 * sin( (float)uis.realtime / 3000 ); VectorSet( angles, 0, 180 + adjust, 0 ); AnglesToAxis( angles, ent.axis ); ent.hModel = s_main.bannerModel; VectorCopy( origin, ent.origin ); VectorCopy( origin, ent.lightingOrigin ); ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; VectorCopy( ent.origin, ent.oldorigin ); trap_R_AddRefEntityToScene( &ent ); // standard menu drawing Menu_Draw( &s_main.menu ); trap_R_RenderScene( &refdef ); /* if (uis.demoversion) { UI_DrawProportionalString( 320, 372, "DEMO FOR MATURE AUDIENCES DEMO", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); } else { UI_DrawString( 320, 450, "Quake III Arena(c) 1999-2000, Id Software, Inc. All Rights Reserved", UI_CENTER|UI_SMALLFONT, color ); }*/ }
/* =============== 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; } 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 / 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 ); }
void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_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 backpack = {0}; refEntity_t helmet = {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; vec4_t hcolor = { 1, 0, 0, 0.5 }; const char *torso_anim = NULL, *legs_anim = NULL; if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) { 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( trap_S_RegisterSound( "sound/weapons/change.wav" ), CHAN_LOCAL ); } } UI_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; refdef.fov_x = (int)((float)refdef.width / uiInfo.uiDC.xscale / 640.0f * 90.0f); xx = refdef.width / uiInfo.uiDC.xscale / tan( refdef.fov_x / 360 * M_PI ); refdef.fov_y = atan2( refdef.height / uiInfo.uiDC.yscale, xx ); refdef.fov_y *= ( 360 / M_PI ); // calculate distance so the player nearly fills the box len = 1.01 * ( maxs[2] - mins[2] ); // NERVE - SMF - changed from 0.7 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_SetColor( hcolor ); trap_R_ClearScene(); trap_R_SetColor( NULL ); // 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 body // legs.hModel = pi->legsModel; legs.customSkin = pi->legsSkin; legs.renderfx = renderfx; VectorCopy( origin, legs.origin ); VectorCopy( origin, legs.lightingOrigin ); VectorCopy( legs.origin, legs.oldorigin ); WM_getWeaponAnim( &torso_anim, &legs_anim ); if ( torso_anim ) { legs.torsoFrame = UI_GetAnimation( pi, torso_anim ); legs.oldTorsoFrame = UI_GetAnimation( pi, torso_anim ); } legs.torsoBacklerp = 0; //torso.backlerp; if ( legs_anim ) { legs.frame = UI_GetAnimation( pi, legs_anim ); legs.oldframe = UI_GetAnimation( pi, legs_anim ); } legs.backlerp = 0; memcpy( legs.torsoAxis, torso.axis, sizeof( torso.axis ) ); torso = legs; trap_R_AddRefEntityToScene( &torso ); // // add the head // head.hModel = pi->headModel; if ( !head.hModel ) { return; } head.customSkin = pi->headSkin; VectorCopy( origin, head.lightingOrigin ); UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head" ); head.renderfx = renderfx; trap_R_AddRefEntityToScene( &head ); // // add the gun // if ( pi->currentWeapon != WP_NONE ) { memset( &gun, 0, sizeof( gun ) ); gun.hModel = pi->weaponModel; VectorCopy( origin, gun.lightingOrigin ); UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon" ); gun.renderfx = renderfx; trap_R_AddRefEntityToScene( &gun ); } // // add muzzle flash // if ( dp_realtime <= pi->muzzleFlashTime ) { if ( pi->flashModel ) { memset( &flash, 0, sizeof( flash ) ); flash.hModel = pi->flashModel; VectorCopy( origin, flash.lightingOrigin ); UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash" ); flash.renderfx = renderfx; trap_R_AddRefEntityToScene( &flash ); } // make a dlight for the flash if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { trap_R_AddLightToScene( flash.origin, 200 + ( rand() & 31 ), pi->flashDlightColor[0], pi->flashDlightColor[1], pi->flashDlightColor[2], 0 ); } } // // add the backpack // if ( pi->backpackModel ) { memset( &backpack, 0, sizeof( backpack ) ); backpack.hModel = pi->backpackModel; VectorCopy( origin, backpack.lightingOrigin ); UI_PositionEntityOnTag( &backpack, &torso, pi->torsoModel, "tag_back" ); backpack.renderfx = renderfx; trap_R_AddRefEntityToScene( &backpack ); } // // add the helmet // if ( pi->helmetModel ) { memset( &helmet, 0, sizeof( helmet ) ); helmet.hModel = pi->helmetModel; VectorCopy( origin, helmet.lightingOrigin ); UI_PositionEntityOnTag( &helmet, &head, pi->headModel, "tag_mouth" ); helmet.renderfx = renderfx; trap_R_AddRefEntityToScene( &helmet ); } // // add the chat icon // if ( pi->chat ) { UI_PlayerFloatSprite( pi, 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_AddLightToScene( origin, 500, 1.0, 1.0, 1.0, 0 ); origin[0] -= 100; origin[1] -= 100; origin[2] -= 100; trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0, 0 ); trap_R_RenderScene( &refdef ); }
/* * UI_DrawPlayer */ void UI_DrawPlayer(float x, float y, float w, float h, Playerinfo *pi, int time) { Refdef refdef; Refent legs; Refent torso; Refent head; Refent gun; Refent barrel; Refent flash; Vec3 origin; int renderfx; Vec3 mins = {-16, -16, -24}; Vec3 maxs = {16, 16, 32}; float len; float xx; if(!pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames) return; dp_realtime = time; if(pi->pendingWeapon != -1 && dp_realtime > pi->weaponTimer){ pi->weapon = pi->pendingWeapon; pi->lastWeapon = pi->pendingWeapon; pi->pendingWeapon = -1; pi->weaponTimer = 0; if(pi->currentWeapon != pi->weapon) trap_sndstartlocalsound(weaponChangeSound, CHAN_LOCAL); } UI_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; clearaxis(refdef.viewaxis); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f); xx = refdef.width / tan(refdef.fov_x / 360 * M_PI); refdef.fov_y = atan2(refdef.height, 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 = pi->legsSkin; copyv3(origin, legs.origin); copyv3(origin, legs.lightingOrigin); legs.renderfx = renderfx; copyv3 (legs.origin, legs.oldorigin); trap_R_AddRefEntityToScene(&legs); if(!legs.hModel) return; /* * add the torso * */ torso.hModel = pi->torsoModel; if(!torso.hModel) return; torso.customSkin = pi->torsoSkin; copyv3(origin, torso.lightingOrigin); UI_PositionRotatedEntityOnTag(&torso, &legs, pi->legsModel, "tag_torso"); torso.renderfx = renderfx; trap_R_AddRefEntityToScene(&torso); /* * add the head * */ head.hModel = pi->headModel; if(!head.hModel) return; head.customSkin = pi->headSkin; copyv3(origin, head.lightingOrigin); UI_PositionRotatedEntityOnTag(&head, &torso, pi->torsoModel, "tag_head"); head.renderfx = renderfx; trap_R_AddRefEntityToScene(&head); /* * add the gun * */ if(pi->currentWeapon != Wnone){ memset(&gun, 0, sizeof(gun)); gun.hModel = pi->weaponModel; if(pi->currentWeapon == Wrailgun) byte4copy(pi->c1RGBA, gun.shaderRGBA); else byte4copy(colorWhite, gun.shaderRGBA); copyv3(origin, gun.lightingOrigin); UI_PositionEntityOnTag(&gun, &torso, pi->torsoModel, "tag_weapon"); gun.renderfx = renderfx; trap_R_AddRefEntityToScene(&gun); } /* * add the spinning barrel * */ if(pi->realWeapon == Wmachinegun || pi->realWeapon == Wmelee){ Vec3 angles; memset(&barrel, 0, sizeof(barrel)); copyv3(origin, barrel.lightingOrigin); barrel.renderfx = renderfx; barrel.hModel = pi->barrelModel; angles[YAW] = 0; angles[PITCH] = 0; angles[ROLL] = UI_MachinegunSpinAngle(pi); if(pi->realWeapon == Wmelee){ angles[PITCH] = angles[ROLL]; angles[ROLL] = 0; } eulertoaxis(angles, barrel.axis); UI_PositionRotatedEntityOnTag(&barrel, &gun, pi->weaponModel, "tag_barrel"); trap_R_AddRefEntityToScene(&barrel); } /* * add muzzle flash * */ if(dp_realtime <= pi->muzzleFlashTime){ if(pi->flashModel){ memset(&flash, 0, sizeof(flash)); flash.hModel = pi->flashModel; if(pi->currentWeapon == Wrailgun) byte4copy(pi->c1RGBA, flash.shaderRGBA); else byte4copy(colorWhite, flash.shaderRGBA); copyv3(origin, flash.lightingOrigin); UI_PositionEntityOnTag(&flash, &gun, pi->weaponModel, "tag_flash"); flash.renderfx = renderfx; trap_R_AddRefEntityToScene(&flash); } /* make a dlight for the flash */ if(pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2]) trap_R_AddLightToScene(flash.origin, 200 + (rand()&31), pi->flashDlightColor[0], pi->flashDlightColor[1], pi->flashDlightColor[2]); } /* * add the chat icon * */ if(pi->chat) UI_PlayerFloatSprite(pi, origin, trap_R_RegisterShaderNoMip("sprites/balloon4")); /* * add an accent light * */ origin[0] -= 100; /* + = behind, - = in front */ origin[1] += 100; /* + = left, - = right */ origin[2] += 100; /* + = above, - = below */ trap_R_AddLightToScene(origin, 500, 1.0, 1.0, 1.0); origin[0] -= 100; origin[1] -= 100; origin[2] -= 100; trap_R_AddLightToScene(origin, 500, 1.0, 0.0, 0.0); trap_R_RenderScene(&refdef); }
void CG_DemosDrawActiveFrame( int serverTime, stereoFrame_t stereoView ) { int deltaTime; qboolean hadSkip; qboolean captureFrame; float captureFPS; float frameSpeed; int blurTotal, blurIndex; float blurFraction; float stereoSep = CG_Cvar_Get( "r_stereoSeparation" ); int inwater, entityNum; if (!demo.initDone) { if ( !cg.snap ) { demoProcessSnapShots( qtrue ); } if ( !cg.snap ) { CG_Error( "No Initial demo snapshot found" ); } demoPlaybackInit(); } cg.demoPlayback = 2; // update cvars CG_UpdateCvars(); // if we are only updating the screen as a loading // pacifier, don't even try to read snapshots if ( cg.loading ) { CG_DrawInformation(); return; } captureFrame = demo.capture.active && !demo.play.paused; if ( captureFrame ) { trap_MME_BlurInfo( &blurTotal, &blurIndex ); captureFPS = mov_captureFPS.value; if ( blurTotal > 0) { captureFPS *= blurTotal; blurFraction = blurIndex / (float)blurTotal; } else { blurFraction = 0; } } else { } /* Forward the demo */ deltaTime = serverTime - demo.serverTime; if (deltaTime > 50) deltaTime = 50; demo.serverTime = serverTime; demo.serverDeltaTime = 0.001 * deltaTime; cg.oldTime = cg.time; cg.oldTimeFraction = cg.timeFraction; if (demo.play.time < 0) { demo.play.time = demo.play.fraction = 0; } demo.play.oldTime = demo.play.time; /* Handle the music */ if ( demo.play.paused ) { if ( lastMusicStart >= 0) demoSynchMusic( -1, 0 ); } else { int musicStart = (demo.play.time - mov_musicStart.value * 1000 ); if ( musicStart <= 0 ) { if (lastMusicStart >= 0 ) demoSynchMusic( -1, 0 ); } else { if ( demo.play.time != demo.play.lastTime || lastMusicStart < 0) demoSynchMusic( musicStart, 0 ); } } /* forward the time a bit till the moment of capture */ if ( captureFrame && demo.capture.locked && demo.play.time < demo.capture.start ) { int left = demo.capture.start - demo.play.time; if ( left > 2000) { left -= 1000; captureFrame = qfalse; } else if (left > 5) { captureFrame = qfalse; left = 5; } demo.play.time += left; } else if ( captureFrame && demo.loop.total && blurTotal ) { float loopFraction = demo.loop.index / (float)demo.loop.total; demo.play.time = demo.loop.start; demo.play.fraction = demo.loop.range * loopFraction; demo.play.time += (int)demo.play.fraction; demo.play.fraction -= (int)demo.play.fraction; } else if (captureFrame) { float frameDelay = 1000.0f / captureFPS; demo.play.fraction += frameDelay * demo.play.speed; demo.play.time += (int)demo.play.fraction; demo.play.fraction -= (int)demo.play.fraction; } else if ( demo.find ) { demo.play.time = demo.play.oldTime + 20; demo.play.fraction = 0; if ( demo.play.paused ) demo.find = findNone; } else if (!demo.play.paused) { float delta = demo.play.fraction + deltaTime * demo.play.speed; demo.play.time += (int)delta; demo.play.fraction = delta - (int)delta; } demo.play.lastTime = demo.play.time; if ( demo.loop.total && captureFrame && blurTotal ) { //Delay till we hit the right part at the start int time; float timeFraction; if ( demo.loop.lineDelay && !blurIndex ) { time = demo.loop.start - demo.loop.lineDelay; timeFraction = 0; if ( demo.loop.lineDelay > 8 ) demo.loop.lineDelay -= 8; else demo.loop.lineDelay = 0; captureFrame = qfalse; } else { if ( blurIndex == blurTotal - 1 ) { //We'll restart back to the start again demo.loop.lineDelay = 2000; if ( ++demo.loop.index >= demo.loop.total ) { demo.loop.total = 0; } } time = demo.loop.start; timeFraction = demo.loop.range * blurFraction; } time += (int)timeFraction; timeFraction -= (int)timeFraction; lineAt( time, timeFraction, &demo.line.time, &cg.timeFraction, &frameSpeed ); } else { lineAt( demo.play.time, demo.play.fraction, &demo.line.time, &cg.timeFraction, &frameSpeed ); } /* Set the correct time */ cg.time = trap_MME_SeekTime( demo.line.time ); /* cg.time is shifted ahead a bit to correct some issues.. */ frameSpeed *= demo.play.speed; cg.frametime = (cg.time - cg.oldTime) + (cg.timeFraction - cg.oldTimeFraction); if (cg.frametime < 0) { int i; cg.frametime = 0; hadSkip = qtrue; cg.oldTime = cg.time; cg.oldTimeFraction = cg.timeFraction; CG_InitLocalEntities(); CG_InitMarkPolys(); CG_ClearParticles (); trap_FX_Reset( ); trap_R_DecalReset(); cg.centerPrintTime = 0; cg.damageTime = 0; cg.powerupTime = 0; cg.rewardTime = 0; cg.scoreFadeTime = 0; cg.lastKillTime = 0; cg.attackerTime = 0; cg.soundTime = 0; cg.itemPickupTime = 0; cg.itemPickupBlendTime = 0; cg.weaponSelectTime = 0; cg.headEndTime = 0; cg.headStartTime = 0; cg.v_dmg_time = 0; cg.rewardCount[0] = 0; cg.rewardStack = 0; cg.rewardTime = 0; trap_S_ClearLoopingSounds(qtrue); for (i = 0; i < MAX_CHATBOX_ITEMS; i++) cg.chatItems[i].time = 0; } else if (cg.frametime > 100) { hadSkip = qtrue; } else { hadSkip = qfalse; } /* Make sure the random seed is the same each time we hit this frame */ srand( (cg.time % 10000000) + cg.timeFraction * 1000); /* Prepare to render the screen */ trap_S_ClearLoopingSounds(qfalse); trap_R_ClearScene(); /* Update demo related information */ trap_SetUserCmdValue( cg.weaponSelect, 1 ); demoProcessSnapShots( hadSkip ); if ( !cg.snap ) { CG_DrawInformation(); return; } CG_PreparePacketEntities( ); CG_DemosUpdatePlayer( ); chaseUpdate( demo.play.time, demo.play.fraction ); cameraUpdate( demo.play.time, demo.play.fraction ); dofUpdate( demo.play.time, demo.play.fraction ); demoEffectUpdate( demo.play.time, demo.play.fraction ); cg.clientFrame++; // update cg.predictedPlayerState CG_InterpolatePlayerState( qfalse ); BG_PlayerStateToEntityState( &cg.predictedPlayerState, &cg.predictedPlayerEntity.currentState, qfalse ); if ( cg.cpma.detected ) { if ( cg.predictedPlayerState.pm_type >= 4 ) cg.predictedPlayerEntity.currentState.eType = ET_INVISIBLE; } cg.predictedPlayerEntity.currentValid = qtrue; VectorCopy( cg.predictedPlayerEntity.currentState.pos.trBase, cg.predictedPlayerEntity.lerpOrigin ); VectorCopy( cg.predictedPlayerEntity.currentState.apos.trBase, cg.predictedPlayerEntity.lerpAngles ); inwater = demoSetupView(); CG_TileClear(); trap_FX_Begin( cg.time, cg.timeFraction ); scriptRun( hadSkip ); CG_AddPacketEntities(); CG_AddMarks(); CG_AddParticles (); CG_AddLocalEntities(); if ( cg.playerCent == &cg.predictedPlayerEntity ) { // warning sounds when powerup is wearing off CG_PowerupTimerSounds(); CG_AddViewWeapon( &cg.predictedPlayerState ); } else if ( cg.playerCent && cg.playerCent->currentState.number < MAX_CLIENTS ) { CG_AddViewWeaponDirect( cg.playerCent ); } trap_S_UpdateEntityPosition(ENTITYNUM_NONE, cg.refdef.vieworg); CG_PlayBufferedSounds(); CG_PlayBufferedVoiceChats(); cg.refdef.time = cg.time; memcpy( cg.refdef.areamask, cg.snap->areamask, sizeof( cg.refdef.areamask ) ); /* Render some extra demo related stuff */ if (!captureFrame) { switch (demo.editType) { case editCamera: cameraDraw( demo.play.time, demo.play.fraction ); break; case editChase: chaseDraw( demo.play.time, demo.play.fraction ); break; case editDof: dofDraw( demo.play.time, demo.play.fraction ); break; case editEffect: demoEffectDraw( demo.play.time, demo.play.fraction ); break; } /* Add bounding boxes for easy aiming */ if ( demo.editType && ( demo.cmd.buttons & BUTTON_ATTACK) && ( demo.cmd.buttons & BUTTON_AFFIRMATIVE) ) { int i; centity_t *targetCent; for (i = 0;i<MAX_GENTITIES;i++) { targetCent = demoTargetEntity( i ); if (targetCent) { vec3_t container, traceStart, traceImpact, forward; const float *color; demoCentityBoxSize( targetCent, container ); VectorSubtract( demo.viewOrigin, targetCent->lerpOrigin, traceStart ); AngleVectors( demo.viewAngles, forward, 0, 0 ); if (BoxTraceImpact( traceStart, forward, container, traceImpact )) { color = colorRed; } else { color = colorYellow; } demoDrawBox( targetCent->lerpOrigin, container, color ); } } } if ( mov_gridStep.value > 0 && mov_gridRange.value > 0) { vec4_t color; vec3_t offset; qhandle_t shader = trap_R_RegisterShader( "mme/gridline" ); color[0] = color[1] = color[2] = 1; color[3] = 0; offset[0] = offset[1] = offset[2] = 0; Q_parseColor( mov_gridColor.string, ospColors, color ); demoDrawGrid( demo.viewOrigin, color, offset, mov_gridWidth.value, mov_gridStep.value, mov_gridRange.value, shader ); } } if (frameSpeed > 5) frameSpeed = 5; trap_S_UpdateScale( frameSpeed ); if (cg.playerCent && cg.predictedPlayerState.pm_type == PM_INTERMISSION) { entityNum = cg.snap->ps.clientNum; } else if (cg.playerCent) { entityNum = cg.playerCent->currentState.number; } else { entityNum = ENTITYNUM_NONE; } trap_S_Respatialize( entityNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater); trap_FX_End(); if (captureFrame && stereoSep > 0.0f) trap_Cvar_Set("r_stereoSeparation", va("%f", -stereoSep)); trap_MME_TimeFraction(cg.timeFraction); trap_R_RenderScene( &cg.refdef ); if ( demo.viewType == viewChase && cg.playerCent && ( cg.playerCent->currentState.number < MAX_CLIENTS ) ) CG_Draw2D(); // CG_DrawSmallString( 0, 0, va( "height %d", cg.playerCent->pe.viewHeight ), 1 ); if (captureFrame) { char fileName[MAX_OSPATH]; Com_sprintf( fileName, sizeof( fileName ), "capture/%s/%s", mme_demoFileName.string, mov_captureName.string ); trap_MME_Capture( fileName, captureFPS, demo.viewFocus, demo.viewRadius ); if ( mov_captureCamera.integer ) demoAddViewPos( fileName, demo.viewOrigin, demo.viewAngles, demo.viewFov ); } else { if (demo.editType && !cg.playerCent) demoDrawCrosshair(); hudDraw(); if (demo.editType) { demoDrawProgress(trap_MME_ProgressTime()); } } //checkCaptureEnd: if ( demo.capture.active && demo.capture.locked && demo.play.time > demo.capture.end ) { Com_Printf( "Capturing ended\n" ); if (demo.autoLoad) { trap_SendConsoleCommand( "disconnect\n" ); } demo.capture.active = qfalse; } }
static void Main_MenuDraw( void ) { refdef_t refdef; refEntity_t ent; vec3_t origin; vec3_t angles; float adjust; float x, y, w, h; vec4_t color = {0.2, 0.2, 1.0, 1}; // setup the refdef memset( &refdef, 0, sizeof( refdef ) ); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear( refdef.viewaxis ); x = 0; y = 0; w = 640; h = 120; UI_AdjustFrom640( &x, &y, &w, &h ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 ); refdef.fov_x = 60 + adjust; refdef.fov_y = 19.6875 + adjust; refdef.time = uis.realtime; origin[0] = 300; origin[1] = 0; origin[2] = -32; trap_R_ClearScene(); // add the model memset( &ent, 0, sizeof(ent) ); adjust = 5.0 * sin( (float)uis.realtime / 5000 ); VectorSet( angles, 0, 180 + adjust, 0 ); AnglesToAxis( angles, ent.axis ); ent.hModel = s_main.bannerModel; VectorCopy( origin, ent.origin ); VectorCopy( origin, ent.lightingOrigin ); ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; VectorCopy( ent.origin, ent.oldorigin ); trap_R_AddRefEntityToScene( &ent ); trap_R_RenderScene( &refdef ); if (strlen(s_errorMessage.errorMessage)) { UI_DrawProportionalString_AutoWrapped( 320, 192, 600, 20, s_errorMessage.errorMessage, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); } else { // standard menu drawing Menu_Draw( &s_main.menu ); } UI_DrawProportionalString( 320, 372, "", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 400, "OpenArena(c) 2005-2018 OpenArena Team", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 414, "OpenArena comes with ABSOLUTELY NO WARRANTY; this is free software", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 428, "and you are welcome to redistribute it under certain conditions;", UI_CENTER|UI_SMALLFONT, color ); UI_DrawString( 320, 444, "read COPYING for details.", UI_CENTER|UI_SMALLFONT, color ); //Draw version. UI_DrawString( 640-40, 480-14, "^7" OA_VERSION, UI_SMALLFONT, color ); if ((int)trap_Cvar_VariableValue("protocol")!=OA_STD_PROTOCOL) { UI_DrawString( 0, 480-14, va("^7Protocol: %i",(int)trap_Cvar_VariableValue("protocol")), UI_SMALLFONT, color); } }
static void Main_MenuDraw(void) { refdef_t refdef; refEntity_t ent; vec3_t origin; vec3_t angles; float adjust; float x, y, w, h; vec4_t color; qboolean connected = qtrue; vec4_t oldColor = {0.8, 0.8, 0.8, 1}; // FIXME dont call on every update... s_main.servers = (int) trap_Cvar_VariableValue("ma_servers"); s_main.players = (int) trap_Cvar_VariableValue("ma_players"); s_main.motd = UI_Cvar_VariableString("ma_motd"); if (!s_main.motd || !Q_stricmp(s_main.motd, "")) { s_main.motd = "Failed to connect to master server"; connected = qfalse; } // options the refdef memset(&refdef, 0, sizeof ( refdef)); refdef.rdflags = RDF_NOWORLDMODEL; AxisClear(refdef.viewaxis); x = 0; y = 0; w = 640; h = 120; UI_AdjustFrom640(&x, &y, &w, &h); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 ); refdef.fov_x = 60 + adjust; refdef.fov_y = 19.6875 + adjust; refdef.time = uis.realtime; origin[0] = 300; origin[1] = 0; origin[2] = -32; trap_R_ClearScene(); // add the model memset(&ent, 0, sizeof (ent)); /*adjust = 5.0 * sin((float) uis.realtime / 5000); VectorSet(angles, 0, 180 + adjust, 0); AnglesToAxis(angles, ent.axis); ent.hModel = s_main.bannerModel; VectorCopy(origin, ent.origin); VectorCopy(origin, ent.lightingOrigin); ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW; VectorCopy(ent.origin, ent.oldorigin);*/ x = 0; y = 0; w = 640; h = 64; UI_FillRect(x, y, w, h, color_black); x = 16; y = 16; UI_DrawString(x, y, "Hazewood", UI_LEFT, color_green); x = 196; y = 28; if (connected) { UI_DrawString(x, y, va("%s", s_main.motd), UI_LEFT | UI_SMALLERFONT, color_white); } else { UI_DrawString(x, y, va("%s", s_main.motd), UI_LEFT | UI_SMALLERFONT, color_red); } x = 640 - 196 + 48; y = 12; if (s_main.servers > 0) { UI_DrawString(x, y, va("%i Servers", s_main.servers), UI_LEFT | UI_SMALLFONT, color_blue); } else { UI_DrawString(x, y, va("%i Servers", s_main.servers), UI_LEFT | UI_SMALLFONT, color_red); } y = 36; if (s_main.players > 0) { UI_DrawString(x, y, va("%i Players", s_main.players), UI_LEFT | UI_SMALLFONT, color_blue); } else { UI_DrawString(x, y, va("%i Players", s_main.players), UI_LEFT | UI_SMALLFONT, color_red); } x = 0; y = 480 - 64; w = 640; h = 64; UI_FillRect(x, y, w, h, color_black); x = 0; y = 64; w = 640; h = 480 - 128; if (!s_main.up) { s_main.fade -= ((float) uis.frametime) / 10.0f; } else { s_main.fade += ((float) uis.frametime) / 10.0f; } if (s_main.fade >= 1200.0f) { s_main.up = qfalse; s_main.currentScene++; if (s_main.currentScene >= MAX_MENU_SCENES) { s_main.currentScene = 0; } } if (s_main.fade <= -100.0f) { s_main.up = qtrue; } Vector4Copy(oldColor, color); UI_DrawHandlePic(x, y, w, h, trap_R_RegisterShaderNoMip(va("gfx/scenes/%i", s_main.currentScene))); color[3] = s_main.fade / 1000.0f; if (color[3] > 1) { color[3] = 1; } if (color[3] < 0) { color[3] = 0; } trap_R_SetColor(color); UI_DrawNamedPic(x, y, w, h, "gfx/colors/blue.jpg"); trap_R_SetColor(oldColor); trap_R_AddRefEntityToScene(&ent); trap_R_RenderScene(&refdef); if (strlen(s_errorMessage.errorMessage)) { UI_DrawProportionalString_AutoWrapped(320, 192, 600, 20, s_errorMessage.errorMessage, UI_CENTER | UI_SMALLFONT | UI_DROPSHADOW, menu_text_color); } else { Menu_Draw(&s_main.menu); } }
/* =============== UI_DrawPlayer =============== */ void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ) { refdef_t refdef; refEntity_t legs; refEntity_t torso; refEntity_t head; refEntity_t gun; refEntity_t flash; vec3_t origin; int renderfx; vec3_t mins = {-16, -16, -24}; vec3_t maxs = {16, 16, 32}; float len; float xx; 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 != -1 && dp_realtime > pi->weaponTimer ) { pi->weapon = pi->pendingWeapon; pi->lastWeapon = pi->pendingWeapon; pi->pendingWeapon = -1; pi->weaponTimer = 0; if( pi->currentWeapon != pi->weapon ) { trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL ); } } UI_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; refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f); xx = refdef.width / tan( refdef.fov_x / 360 * M_PI ); refdef.fov_y = atan2( refdef.height, xx ); refdef.fov_y *= ( 360 / (float)M_PI ); // calculate distance so the player nearly fills the box len = 0.72 * ( 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 = pi->legsSkin; VectorCopy( origin, legs.origin ); VectorCopy( origin, legs.lightingOrigin ); legs.renderfx = renderfx; VectorCopy (legs.origin, legs.oldorigin); trap_R_AddRefEntityToScene( &legs ); if (!legs.hModel) { return; } // // add the torso // torso.hModel = pi->torsoModel; if (!torso.hModel) { return; } torso.customSkin = pi->torsoSkin; VectorCopy( origin, torso.lightingOrigin ); UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso"); torso.renderfx = renderfx; trap_R_AddRefEntityToScene( &torso ); // // add the head // head.hModel = pi->headModel; if (!head.hModel) { return; } head.customSkin = pi->headSkin; VectorCopy( origin, head.lightingOrigin ); UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head"); head.renderfx = renderfx; trap_R_AddRefEntityToScene( &head ); // // add the gun // if ( pi->currentWeapon != WP_NONE ) { memset( &gun, 0, sizeof(gun) ); gun.hModel = pi->weaponModel; VectorCopy( origin, gun.lightingOrigin ); UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon"); gun.renderfx = renderfx; trap_R_AddRefEntityToScene( &gun ); } // // add the spinning barrel // // // add muzzle flash // if ( dp_realtime <= pi->muzzleFlashTime ) { if ( pi->flashModel ) { memset( &flash, 0, sizeof(flash) ); flash.hModel = pi->flashModel; VectorCopy( origin, flash.lightingOrigin ); UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash"); flash.renderfx = renderfx; trap_R_AddRefEntityToScene( &flash ); } // make a dlight for the flash if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) { trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), pi->flashDlightColor[0], pi->flashDlightColor[1], pi->flashDlightColor[2] ); } } // // add the chat icon // if ( pi->chat ) { UI_PlayerFloatSprite( pi, 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_AddLightToScene( origin, 500, 1.0, 1.0, 1.0 ); origin[0] -= 100; origin[1] -= 100; origin[2] -= 100; trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0 ); trap_R_RenderScene( &refdef ); }
void CG_RenderView( float frameTime, float realFrameTime, int realTime, unsigned int serverTime, float stereo_separation, unsigned int extrapolationTime, bool flipped ) { refdef_t *rd = &cg.view.refdef; // update time cg.realTime = realTime; cg.frameTime = frameTime; cg.realFrameTime = realFrameTime; cg.frameCount++; cg.time = serverTime; if( !cgs.precacheDone || !cg.frame.valid ) { CG_Precache(); CG_DrawLoading(); return; } { float snapTime = ( cg.frame.serverTime - cg.oldFrame.serverTime ); if( !snapTime ) snapTime = cgs.snapFrameTime; // moved this from CG_Init here cgs.extrapolationTime = extrapolationTime; if( cg.oldFrame.serverTime == cg.frame.serverTime ) cg.lerpfrac = 1.0f; else cg.lerpfrac = ( (double)( cg.time - cgs.extrapolationTime ) - (double)cg.oldFrame.serverTime ) / (double)snapTime; if( cgs.extrapolationTime ) { cg.xerpTime = 0.001f * ( (double)cg.time - (double)cg.frame.serverTime ); cg.oldXerpTime = 0.001f * ( (double)cg.time - (double)cg.oldFrame.serverTime ); if( cg.time >= cg.frame.serverTime ) { cg.xerpSmoothFrac = (double)( cg.time - cg.frame.serverTime ) / (double)( cgs.extrapolationTime ); clamp( cg.xerpSmoothFrac, 0.0f, 1.0f ); } else { cg.xerpSmoothFrac = (double)( cg.frame.serverTime - cg.time ) / (double)( cgs.extrapolationTime ); clamp( cg.xerpSmoothFrac, -1.0f, 0.0f ); cg.xerpSmoothFrac = 1.0f - cg.xerpSmoothFrac; } clamp_low( cg.xerpTime, -( cgs.extrapolationTime * 0.001f ) ); //clamp( cg.xerpTime, -( cgs.extrapolationTime * 0.001f ), ( cgs.extrapolationTime * 0.001f ) ); //clamp( cg.oldXerpTime, 0, ( ( snapTime + cgs.extrapolationTime ) * 0.001f ) ); } else { cg.xerpTime = 0.0f; cg.xerpSmoothFrac = 0.0f; } } if( cg_showClamp->integer ) { if( cg.lerpfrac > 1.0f ) CG_Printf( "high clamp %f\n", cg.lerpfrac ); else if( cg.lerpfrac < 0.0f ) CG_Printf( "low clamp %f\n", cg.lerpfrac ); } clamp( cg.lerpfrac, 0.0f, 1.0f ); if( !cgs.configStrings[CS_WORLDMODEL][0] ) { CG_AddLocalSounds(); trap_R_DrawStretchPic( 0, 0, cgs.vidWidth, cgs.vidHeight, 0, 0, 1, 1, colorBlack, cgs.shaderWhite ); trap_S_Update( vec3_origin, vec3_origin, axis_identity, cgs.clientInfo[cgs.playerNum].name ); return; } // bring up the game menu after reconnecting if( !cgs.tv && !cgs.demoPlaying ) { if( ISREALSPECTATOR() && !cg.firstFrame ) { if( !cgs.gameMenuRequested ) { trap_Cmd_ExecuteText( EXEC_NOW, "gamemenu\n" ); } cgs.gameMenuRequested = true; } } if( !cg.viewFrameCount ) cg.firstViewRealTime = cg.realTime; CG_FlashGameWindow(); // notify player of important game events CG_CalcVrect(); // find sizes of the 3d drawing screen CG_TileClear(); // clear any dirty part of the background CG_ChaseCamButtons(); CG_RunLightStyles(); CG_ClearFragmentedDecals(); trap_R_ClearScene(); if( CG_DemoCam_Update() ) CG_SetupViewDef( &cg.view, CG_DemoCam_GetViewType(), flipped ); else CG_SetupViewDef( &cg.view, VIEWDEF_PLAYERVIEW, flipped ); CG_LerpEntities(); // interpolate packet entities positions CG_CalcViewWeapon( &cg.weapon ); CG_FireEvents( false ); CG_AddEntities(); CG_AddViewWeapon( &cg.weapon ); CG_AddLocalEntities(); CG_AddParticles(); CG_AddDlights(); CG_AddShadeBoxes(); CG_AddDecals(); CG_AddPolys(); CG_AddLightStyles(); #ifndef PUBLIC_BUILD CG_AddTest(); #endif // offset vieworg appropriately if we're doing stereo separation VectorMA( cg.view.origin, stereo_separation, &cg.view.axis[AXIS_RIGHT], rd->vieworg ); // never let it sit exactly on a node line, because a water plane can // disappear when viewed with the eye exactly on it. // the server protocol only specifies to 1/16 pixel, so add 1/16 in each axis rd->vieworg[0] += 1.0/PM_VECTOR_SNAP; rd->vieworg[1] += 1.0/PM_VECTOR_SNAP; rd->vieworg[2] += 1.0/PM_VECTOR_SNAP; AnglesToAxis( cg.view.angles, rd->viewaxis ); rd->rdflags = CG_RenderFlags(); // warp if underwater if( rd->rdflags & RDF_UNDERWATER ) { float phase = rd->time * 0.001 * WAVE_FREQUENCY * M_TWOPI; float v = WAVE_AMPLITUDE * ( sin( phase ) - 1.0 ) + 1; rd->fov_x *= v; rd->fov_y *= v; } CG_AddLocalSounds(); CG_SetSceneTeamColors(); // update the team colors in the renderer trap_R_RenderScene( &cg.view.refdef ); cg.oldAreabits = true; trap_S_Update( cg.view.origin, cg.view.velocity, cg.view.axis, cgs.clientInfo[cgs.playerNum].name ); CG_Draw2D(); CG_ResetTemporaryBoneposesCache(); // clear for next frame cg.viewFrameCount++; }