void BlackBox_Record( const char *type, const char *pFormat, ... ) { static ConVarRef blackbox( "blackbox" ); if ( IsX360() ) return; if ( !blackbox.IsValid() || !blackbox.GetBool() ) return; int type_num; for ( type_num = 0; type_num < blackboxrecorder->GetTypeCount(); type_num++ ) { if ( !V_strcasecmp( blackboxrecorder->GetTypeName( type_num ), type ) ) break; } if ( type_num >= blackboxrecorder->GetTypeCount() ) { Msg( "Invalid blackbox type: %s\n", type ); return; } char szMessage[1024]; va_list marker; va_start( marker, pFormat); Q_vsnprintf( szMessage, sizeof( szMessage ), pFormat, marker); va_end( marker ); //Msg( "Record: %s: %s\n", type, szMessage ); blackboxrecorder->Record( type_num, szMessage ); }
void CReplayRenderer::LayoffFrame( int nFrame ) { VPROF_BUDGET( "CReplayRenderer::LayoffFrame", VPROF_BUDGETGROUP_REPLAY ); // FIXME: This is somewhat of a hack to get layoff working again // We're rendering into the full preview size, but stretching down to the actual size Rect_t srcRect; srcRect.x = 0; srcRect.y = 0; srcRect.width = m_RenderParams.m_Settings.m_nWidth; srcRect.height = m_RenderParams.m_Settings.m_nHeight; Rect_t dstRect; dstRect.x = 0; dstRect.y = 0; dstRect.width = m_RenderParams.m_Settings.m_nWidth; dstRect.height = m_RenderParams.m_Settings.m_nHeight; #ifdef TRACE_REPLAY_STATE_MACHINE Msg( "laying off movie frame %i\n", nFrame ); #endif CMatRenderContextPtr pRenderContext( materials ); // pRenderContext->ReadPixelsAndStretch( &srcRect, &dstRect, (unsigned char*)m_pLayoffBuf, // IMAGE_FORMAT_BGRA8888, dstRect.width * ImageLoader::SizeInBytes( IMAGE_FORMAT_BGRA8888 ) ); pRenderContext->ReadPixels( 0, 0, (int) m_RenderParams.m_Settings.m_nWidth, (int) m_RenderParams.m_Settings.m_nHeight, (unsigned char*)m_pLayoffBuf, IMAGE_FORMAT_BGRA8888 ); static ConVarRef mat_queue_mode( "mat_queue_mode" ); // Encode the frame #ifdef REPLAY_RECORDING_ENABLE if ( m_RenderParams.m_bExportRaw ) { CUtlBuffer bufOut; if ( TGAWriter::WriteToBuffer( (unsigned char *)m_pLayoffBuf, bufOut, m_RenderParams.m_Settings.m_nWidth, m_RenderParams.m_Settings.m_nHeight, IMAGE_FORMAT_BGRA8888, IMAGE_FORMAT_RGB888 ) ) { // Format filename and write the TGA CFmtStr fmtFilename( "%sFrame_%04i.tga", m_fmtTgaRenderDirName.Access(), m_iTgaFrame++ ); if ( !g_pFullFileSystem->WriteFile( fmtFilename.Access(), NULL, bufOut ) ) { Warning( "Couldn't write bitmap data snapshot to file %s.\n", fmtFilename.Access() ); } } } else if ( m_pMovieMaker ) { // can't run in any other mode Assert( mat_queue_mode.GetInt() == 0 ); VPROF_BUDGET( "CReplayRenderer::LayoffFrame - AppendVideoFrame", VPROF_BUDGETGROUP_REPLAY ); m_pMovieMaker->AppendVideoFrame( m_pLayoffBuf ); } #endif }
//============================================================================= void LoadingProgress::ApplySchemeSettings( IScheme *pScheme ) { // will cause the controls to be instanced BaseClass::ApplySchemeSettings( pScheme ); SetPaintBackgroundEnabled( true ); // now have controls, can now do further initing m_bValid = true; // find or create pattern // purposely not freeing these, not worth the i/o hitch for something so small const char *pImageName = "vgui/loadingbar"; m_textureID_LoadingBar = vgui::surface()->DrawGetTextureId( pImageName ); if ( m_textureID_LoadingBar == -1 ) { m_textureID_LoadingBar = vgui::surface()->CreateNewTextureID(); vgui::surface()->DrawSetTextureFile( m_textureID_LoadingBar, pImageName, true, false ); } // find or create pattern // purposely not freeing these, not worth the i/o hitch for something so small pImageName = "vgui/loadingbar_bg"; m_textureID_LoadingBarBG = vgui::surface()->DrawGetTextureId( pImageName ); if ( m_textureID_LoadingBarBG == -1 ) { m_textureID_LoadingBarBG = vgui::surface()->CreateNewTextureID(); vgui::surface()->DrawSetTextureFile( m_textureID_LoadingBarBG, pImageName, true, false ); } // need to get the default image loaded now // find or create pattern // Purposely not freeing these, need this image to be resident always. We flip to // this image on a sign out during loading and cannot bring it into existence then. #if defined ( SUPPORT_DEFAULT_LOADING_POSTER ) if ( m_pDefaultPosterDataKV ) { static ConVarRef mat_xbox_iswidescreen( "mat_xbox_iswidescreen" ); bool bIsWidescreen = mat_xbox_iswidescreen.GetBool(); bool bFullscreenPoster = m_pDefaultPosterDataKV->GetBool( "fullscreen", false ); const char *pszPosterImage = ( bFullscreenPoster && bIsWidescreen ) ? m_pDefaultPosterDataKV->GetString( "posterImage_widescreen" ) : m_pDefaultPosterDataKV->GetString( "posterImage" ); // have to do this to mimic what the bowels of the scheme manager does with bitmaps bool bPrependVguiFix = V_strnicmp( pszPosterImage, "vgui", 4 ) != 0; CFmtStr sPosterImageFmt( "%s%s", ( bPrependVguiFix ? "vgui/" : "" ), pszPosterImage ); pszPosterImage = sPosterImageFmt; m_textureID_DefaultPosterImage = vgui::surface()->DrawGetTextureId( pszPosterImage ); if ( m_textureID_DefaultPosterImage == -1 ) { m_textureID_DefaultPosterImage = vgui::surface()->CreateNewTextureID(); vgui::surface()->DrawSetTextureFile( m_textureID_DefaultPosterImage, pszPosterImage, true, false ); } } #endif SetupControlStates(); }
void ClientModeHLNormal::LevelInit( const char *newmap ) { // reset ambient light static ConVarRef mat_ambient_light_r( "mat_ambient_light_r" ); static ConVarRef mat_ambient_light_g( "mat_ambient_light_g" ); static ConVarRef mat_ambient_light_b( "mat_ambient_light_b" ); if ( mat_ambient_light_r.IsValid() ) { mat_ambient_light_r.SetValue( "0" ); } if ( mat_ambient_light_g.IsValid() ) { mat_ambient_light_g.SetValue( "0" ); } if ( mat_ambient_light_b.IsValid() ) { mat_ambient_light_b.SetValue( "0" ); } BaseClass::LevelInit(newmap); // sdk: make sure no windows are left open from before SDK_CloseAllWindows(); // clear any DSP effects CLocalPlayerFilter filter; enginesound->SetRoomType( filter, 0 ); enginesound->SetPlayerDSP( filter, 0, true ); }
void ShaderEditorInterface::OnFrame( float frametime ) { if ( IsInEditMode() ) { static ConVarRef qMode( "mat_queue_mode" ); #if defined( SHADER_EDITOR_DLL_SWARM ) || defined( SHADER_EDITOR_DLL_2013 ) qMode.SetValue( "0" ); #else qMode.SetValue( "-1" ); #endif } IGameSystem::UpdateAllSystems( frametime ); }
void CHudMapFinishedDialog::OnThink() { BaseClass::OnThink(); static ConVarRef hvel("mom_hud_speedometer_hvel"); m_iVelocityType = hvel.GetBool(); m_pPlayReplayButton->SetVisible(!m_bIsGhost); m_pRunUploadStatus->SetVisible(!m_bIsGhost); m_pRunSaveStatus->SetVisible(!m_bIsGhost); CMOMSpectatorGUI *pPanel = dynamic_cast<CMOMSpectatorGUI*>(gViewPortInterface->FindPanelByName(PANEL_SPECGUI)); if (pPanel && pPanel->IsVisible()) SetMouseInputEnabled(pPanel->IsMouseInputEnabled()); }
void OnGameFrameStart() { g_MapzoneEdit.Update(); if (!g_Timer.GotCaughtCheating()) { ConVarRef cheatsRef = ConVarRef("sv_cheats"); if (cheatsRef.GetBool()) { g_Timer.SetCheating(true); g_Timer.Stop(false); } } }
void CReplayRenderer::RenderVideo() { #if _DEBUG static ConVarRef replay_fake_render( "replay_fake_render" ); if ( replay_fake_render.IsValid() && replay_fake_render.GetBool() ) return; #endif if ( !engine->IsInGame() ) return; if ( !m_LayoffResult.IsValid() ) return; CompositeAndLayoffFrame( m_nFrame++ ); }
//----------------------------------------------------------------------------- // Purpose: Activate a button click. //----------------------------------------------------------------------------- void Button::DoClick() { SetSelected(true); FireActionSignal(); PlayButtonReleasedSound(); static ConVarRef vgui_nav_lock( "vgui_nav_lock" ); if ( ( !vgui_nav_lock.IsValid() || vgui_nav_lock.GetInt() == 0 ) && NavigateActivate() ) { vgui_nav_lock.SetValue( 1 ); } if ( !m_bStaySelectedOnClick ) { SetSelected(false); } }
//Check friendly fire rules to see if a player should be hit //Returns true if damage should be dealt, false if it should not bool CDHLProjectile::CheckFriendlyFire( CBaseEntity* pEnt ) { if ( DHLRules()->IsTeamplay() ) { if ( pEnt->IsPlayer() ) { CDHL_Player* pPlayer = ToDHLPlayer( pEnt ); if ( pPlayer && m_pShooter ) { if ( pPlayer->GetTeamNumber() == m_pShooter->GetTeamNumber() ) { static ConVarRef ffVar("mp_friendlyfire"); if ( ffVar.GetBool() ) return false; } } } } return true; }
void SignInDialog::ApplySchemeSettings( IScheme *pScheme ) { BaseClass::ApplySchemeSettings( pScheme ); #ifdef _X360 char chGamerName[256]; XUSER_SIGNIN_INFO xsi; if ( XBX_GetPrimaryUserId() >= 0 && XUserGetSigninState( XBX_GetPrimaryUserId() ) != eXUserSigninState_NotSignedIn && ERROR_SUCCESS == XUserGetName( XBX_GetPrimaryUserId(), chGamerName, sizeof( chGamerName ) ) && ERROR_SUCCESS == XUserGetSigninInfo( XBX_GetPrimaryUserId(), XUSER_GET_SIGNIN_INFO_ONLINE_XUID_ONLY, &xsi ) && !(xsi.dwInfoFlags & XUSER_INFO_FLAG_GUEST) ) // need to catch promoted-guest-accounts { static ConVarRef cl_names_debug( "cl_names_debug" ); if ( cl_names_debug.GetInt() ) { strcpy( chGamerName, PLAYER_DEBUG_NAME ); } const unsigned messageLen = 256; wchar_t* wStringTableEntry = g_pVGuiLocalize->Find( "#L4D360UI_SignIn_Title" ); wchar_t wWelcomeMsg[ messageLen ]; wchar_t wGamerTag[ messageLen ]; g_pVGuiLocalize->ConvertANSIToUnicode( chGamerName, wGamerTag, sizeof( wGamerTag ) ); g_pVGuiLocalize->ConstructString( wWelcomeMsg, sizeof( wWelcomeMsg ), wStringTableEntry, 1, wGamerTag ); SetSignInTitle( wWelcomeMsg ); m_bSignedIn = true; } else #endif { SetSignInTitle( "#L4D360UI_SignIn_TitleNo" ); m_bSignedIn = false; } }
//============================================================================= void CUIGameData::OnCompletedAsyncDeviceAttached( CAsyncCtxUIOnDeviceAttached * job ) { ISelectStorageDeviceClient *pStorageDeviceClient = m_pSelectStorageClient; m_pSelectStorageClient = NULL; static ConVarRef mm_dlcs_mask_extras( "mm_dlcs_mask_extras" ); if ( mm_dlcs_mask_extras.IsValid() ) { #ifdef _X360 int iDLCmask = mm_dlcs_mask_extras.GetInt(); if ( engine->IsLowViolence() && XGetGameRegion() == XC_GAME_REGION_EUROPE_REST ) { // iDLCmask |= ( 1 << ? ); } mm_dlcs_mask_extras.SetValue( iDLCmask ); #endif } uint nRet = job ? job->GetContainerOpenResult() : ERROR_SUCCESS; if ( nRet != ERROR_SUCCESS ) { CloseWaitScreen( NULL, "ReportDeviceCorrupt" ); pStorageDeviceClient->OnDeviceFail( ISelectStorageDeviceClient::FAIL_CORRUPT ); } else { // Notify that data has loaded pStorageDeviceClient->AfterDeviceMounted(); // Check for opening a new storage device immediately if ( m_pSelectStorageClient == NULL ) { // Close down the waiting screen CloseWaitScreen( NULL, "OnCompletedAsyncDeviceAttached" ); } } }
//==================================================================== // Prepara al Cliente para el inicio de un nivel //==================================================================== void InClientMode::LevelInit( const char *newmap ) { // Reiniciamos la luz de ambiente static ConVarRef mat_ambient_light_r( "mat_ambient_light_r" ); static ConVarRef mat_ambient_light_g( "mat_ambient_light_g" ); static ConVarRef mat_ambient_light_b( "mat_ambient_light_b" ); if ( mat_ambient_light_r.IsValid() ) mat_ambient_light_r.SetValue( "0" ); if ( mat_ambient_light_g.IsValid() ) mat_ambient_light_g.SetValue( "0" ); if ( mat_ambient_light_b.IsValid() ) mat_ambient_light_b.SetValue( "0" ); BaseClass::LevelInit( newmap ); // clear any DSP effects CLocalPlayerFilter filter; enginesound->SetRoomType( filter, 0 ); enginesound->SetPlayerDSP( filter, 0, true ); }
void CHudDHLRoundTime::MsgFunc_RoundEnd( bf_read &msg ) { bool bSuccess = false; byte val = msg.ReadByte(); if ( val == 255 ) //Arbitrary "round draw" value { wcsncpy( wszHudText, g_pVGuiLocalize->Find( "#DHL_ROUND_DRAW" ), 50 ); bSuccess = true; } else { if ( DHLRules()->IsTeamplay() ) { //Val indicates winning team # C_Team* pTeam = GetGlobalTeam( val ); if ( pTeam ) { wchar_t wszTeamName[32]; g_pVGuiLocalize->ConvertANSIToUnicode( pTeam->Get_Name(), wszTeamName, sizeof(wszTeamName) ); g_pVGuiLocalize->ConstructString( wszHudText, sizeof( wszHudText ), g_pVGuiLocalize->Find( "#DHL_ROUNDPLAY_WINNER" ), 1, wszTeamName ); bSuccess = true; } } else { //Val indicates winning player's index C_BasePlayer *pPlayer = UTIL_PlayerByIndex( val ); if ( pPlayer ) { wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH]; g_pVGuiLocalize->ConvertANSIToUnicode( pPlayer->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) ); g_pVGuiLocalize->ConstructString( wszHudText, sizeof( wszHudText ), g_pVGuiLocalize->Find( "#DHL_LMS_WINNER" ), 1, wszPlayerName ); bSuccess = true; } } } static ConVarRef restartDelay( "dhl_roundrestartdelay" ); if ( bSuccess ) flHudTextTime = gpGlobals->curtime + restartDelay.GetFloat(); }
//============================================================================= void LoadingProgress::SetupPoster( void ) { int i; bool bNamesVisible = false; vgui::ImagePanel *pPoster = dynamic_cast< vgui::ImagePanel* >( FindChildByName( "Poster" ) ); if ( pPoster ) { #if !defined( _X360 ) int screenWide, screenTall; surface()->GetScreenSize( screenWide, screenTall ); float aspectRatio = (float)screenWide/(float)screenTall; bool bIsWidescreen = aspectRatio >= 1.5999f; #else static ConVarRef mat_xbox_iswidescreen( "mat_xbox_iswidescreen" ); bool bIsWidescreen = mat_xbox_iswidescreen.GetBool(); #endif /* const char *pszPosterImage; int nChosenLoadingImage = RandomInt( 1, 4 ); switch( nChosenLoadingImage ) { case 1: pszPosterImage = ( m_bFullscreenPoster && bIsWidescreen ) ? "swarm/loading/BGFX01_wide" : "swarm/loading/BGFX01"; break; case 2: pszPosterImage = ( m_bFullscreenPoster && bIsWidescreen ) ? "swarm/loading/BGFX02_wide" : "swarm/loading/BGFX02"; break; case 3: pszPosterImage = ( m_bFullscreenPoster && bIsWidescreen ) ? "swarm/loading/BGFX03_wide" : "swarm/loading/BGFX03"; break; case 4: default: pszPosterImage = ( m_bFullscreenPoster && bIsWidescreen ) ? "swarm/loading/BGFX04_wide" : "swarm/loading/BGFX04"; break; }*/ char pszPosterImage[MAX_PATH]; V_snprintf( pszPosterImage, sizeof( pszPosterImage ), ( m_bFullscreenPoster && bIsWidescreen ) ? "../console/%s_widescreen" : "../console/%s", m_pChapterInfo->GetString( "map" ) ); // if the image was cached this will just hook it up, otherwise it will load it pPoster->SetImage( pszPosterImage ); if ( pPoster->GetImage() ) { bNamesVisible = true; } } bool bIsLocalized = false; #ifdef _X360 bIsLocalized = XBX_IsLocalized(); #else char uilanguage[ 64 ]; engine->GetUILanguage( uilanguage, sizeof( uilanguage ) ); if ( Q_stricmp( uilanguage, "english" ) ) { bIsLocalized = true; } #endif SetControlVisible( "LocalizedCampaignName", false ); SetControlVisible( "LocalizedCampaignTagline", false ); wchar_t szPlayerNames[MAX_PATH]; Q_memset( szPlayerNames, 0, sizeof( szPlayerNames ) ); int nNumNames = 0; for ( i=0;i<NUM_LOADING_CHARACTERS;i++ ) { if ( !m_PlayerNames[i] || !m_PlayerNames[i][0] ) { continue; } if ( nNumNames != 0 ) { wcsncat( szPlayerNames, L", ", sizeof( szPlayerNames ) ); } wchar_t szName[64]; if ( m_PlayerNames[i] && m_PlayerNames[i][0] == '#' ) { wchar_t *pName = g_pVGuiLocalize->Find( m_PlayerNames[i] ); if ( pName == NULL ) { g_pVGuiLocalize->ConvertANSIToUnicode( m_PlayerNames[i], szName, sizeof( szPlayerNames ) ); } else { Q_wcsncpy( szName, pName, sizeof( szName ) ); } nNumNames++; } else { g_pVGuiLocalize->ConvertANSIToUnicode( m_PlayerNames[i], szName, sizeof( szPlayerNames ) ); nNumNames++; } wcsncat( szPlayerNames, szName, sizeof( szPlayerNames ) ); } if ( nNumNames != 0 ) { wcsncat( szPlayerNames, L".", sizeof( szPlayerNames ) ); } SetControlString( "GameModeLabel", m_szGameMode ); SetControlVisible( "PlayerNames", ( nNumNames > 1 ) ); SetControlVisible( "StarringLabel", ( nNumNames > 1 ) ); SetControlVisible( "GameModeLabel", false ); SetControlString( "playernames", szPlayerNames ); SetControlEnabled( "LoadingTipPanel", false ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pSetup - //----------------------------------------------------------------------------- void ClientModeSDKNormal::OverrideView( CViewSetup *pSetup ) { QAngle camAngles; // Let the player override the view. C_SDKPlayer *pPlayer = (C_SDKPlayer*)C_BasePlayer::GetLocalPlayer(); if(!pPlayer) return; pPlayer->OverrideView( pSetup ); if( ::input->CAM_IsThirdPerson() ) { Vector cam_ofs; ::input->CAM_GetCameraOffset( cam_ofs ); camAngles[ PITCH ] = cam_ofs[ PITCH ]; camAngles[ YAW ] = cam_ofs[ YAW ]; camAngles[ ROLL ] = 0; Vector camForward, camRight, camUp; AngleVectors( camAngles, &camForward, &camRight, &camUp ); VectorMA( pSetup->origin, -cam_ofs[ ROLL ], camForward, pSetup->origin ); static ConVarRef c_thirdpersonshoulder( "c_thirdpersonshoulder" ); if ( c_thirdpersonshoulder.GetBool() ) { static ConVarRef c_thirdpersonshoulderoffset( "c_thirdpersonshoulderoffset" ); static ConVarRef c_thirdpersonshoulderheight( "c_thirdpersonshoulderheight" ); static ConVarRef c_thirdpersonshoulderaimdist( "c_thirdpersonshoulderaimdist" ); // add the shoulder offset to the origin in the cameras right vector VectorMA( pSetup->origin, c_thirdpersonshoulderoffset.GetFloat(), camRight, pSetup->origin ); // add the shoulder height to the origin in the cameras up vector VectorMA( pSetup->origin, c_thirdpersonshoulderheight.GetFloat(), camUp, pSetup->origin ); // adjust the yaw to the aim-point camAngles[ YAW ] += RAD2DEG( atan(c_thirdpersonshoulderoffset.GetFloat() / (c_thirdpersonshoulderaimdist.GetFloat() + cam_ofs[ ROLL ])) ); // adjust the pitch to the aim-point camAngles[ PITCH ] += RAD2DEG( atan(c_thirdpersonshoulderheight.GetFloat() / (c_thirdpersonshoulderaimdist.GetFloat() + cam_ofs[ ROLL ])) ); } // Override angles from third person camera VectorCopy( camAngles, pSetup->angles ); } else if (::input->CAM_IsOrthographic()) { pSetup->m_bOrtho = true; float w, h; ::input->CAM_OrthographicSize( w, h ); w *= 0.5f; h *= 0.5f; pSetup->m_OrthoLeft = -w; pSetup->m_OrthoTop = -h; pSetup->m_OrthoRight = w; pSetup->m_OrthoBottom = h; } }
void DrawFogOfWarBlendedPass( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, FogOfWarBlendedPassVars_t &info, VertexCompressionType_t vertexCompression ) { bool bVertexLitGeneric = false; bool bHasFlashlight = false; SHADOW_STATE { bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); bool bHasSelfIllum = (!bHasFlashlight || IsX360() ) && IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; // Reset shadow state manually since we're drawing from two materials pShader->SetInitialShadowState(); // Set stream format (note that this shader supports compression) unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_FORMAT_COMPRESSED; int nTexCoordCount = 1; int userDataSize = 0; pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); // Vertex Shader DECLARE_STATIC_VERTEX_SHADER( fogofwar_blended_pass_vs20 ); SET_STATIC_VERTEX_SHADER_COMBO( FOW, true ); SET_STATIC_VERTEX_SHADER( fogofwar_blended_pass_vs20 ); // Pixel Shader DECLARE_STATIC_PIXEL_SHADER( fogofwar_blended_pass_ps20b ); SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, bHasSelfIllum ); SET_STATIC_PIXEL_SHADER_COMBO( FOW, true ); SET_STATIC_PIXEL_SHADER( fogofwar_blended_pass_ps20b ); pShader->DefaultFog(); // Textures pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); //pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); // Blending pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); pShaderShadow->EnableAlphaTest( bIsAlphaTested ); pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); } DYNAMIC_STATE { // Decide if this pass should be drawn static ConVarRef sv_fogofwar("sv_fogofwar"); //static ConVarRef sv_fogofwar_tilesize("sv_fogofwar_tilesize"); if( !sv_fogofwar.GetBool() ) { pShader->Draw( false ); return; } // Reset render state manually since we're drawing from two materials pShaderAPI->SetDefaultState(); // Set Vertex Shader Combos DECLARE_DYNAMIC_VERTEX_SHADER( fogofwar_blended_pass_vs20 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER_COMBO( DOWATERFOG, pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER( fogofwar_blended_pass_vs20 ); // Set Vertex Shader Constants //pShader->SetAmbientCubeDynamicStateVertexShader(); // Set Pixel Shader Combos DECLARE_DYNAMIC_PIXEL_SHADER( fogofwar_blended_pass_ps20b ); SET_DYNAMIC_PIXEL_SHADER( fogofwar_blended_pass_ps20b ); // Bind textures pShader->BindTexture( SHADER_SAMPLER0, info.m_nBaseTexture ); pShader->BindTexture( SHADER_SAMPLER1, info.m_nFogOfWarTexture ); // Set Pixel Shader Constants //pShader->SetModulationPixelShaderDynamicState_LinearColorSpace( 1 ); float eyePos[4]; pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); pShaderAPI->SetPixelShaderConstant( 0, eyePos, 1 ); bool bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); bool bWriteWaterFogToAlpha = false; bool bHasVertexAlpha = bVertexLitGeneric ? false : IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA ); float fPixelFogType = pShaderAPI->GetPixelFogCombo() == 1 ? 1 : 0; float fWriteDepthToAlpha = bWriteDepthToAlpha && IsPC() ? 1 : 0; float fWriteWaterFogToDestAlpha = bWriteWaterFogToAlpha ? 1 : 0; float fVertexAlpha = bHasVertexAlpha ? 1 : 0; // Controls for lerp-style paths through shader code (bump and non-bump have use different register) float vShaderControls[4] = { fPixelFogType, fWriteDepthToAlpha, fWriteWaterFogToDestAlpha, fVertexAlpha }; pShaderAPI->SetPixelShaderConstant( 1, vShaderControls, 1 ); pShaderAPI->SetPixelShaderFogParams(2); float vFoWSize[ 4 ]; Vector vMins = pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_GLOBAL_FOW_MINS ); Vector vMaxs = pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_GLOBAL_FOW_MAXS ); vFoWSize[ 0 ] = vMins.x; vFoWSize[ 1 ] = vMins.y; vFoWSize[ 2 ] = vMaxs.x - vMins.x; vFoWSize[ 3 ] = vMaxs.y - vMins.y; pShaderAPI->SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, vFoWSize ); /* // Fog of war color static float c[4]; c[0] = mat_fogofwar_r.GetFloat(); c[1] = mat_fogofwar_g.GetFloat(); c[2] = mat_fogofwar_b.GetFloat(); c[3] = mat_fogofwar_a.GetFloat(); pShaderAPI->SetPixelShaderConstant( 3, (const float *)(&c), 1 ); */ // Tilesize //static float ts[4]; //ts[0] = sv_fogofwar_tilesize.GetInt(); //pShaderAPI->SetPixelShaderConstant( 4, (const float *)(&ts), 1 ); } pShader->Draw(); }
//================================================================================= // Callback for the 'webspec' protocol // Manages spectator connections & sending Initial messages to new spectators //================================================================================= int webspec_callback(struct libwebsocket_context *ctx, struct libwebsocket *wsi, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { switch (reason) { case LWS_CALLBACK_ESTABLISHED: { Msg("[WS] New connection\n"); // New connection ws_spectators.AddToTail(wsi); // Send basic game info to let client set up // MapName, Server name (may remove), current team names char *buffer = (char*)malloc(MAX_BUFFER_SIZE); char *mapName = (char*) STRING(gpGlobals->mapname); ConVarRef hostNameCVar = ConVarRef("hostname"); string_t hostname; if (hostNameCVar.IsValid()) hostname = MAKE_STRING(hostNameCVar.GetString()); else hostname = MAKE_STRING("WebSpec Demo Server"); //Can't imagine when hostname would be invalid, but this is Source int length = snprintf(buffer, MAX_BUFFER_SIZE, "%c%s:%s:%s:%s", WSPacket_Init, mapName, STRING(hostname), STRING(ws_teamName[1]), STRING(ws_teamName[0])); SendPacketToOne(buffer, length, wsi); free(buffer); //Send connected players IPlayerInfo *playerInfo; for (int i=1; i<=gpGlobals->maxClients; i++) { playerInfo = playerInfoManager->GetPlayerInfo(engine->PEntityOfEntIndex(i)); if (playerInfo != NULL && playerInfo->IsConnected()) { buffer = (char *)malloc(MAX_BUFFER_SIZE); int userid = playerInfo->GetUserID(); int teamid = playerInfo->GetTeamIndex(); int health = playerInfo->GetHealth(); int maxHealth = playerInfo->GetMaxHealth(); bool alive = !playerInfo->IsDead(); string_t playerName = MAKE_STRING(playerInfo->GetName()); //Pointer magic to get TF2 class CBaseEntity *playerEntity = serverGameEnts->EdictToBaseEntity(engine->PEntityOfEntIndex(i)); int playerClass = *MakePtr(int*, playerEntity, WSOffsets::pCTFPlayer__m_iClass); float uberCharge = 0.0f; if (playerClass == TFClass_Medic) { //Way more pointer magic to get ubercharge from medigun CBaseCombatCharacter *playerCombatCharacter = CBaseEntity_MyCombatCharacterPointer(playerEntity); CBaseCombatWeapon *slot1Weapon = CBaseCombatCharacter_Weapon_GetSlot(playerCombatCharacter, 1); uberCharge = *MakePtr(float*, slot1Weapon, WSOffsets::pCWeaponMedigun__m_flChargeLevel); } int length = snprintf(buffer, MAX_BUFFER_SIZE, "%c%d:%d:%d:%d:%d:%d:0:%d:%s", 'C', userid, teamid, playerClass, health, maxHealth, alive, Round(uberCharge*100.0f), STRING(playerName)); SendPacketToOne(buffer, length, wsi); free(buffer); } } break; }
void DrawLightmappedGeneric_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, LightmappedGeneric_DX9_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr, bool bDeferredActive ) { //bool bDeferredActive = GetDeferredExt()->IsDeferredLightingEnabled(); bool bSinglePassFlashlight = true; bool hasFlashlight = !bDeferredActive && pShader->UsingFlashlight( params ); CLightmappedGeneric_DX9_Context *pContextData = reinterpret_cast< CLightmappedGeneric_DX9_Context *> ( *pContextDataPtr ); bool bShaderSrgbRead = ( IsX360() && IS_PARAM_DEFINED( info.m_nShaderSrgbRead360 ) && params[info.m_nShaderSrgbRead360]->GetIntValue() ); const bool bHasFoW = true; //( ( info.m_nFoW != -1 ) && ( params[ info.m_nFoW ]->IsTexture() != 0 ) ); if ( pShaderShadow || ( ! pContextData )|| pContextData->m_bMaterialVarsChanged || pContextData->m_bNeedsCmdRegen || ( hasFlashlight && !IsX360() ) ) { bool hasBaseTexture = params[info.m_nBaseTexture]->IsTexture(); int nAlphaChannelTextureVar = hasBaseTexture ? (int)info.m_nBaseTexture : (int)info.m_nEnvmapMask; BlendType_t nBlendType = pShader->EvaluateBlendRequirements( nAlphaChannelTextureVar, hasBaseTexture ); bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; bool bFullyOpaqueWithoutAlphaTest = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && (!hasFlashlight || IsX360()); //dest alpha is free for special use bool bFullyOpaque = bFullyOpaqueWithoutAlphaTest && !bIsAlphaTested; bool bNeedRegenStaticCmds = (! pContextData ) || pShaderShadow || pContextData->m_bNeedsCmdRegen; if ( ! pContextData ) // make sure allocated { pContextData = new CLightmappedGeneric_DX9_Context; *pContextDataPtr = pContextData; } bool hasBump = ( params[info.m_nBumpmap]->IsTexture() ) && g_pConfig->UseBumpmapping(); bool hasSSBump = hasBump && (info.m_nSelfShadowedBumpFlag != -1) && ( params[info.m_nSelfShadowedBumpFlag]->GetIntValue() ); bool hasBaseTexture2 = hasBaseTexture && params[info.m_nBaseTexture2]->IsTexture(); bool hasLightWarpTexture = params[info.m_nLightWarpTexture]->IsTexture(); bool hasBump2 = hasBump && params[info.m_nBumpmap2]->IsTexture(); bool hasDetailTexture = params[info.m_nDetail]->IsTexture(); bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM ); bool hasBumpMask = hasBump && hasBump2 && params[info.m_nBumpMask]->IsTexture() && !hasSelfIllum && !hasDetailTexture && !hasBaseTexture2 && (params[info.m_nBaseTextureNoEnvmap]->GetIntValue() == 0); bool bHasBlendModulateTexture = (info.m_nBlendModulateTexture != -1) && (params[info.m_nBlendModulateTexture]->IsTexture() ); bool hasNormalMapAlphaEnvmapMask = g_pConfig->UseSpecular() && IS_FLAG_SET( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK ); if( g_pConfig->bEditMode ) { hasBump = false; hasBump2 = false; } bool bParallaxMapping = false; if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) bParallaxMapping = ( info.m_nParallaxMap != -1 ) && ( params[info.m_nParallaxMap]->GetIntValue() != 0 ); if ( hasFlashlight && !IsX360() ) { // !!speed!! do this in the caller so we don't build struct every time CBaseVSShader::DrawFlashlight_dx90_Vars_t vars; vars.m_bBump = hasBump; vars.m_nBumpmapVar = info.m_nBumpmap; vars.m_nBumpmapFrame = info.m_nBumpFrame; vars.m_nBumpTransform = info.m_nBumpTransform; vars.m_nFlashlightTextureVar = info.m_nFlashlightTexture; vars.m_nFlashlightTextureFrameVar = info.m_nFlashlightTextureFrame; vars.m_bLightmappedGeneric = true; vars.m_bWorldVertexTransition = hasBaseTexture2; vars.m_nBaseTexture2Var = info.m_nBaseTexture2; vars.m_nBaseTexture2FrameVar = info.m_nBaseTexture2Frame; vars.m_nBumpmap2Var = info.m_nBumpmap2; vars.m_nBumpmap2Frame = info.m_nBumpFrame2; vars.m_nBump2Transform = info.m_nBumpTransform2; vars.m_nAlphaTestReference = info.m_nAlphaTestReference; vars.m_bSSBump = hasSSBump; vars.m_nDetailVar = info.m_nDetail; vars.m_nDetailScale = info.m_nDetailScale; vars.m_nDetailTextureCombineMode = info.m_nDetailTextureCombineMode; vars.m_nDetailTextureBlendFactor = info.m_nDetailTextureBlendFactor; vars.m_nDetailTint = info.m_nDetailTint; if ( ( info.m_nSeamlessMappingScale != -1 ) ) vars.m_fSeamlessScale = params[info.m_nSeamlessMappingScale]->GetFloatValue(); else vars.m_fSeamlessScale = 0.0; pShader->DrawFlashlight_dx90( params, pShaderAPI, pShaderShadow, vars ); return; } pContextData->m_bFullyOpaque = bFullyOpaque; pContextData->m_bFullyOpaqueWithoutAlphaTest = bFullyOpaqueWithoutAlphaTest; bool bHasOutline = IsBoolSet( info.m_nOutline, params ); pContextData->m_bPixelShaderForceFastPathBecauseOutline = bHasOutline; bool bHasSoftEdges = IsBoolSet( info.m_nSoftEdges, params ); bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture() && !bHasFoW; float fDetailBlendFactor = GetFloatParam( info.m_nDetailTextureBlendFactor, params, 1.0 ); if ( pShaderShadow || bNeedRegenStaticCmds ) { bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); bool hasDiffuseBumpmap = hasBump && (params[info.m_nNoDiffuseBumpLighting]->GetIntValue() == 0); bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); int envmap_variant; //0 = no envmap, 1 = regular, 2 = darken in shadow mode if( hasEnvmap ) { //only enabled darkened cubemap mode when the scale calls for it. And not supported in ps20 when also using a 2nd bumpmap envmap_variant = ((GetFloatParam( info.m_nEnvMapLightScale, params ) > 0.0f) && (g_pHardwareConfig->SupportsPixelShaders_2_b() || !hasBump2)) ? 2 : 1; } else { envmap_variant = 0; } bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); if ( bNeedRegenStaticCmds ) { pContextData->m_bNeedsCmdRegen = false; pContextData->ResetStaticCmds(); CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf; int nLightingPreviewMode = !bHasFoW ? IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 ) : 0; if ( ( nLightingPreviewMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH ) && IsPC() ) { staticCmdsBuf.SetVertexShaderNearAndFarZ( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 ); // Needed for SSAO } if( !hasBaseTexture ) { if( hasEnvmap ) { // if we only have an envmap (no basetexture), then we want the albedo to be black. staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_BLACK ); } else { staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_WHITE ); } } staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER1, TEXTURE_LIGHTMAP ); if ( g_pConfig->m_bPaintInGame && !r_twopasspaint.GetBool() ) { staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_PAINT ); } if ( bSeamlessMapping ) { staticCmdsBuf.SetVertexShaderConstant4( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, params[info.m_nSeamlessMappingScale]->GetFloatValue(),0,0,0 ); } staticCmdsBuf.StoreEyePosInPixelShaderConstant( 10 ); staticCmdsBuf.SetPixelShaderFogParams( 11 ); staticCmdsBuf.End(); // now, copy buf pContextData->m_pStaticCmds = new uint8[staticCmdsBuf.Size()]; memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() ); } if ( pShaderShadow ) { // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState pShaderShadow->EnableAlphaTest( bIsAlphaTested ); if ( info.m_nAlphaTestReference != -1 && params[info.m_nAlphaTestReference]->GetFloatValue() > 0.0f ) { pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[info.m_nAlphaTestReference]->GetFloatValue() ); } pShader->SetDefaultBlendingShadowState( nAlphaChannelTextureVar, hasBaseTexture ); unsigned int flags = VERTEX_POSITION; // base texture pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, !bShaderSrgbRead ); if ( g_pConfig->m_bPaintInGame && !r_twopasspaint.GetBool() ) { pShaderShadow->EnableTexture( SHADER_SAMPLER9, true ); pShaderShadow->EnableSRGBRead( SHADER_SAMPLER9, !bShaderSrgbRead ); } if ( hasLightWarpTexture ) { pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); pShaderShadow->EnableSRGBRead( SHADER_SAMPLER6, false ); } if ( bHasBlendModulateTexture ) { pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); pShaderShadow->EnableSRGBRead( SHADER_SAMPLER3, false ); } if ( hasBaseTexture2 ) { pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); pShaderShadow->EnableSRGBRead( SHADER_SAMPLER7, !bShaderSrgbRead ); } // if( hasLightmap ) pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, true ); } else { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER1, false ); } if( hasEnvmap || ( IsX360() && hasFlashlight ) ) { if( hasEnvmap ) { pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); } } flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL; } #define TCOMBINE_NONE 12 // there is no detail texture int nDetailBlendMode = TCOMBINE_NONE; if ( hasDetailTexture ) { nDetailBlendMode = GetIntParam( info.m_nDetailTextureCombineMode, params ); ITexture *pDetailTexture = params[info.m_nDetail]->GetTextureValue(); if ( pDetailTexture->GetFlags() & TEXTUREFLAGS_SSBUMP ) { if ( hasBump ) nDetailBlendMode = 10; // ssbump else nDetailBlendMode = 11; // ssbump_nobump } pShaderShadow->EnableTexture( SHADER_SAMPLER12, true ); bool bSRGBState = ( nDetailBlendMode == 1 ); pShaderShadow->EnableSRGBRead( SHADER_SAMPLER12, bSRGBState ); } // Hijack detail blend mode 9 for paint (this blend mode was previously skipped/unused in lightmappedgeneric) if ( g_pConfig->m_bPaintInGame && !r_twopasspaint.GetBool() ) { nDetailBlendMode = 9; } if( hasBump || hasNormalMapAlphaEnvmapMask ) { pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); } if( hasBump2 ) { pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); } if( hasBumpMask ) { pShaderShadow->EnableTexture( SHADER_SAMPLER8, true ); } if( hasEnvmapMask ) { pShaderShadow->EnableTexture( SHADER_SAMPLER5, true ); } if( bHasFoW ) { pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); } if( bDeferredActive ) { pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER15, true ); } if( hasFlashlight && IsX360() ) { pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); pShaderShadow->SetShadowDepthFiltering( SHADER_SAMPLER14 ); pShaderShadow->EnableTexture( SHADER_SAMPLER15, true ); } if( hasVertexColor || hasBaseTexture2 || hasBump2 ) { flags |= VERTEX_COLOR; } // texcoord0 : base texcoord // texcoord1 : lightmap texcoord // texcoord2 : lightmap texcoord offset int numTexCoords; // if ( pShaderAPI->InEditorMode() ) // if ( pShader->CanUseEditorMaterials() ) // { // numTexCoords = 1; // } // else { numTexCoords = 2; if( hasBump ) { numTexCoords = 3; } } int nLightingPreviewMode = !bHasFoW ? IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 ) : 0; pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 ); // Pre-cache pixel shaders bool hasBaseAlphaEnvmapMask = IS_FLAG_SET( MATERIAL_VAR_BASEALPHAENVMAPMASK ); int bumpmap_variant=(hasSSBump) ? 2 : hasBump; bool bMaskedBlending=( (info.m_nMaskedBlending != -1) && (params[info.m_nMaskedBlending]->GetIntValue() != 0) ); if( bDeferredActive ) { DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_deferred_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask ); SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, params[info.m_nEnvmap]->IsTexture() ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, hasBaseTexture2 || hasBump2 ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, hasBumpMask ); SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode ); SET_STATIC_VERTEX_SHADER_COMBO( PARALLAX_MAPPING, bParallaxMapping ); SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); SET_STATIC_VERTEX_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); SET_STATIC_VERTEX_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); SET_STATIC_VERTEX_SHADER_COMBO( SELFILLUM, hasSelfIllum ); SET_STATIC_VERTEX_SHADER_COMBO( FOW, bHasFoW ); SET_STATIC_VERTEX_SHADER( lightmappedgeneric_deferred_vs30 ); DECLARE_STATIC_PIXEL_SHADER( lightmappedgeneric_deferred_ps30 ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, envmap_variant ); SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); SET_STATIC_PIXEL_SHADER_COMBO( PARALLAX_MAPPING, bParallaxMapping ); SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead ); SET_STATIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode ); SET_STATIC_PIXEL_SHADER( lightmappedgeneric_deferred_ps30 ); } else { DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask ); SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, params[info.m_nEnvmap]->IsTexture() ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump ); SET_STATIC_VERTEX_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, hasBaseTexture2 || hasBump2 ); SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, hasBumpMask ); SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode ); SET_STATIC_VERTEX_SHADER_COMBO( PARALLAX_MAPPING, bParallaxMapping ); SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); SET_STATIC_VERTEX_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); SET_STATIC_VERTEX_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); SET_STATIC_VERTEX_SHADER_COMBO( SELFILLUM, hasSelfIllum ); SET_STATIC_VERTEX_SHADER_COMBO( FOW, bHasFoW ); SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs30 ); DECLARE_STATIC_PIXEL_SHADER( lightmappedgeneric_ps30 ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2, hasBaseTexture2 ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP2, hasBump2 ); SET_STATIC_PIXEL_SHADER_COMBO( BUMPMASK, hasBumpMask ); SET_STATIC_PIXEL_SHADER_COMBO( DIFFUSEBUMPMAP, hasDiffuseBumpmap ); SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, envmap_variant ); SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, hasEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( BASEALPHAENVMAPMASK, hasBaseAlphaEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( SELFILLUM, hasSelfIllum ); SET_STATIC_PIXEL_SHADER_COMBO( NORMALMAPALPHAENVMAPMASK, hasNormalMapAlphaEnvmapMask ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURENOENVMAP, params[info.m_nBaseTextureNoEnvmap]->GetIntValue() ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE2NOENVMAP, params[info.m_nBaseTexture2NoEnvmap]->GetIntValue() ); SET_STATIC_PIXEL_SHADER_COMBO( WARPLIGHTING, hasLightWarpTexture ); SET_STATIC_PIXEL_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture ); SET_STATIC_PIXEL_SHADER_COMBO( MASKEDBLENDING, bMaskedBlending); SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping ); SET_STATIC_PIXEL_SHADER_COMBO( OUTLINE, bHasOutline ); SET_STATIC_PIXEL_SHADER_COMBO( SOFTEDGES, bHasSoftEdges ); SET_STATIC_PIXEL_SHADER_COMBO( DETAILTEXTURE, hasDetailTexture ); SET_STATIC_PIXEL_SHADER_COMBO( DETAIL_BLEND_MODE, nDetailBlendMode ); SET_STATIC_PIXEL_SHADER_COMBO( PARALLAX_MAPPING, bParallaxMapping ); SET_STATIC_PIXEL_SHADER_COMBO( SHADER_SRGB_READ, bShaderSrgbRead ); SET_STATIC_PIXEL_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode ); SET_STATIC_PIXEL_SHADER( lightmappedgeneric_ps30 ); } // HACK HACK HACK - enable alpha writes all the time so that we have them for // underwater stuff and writing depth to dest alpha // But only do it if we're not using the alpha already for translucency pShaderShadow->EnableAlphaWrites( bFullyOpaque ); pShaderShadow->EnableSRGBWrite( true ); pShader->DefaultFog(); // NOTE: This isn't optimal. If $color2 is ever changed by a material // proxy, this code won't get re-run, but too bad. No time to make this work // Also note that if the lightmap scale factor changes // all shadow state blocks will be re-run, so that's ok float flLScale = pShaderShadow->GetLightMapScaleFactor(); pShader->PI_BeginCommandBuffer(); pShader->PI_SetModulationPixelShaderDynamicState( 21 ); // MAINTOL4DMERGEFIXME // Need to reflect this change which is from this rel changelist since this constant set was moved from the dynamic block to here: // Change 578692 by Alex@alexv_rel on 2008/06/04 18:07:31 // // Fix for portalareawindows in ep2 being rendered black. The color variable was being multipurposed for both the vs and ps differently where the ps doesn't care about alpha, but the vs does. Only applying the alpha2 DoD hack to the pixel shader constant where the alpha was never used in the first place and leaving alpha as is for the vs. // color[3] *= ( IS_PARAM_DEFINED( info.m_nAlpha2 ) && params[ info.m_nAlpha2 ]->GetFloatValue() > 0.0f ) ? params[ info.m_nAlpha2 ]->GetFloatValue() : 1.0f; // pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 12, color ); pShader->PI_SetModulationPixelShaderDynamicState_LinearScale_ScaleInW( 12, flLScale ); pShader->PI_SetModulationVertexShaderDynamicState_LinearScale( flLScale ); pShader->PI_EndCommandBuffer(); } // end shadow state } // end shadow || regen display list if ( pShaderAPI && ( pContextData->m_bMaterialVarsChanged ) ) { // need to regenerate the semistatic cmds pContextData->m_SemiStaticCmdsOut.Reset(); pContextData->m_bMaterialVarsChanged = false; bool bHasBlendMaskTransform= ( (info.m_nBlendMaskTransform != -1) && (info.m_nMaskedBlending != -1) && (params[info.m_nMaskedBlending]->GetIntValue() ) && ( ! (params[info.m_nBumpTransform]->MatrixIsIdentity() ) ) ); // If we don't have a texture transform, we don't have // to set vertex shader constants or run vertex shader instructions // for the texture transform. bool bHasTextureTransform = !( params[info.m_nBaseTextureTransform]->MatrixIsIdentity() && params[info.m_nBumpTransform]->MatrixIsIdentity() && params[info.m_nBumpTransform2]->MatrixIsIdentity() && params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() ); bHasTextureTransform |= bHasBlendMaskTransform; pContextData->m_bVertexShaderFastPath = !bHasTextureTransform; if( params[info.m_nDetail]->IsTexture() ) { pContextData->m_bVertexShaderFastPath = false; } int nTransformToLoad = info.m_nBlendMaskTransform; if( ( hasBump || hasSSBump ) && hasDetailTexture && !hasSelfIllum && !bHasBlendModulateTexture ) { nTransformToLoad = info.m_nBumpTransform; } pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, nTransformToLoad ); if ( ! pContextData->m_bVertexShaderFastPath ) { bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) && ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) ); bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture() && !bHasFoW; if (!bSeamlessMapping ) pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform ); // If we have a detail texture, then the bump texcoords are the same as the base texcoords. if( hasBump && !hasDetailTexture ) { pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform ); } if( hasEnvmapMask ) { pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform ); } else if ( hasBump2 ) { pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nBumpTransform2 ); } } pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicState( 0, info.m_nEnvmapTint ); if ( hasDetailTexture ) { float detailTintAndBlend[4] = {1, 1, 1, 1}; if ( info.m_nDetailTint != -1 ) { params[info.m_nDetailTint]->GetVecValue( detailTintAndBlend, 3 ); } detailTintAndBlend[3] = fDetailBlendFactor; pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 8, detailTintAndBlend ); } float envmapTintVal[4]; float selfIllumTintVal[4]; params[info.m_nEnvmapTint]->GetVecValue( envmapTintVal, 3 ); params[info.m_nSelfIllumTint]->GetVecValue( selfIllumTintVal, 3 ); float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); float envmapSaturation = params[info.m_nEnvmapSaturation]->GetFloatValue(); float fresnelReflection = params[info.m_nFresnelReflection]->GetFloatValue(); bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); int envmap_variant; //0 = no envmap, 1 = regular, 2 = darken in shadow mode if( hasEnvmap ) { //only enabled darkened cubemap mode when the scale calls for it. And not supported in ps20 when also using a 2nd bumpmap envmap_variant = ((GetFloatParam( info.m_nEnvMapLightScale, params ) > 0.0f) && (g_pHardwareConfig->SupportsPixelShaders_2_b() || !hasBump2)) ? 2 : 1; } else { envmap_variant = 0; } pContextData->m_bPixelShaderFastPath = true; bool bUsingContrastOrSaturation = hasEnvmap && ( ( (envmapContrast != 0.0f) && (envmapContrast != 1.0f) ) || (envmapSaturation != 1.0f) ); bool bUsingFresnel = hasEnvmap && (fresnelReflection != 1.0f); bool bUsingSelfIllumTint = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && (selfIllumTintVal[0] != 1.0f || selfIllumTintVal[1] != 1.0f || selfIllumTintVal[2] != 1.0f); if ( bUsingContrastOrSaturation || bUsingFresnel || bUsingSelfIllumTint || !g_pConfig->bShowSpecular ) { pContextData->m_bPixelShaderFastPath = false; } if( !pContextData->m_bPixelShaderFastPath ) { pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstants( 2, 3 ); pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapContrast]->GetVecValue() ); pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapSaturation]->GetVecValue() ); float flFresnel = params[info.m_nFresnelReflection]->GetFloatValue(); // [ 0, 0, 1-R(0), R(0) ] pContextData->m_SemiStaticCmdsOut.OutputConstantData4( 0., 0., 1.0 - flFresnel, flFresnel ); pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, params[info.m_nSelfIllumTint]->GetVecValue() ); } else { if ( bHasOutline ) { float flOutlineParms[8] = { GetFloatParam( info.m_nOutlineStart0, params ), GetFloatParam( info.m_nOutlineStart1, params ), GetFloatParam( info.m_nOutlineEnd0, params ), GetFloatParam( info.m_nOutlineEnd1, params ), 0,0,0, GetFloatParam( info.m_nOutlineAlpha, params ) }; if ( info.m_nOutlineColor != -1 ) { params[info.m_nOutlineColor]->GetVecValue( flOutlineParms + 4, 3 ); } pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 2, flOutlineParms, 2 ); } if ( bHasSoftEdges ) { pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 4, GetFloatParam( info.m_nEdgeSoftnessStart, params ), GetFloatParam( info.m_nEdgeSoftnessEnd, params ), 0,0 ); } } // parallax and cubemap light scale mapping parms (c20) if ( bParallaxMapping || (envmap_variant == 2) ) { pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 20, GetFloatParam( info.m_nHeightScale, params), GetFloatParam( info.m_nEnvMapLightScale, params), 0, 0 ); } // texture binds if( hasBaseTexture ) { pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER0, info.m_nBaseTexture, info.m_nBaseTextureFrame ); } // handle mat_fullbright 2 bool bLightingOnly = mat_fullbright.GetInt() == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE ); if( bLightingOnly ) { // BASE TEXTURE if( hasSelfIllum ) { pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY_ALPHA_ZERO ); } else { pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER0, TEXTURE_GREY ); } // BASE TEXTURE 2 if( hasBaseTexture2 ) { pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER7, TEXTURE_GREY ); } // DETAIL TEXTURE if( hasDetailTexture ) { pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER12, TEXTURE_GREY ); } // disable color modulation float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color ); // turn off environment mapping envmapTintVal[0] = 0.0f; envmapTintVal[1] = 0.0f; envmapTintVal[2] = 0.0f; } // always set the transform for detail textures since I'm assuming that you'll // always have a detailscale. if( hasDetailTexture ) { pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureScaledTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBaseTextureTransform, info.m_nDetailScale ); } if( hasBaseTexture2 ) { pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER7, info.m_nBaseTexture2, info.m_nBaseTexture2Frame ); } if( hasDetailTexture ) { pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER12, info.m_nDetail, info.m_nDetailFrame ); } if( hasBump || hasNormalMapAlphaEnvmapMask ) { if( !g_pConfig->m_bFastNoBump ) { pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, info.m_nBumpmap, info.m_nBumpFrame ); } else { if( hasSSBump ) { pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_SSBUMP_FLAT ); } else { pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_NORMALMAP_FLAT ); } } } if( hasBump2 ) { if( !g_pConfig->m_bFastNoBump ) { pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nBumpmap2, info.m_nBumpFrame2 ); } else { if( hasSSBump ) { pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_NORMALMAP_FLAT ); } else { pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_SSBUMP_FLAT ); } } } if( hasBumpMask ) { if( !g_pConfig->m_bFastNoBump ) { pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER8, info.m_nBumpMask, -1 ); } else { // this doesn't make sense pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER8, TEXTURE_NORMALMAP_FLAT ); } } if( hasEnvmapMask ) { pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, info.m_nEnvmapMask, info.m_nEnvmapMaskFrame ); } if ( hasLightWarpTexture ) { pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER6, info.m_nLightWarpTexture, -1 ); } if ( bHasBlendModulateTexture ) { pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, info.m_nBlendModulateTexture, -1 ); } if ( hasFlashlight && IsX360() ) { pContextData->m_SemiStaticCmdsOut.SetVertexShaderFlashlightState( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 ); CBCmdSetPixelShaderFlashlightState_t state; state.m_LightSampler = SHADER_SAMPLER13; state.m_DepthSampler = SHADER_SAMPLER14; state.m_ShadowNoiseSampler = SHADER_SAMPLER15; state.m_nColorConstant = 28; state.m_nAttenConstant = 13; state.m_nOriginConstant = 14; state.m_nDepthTweakConstant = 19; state.m_nScreenScaleConstant = 31; state.m_nWorldToTextureConstant = -1; state.m_bFlashlightNoLambert = false; state.m_bSinglePassFlashlight = bSinglePassFlashlight; pContextData->m_SemiStaticCmdsOut.SetPixelShaderFlashlightState( state ); } pContextData->m_SemiStaticCmdsOut.End(); } } DYNAMIC_STATE { CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut; DynamicCmdsOut.Call( pContextData->m_pStaticCmds ); DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() ); bool hasEnvmap = params[info.m_nEnvmap]->IsTexture(); if( hasEnvmap ) { DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER2, info.m_nEnvmap, info.m_nEnvmapFrame ); } bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath; int nFixedLightingMode = pShaderAPI->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING ); if( nFixedLightingMode != ENABLE_FIXED_LIGHTING_NONE ) { if ( pContextData->m_bPixelShaderForceFastPathBecauseOutline ) { nFixedLightingMode = ENABLE_FIXED_LIGHTING_NONE; } else { bVertexShaderFastPath = false; } } bool bWorldNormal = ( nFixedLightingMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH ); if ( bWorldNormal && IsPC() ) { float vEyeDir[4]; pShaderAPI->GetWorldSpaceCameraDirection( vEyeDir ); float flFarZ = pShaderAPI->GetFarZ(); vEyeDir[0] /= flFarZ; // Divide by farZ for SSAO algorithm vEyeDir[1] /= flFarZ; vEyeDir[2] /= flFarZ; DynamicCmdsOut.SetVertexShaderConstant4( 12, vEyeDir[0], vEyeDir[1], vEyeDir[2], 1.0f ); } MaterialFogMode_t fogType = pShaderAPI->GetSceneFogMode(); if( bDeferredActive ) { DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_deferred_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_deferred_vs30 ); } else { DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs30 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath ); SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_vs30 ); } bool bPixelShaderFastPath = pContextData->m_bPixelShaderFastPath; if ( nFixedLightingMode != ENABLE_FIXED_LIGHTING_NONE ) { bPixelShaderFastPath = false; } bool bWriteDepthToAlpha; bool bWriteWaterFogToAlpha; if( pContextData->m_bFullyOpaque ) { bWriteDepthToAlpha = pShaderAPI->ShouldWriteDepthToDestAlpha(); bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z); AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." ); } else { //can't write a special value to dest alpha if we're actually using as-intended alpha bWriteDepthToAlpha = false; bWriteWaterFogToAlpha = false; } if( bHasFoW ) { if( ( info.m_nFoW != -1 ) && ( params[ info.m_nFoW ]->IsTexture() != 0 ) ) DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER13, info.m_nFoW, -1 ); else DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER13, TEXTURE_WHITE ); float vFoWSize[ 4 ]; Vector vMins = pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_GLOBAL_FOW_MINS ); Vector vMaxs = pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_GLOBAL_FOW_MAXS ); vFoWSize[ 0 ] = vMins.x; vFoWSize[ 1 ] = vMins.y; vFoWSize[ 2 ] = vMaxs.x - vMins.x; vFoWSize[ 3 ] = vMaxs.y - vMins.y; DynamicCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_SHADER_SPECIFIC_CONST_12, vFoWSize ); } if( bDeferredActive ) { DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER14, GetDeferredExt()->GetTexture_LightAccum(), 0 ); DynamicCmdsOut.BindTexture( pShader, SHADER_SAMPLER15, GetDeferredExt()->GetTexture_LightAccum2(), 0 ); //DynamicCmdsOut.BindStandardTexture( SHADER_SAMPLER14, TEXTURE_WHITE ); int x, y, w, t; pShaderAPI->GetCurrentViewport( x, y, w, t ); float fl1[4] = { 1.0f / w, 1.0f / t, 0, 0 }; DynamicCmdsOut.SetPixelShaderConstant( PSREG_UBERLIGHT_SMOOTH_EDGE_0, fl1 ); } bool bFlashlightShadows = false; bool bUberlight = false; if( hasFlashlight && IsX360() ) { pShaderAPI->GetFlashlightShaderInfo( &bFlashlightShadows, &bUberlight ); } else { // only do ambient light when not using flashlight static ConVarRef mat_ambient_light_r_forced( "mat_ambient_light_r_forced" ); static ConVarRef mat_ambient_light_g_forced( "mat_ambient_light_g_forced" ); static ConVarRef mat_ambient_light_b_forced( "mat_ambient_light_b_forced" ); float vAmbientColor[4] = { mat_ambient_light_r_forced.GetFloat() != -1.0f ? mat_ambient_light_r_forced.GetFloat() : mat_ambient_light_r.GetFloat(), mat_ambient_light_g_forced.GetFloat() != -1.0f ? mat_ambient_light_g_forced.GetFloat() : mat_ambient_light_g.GetFloat(), mat_ambient_light_b_forced.GetFloat() != -1.0f ? mat_ambient_light_b_forced.GetFloat() : mat_ambient_light_b.GetFloat(), 0.0f }; if ( mat_fullbright.GetInt() == 1 ) { vAmbientColor[0] = vAmbientColor[1] = vAmbientColor[2] = 0.0f; } DynamicCmdsOut.SetPixelShaderConstant( 31, vAmbientColor, 1 ); } float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue(); if( bDeferredActive ) { DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedgeneric_deferred_ps30); SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath || pContextData->m_bPixelShaderForceFastPathBecauseOutline ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); // Don't write fog to alpha if we're using translucency SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, /*bFlashlightShadows*/ 0 ); SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_deferred_ps30 ); } else { DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedgeneric_ps30 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath || pContextData->m_bPixelShaderForceFastPathBecauseOutline ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f ); // Don't write fog to alpha if we're using translucency SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bWriteDepthToAlpha ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITEWATERFOGTODESTALPHA, bWriteWaterFogToAlpha ); SET_DYNAMIC_PIXEL_SHADER_COMBO( FLASHLIGHTSHADOWS, bFlashlightShadows ); SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_ps30 ); } DynamicCmdsOut.End(); pShaderAPI->ExecuteCommandBuffer( DynamicCmdsOut.Base() ); } pShader->Draw(); if( !bDeferredActive && IsPC() && (IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0) && pContextData->m_bFullyOpaqueWithoutAlphaTest ) { //Alpha testing makes it so we can't write to dest alpha //Writing to depth makes it so later polygons can't write to dest alpha either //This leads to situations with garbage in dest alpha. //Fix it now by converting depth to dest alpha for any pixels that just wrote. pShader->DrawEqualDepthToDestAlpha(); } }
void CBlobParticleNetworkBypassAutoGame::PreRender( void ) { if( engine->IsRecordingDemo() && g_pBlobNetworkBypass->bDataUpdated ) { //record the update, TODO: compress the data by omitting the holes int iMaxIndex = MAX(g_pBlobNetworkBypass->iHighestIndexUsed, m_iOldHighestIndexUsed); int iBitMax = (iMaxIndex / BITS_PER_INT) + 1; size_t iDataSize = sizeof( int ) + sizeof( float ) + sizeof( int ) + sizeof( int ) + (sizeof( int ) * iBitMax) + iMaxIndex*( sizeof( Vector ) + sizeof( float ) + sizeof( Vector ) ); uint8 *pData = new uint8 [iDataSize]; uint8 *pWrite = pData; //let the receiver know how much of each array to expect *(int *)pWrite = LittleDWord( iMaxIndex ); pWrite += sizeof( int ); //write the update timestamp *(float *)pWrite = g_pBlobNetworkBypass->fTimeDataUpdated; pWrite += sizeof( float ); //record usage information, also helps us effectively compress the subsequent data by omitting the holes. *(int *)pWrite = LittleDWord( g_pBlobNetworkBypass->iHighestIndexUsed ); pWrite += sizeof( int ); *(int *)pWrite = LittleDWord( g_pBlobNetworkBypass->iNumParticlesAllocated ); pWrite += sizeof( int ); int *pIntParser = (int *)&g_pBlobNetworkBypass->bCurrentlyInUse; for( int i = 0; i != iBitMax; ++i ) { //convert and write the bitfield integers *(int *)pWrite = LittleDWord( *pIntParser ); pWrite += sizeof( int ); ++pIntParser; } //write positions memcpy( pWrite, g_pBlobNetworkBypass->vParticlePositions, sizeof( Vector ) * iMaxIndex ); pWrite += sizeof( Vector ) * iMaxIndex; //write radii memcpy( pWrite, g_pBlobNetworkBypass->vParticleRadii, sizeof( float ) * iMaxIndex ); pWrite += sizeof( float ) * iMaxIndex; //write closest surface direction memcpy( pWrite, g_pBlobNetworkBypass->vParticleClosestSurfDir, sizeof( Vector ) * iMaxIndex ); pWrite += sizeof( Vector ) * iMaxIndex; engine->RecordDemoCustomData( BlobNetworkBypass_CustomDemoDataCallback, pData, iDataSize ); Assert( pWrite == (pData + iDataSize) ); delete []pData; } //invalidate interpolation on freed indices, do a quick update for brand new indices { //operate on smaller chunks based on the assumption that LARGE portions of the end of the bitvecs are empty CBitVec<BITS_PER_INT> *pCurrentlyInUse = (CBitVec<BITS_PER_INT> *)&g_pBlobNetworkBypass->bCurrentlyInUse; CBitVec<BITS_PER_INT> *pOldInUse = (CBitVec<BITS_PER_INT> *)&m_bOldInUse; int iStop = (MAX(g_pBlobNetworkBypass->iHighestIndexUsed, m_iOldHighestIndexUsed) / BITS_PER_INT) + 1; int iBaseIndex = 0; //float fNewIndicesUpdateTime = g_pBlobNetworkBypass->bPositionsUpdated ? g_pBlobNetworkBypass->fTimeDataUpdated : gpGlobals->curtime; for( int i = 0; i != iStop; ++i ) { CBitVec<BITS_PER_INT> bInUseXOR; pCurrentlyInUse->Xor( *pOldInUse, &bInUseXOR ); //find bits that changed int j = 0; while( (j = bInUseXOR.FindNextSetBit( j )) != -1 ) { int iChangedUsageIndex = iBaseIndex + j; if( pOldInUse->IsBitSet( iChangedUsageIndex ) ) { //index no longer used g_BlobParticleInterpolation.vInterpolatedPositions[iChangedUsageIndex] = vec3_origin; s_PositionInterpolators[iChangedUsageIndex].ClearHistory(); g_BlobParticleInterpolation.vInterpolatedRadii[iChangedUsageIndex] = 1.0f; s_RadiusInterpolators[iChangedUsageIndex].ClearHistory(); g_BlobParticleInterpolation.vInterpolatedClosestSurfDir[iChangedUsageIndex] = vec3_origin; s_ClosestSurfDirInterpolators[iChangedUsageIndex].ClearHistory(); } else { //index just started being used. Assume we got an out of band update to the position g_BlobParticleInterpolation.vInterpolatedPositions[iChangedUsageIndex] = g_pBlobNetworkBypass->vParticlePositions[iChangedUsageIndex]; s_PositionInterpolators[iChangedUsageIndex].Reset( gpGlobals->curtime ); g_BlobParticleInterpolation.vInterpolatedRadii[iChangedUsageIndex] = g_pBlobNetworkBypass->vParticleRadii[iChangedUsageIndex]; s_RadiusInterpolators[iChangedUsageIndex].Reset( gpGlobals->curtime ); g_BlobParticleInterpolation.vInterpolatedClosestSurfDir[iChangedUsageIndex] = g_pBlobNetworkBypass->vParticleClosestSurfDir[iChangedUsageIndex]; s_ClosestSurfDirInterpolators[iChangedUsageIndex].Reset( gpGlobals->curtime ); //s_PositionInterpolators[iChangedUsageIndex].NoteChanged( gpGlobals->curtime, fNewIndicesUpdateTime, true ); } ++j; if( j == BITS_PER_INT ) break; } iBaseIndex += BITS_PER_INT; ++pCurrentlyInUse; ++pOldInUse; } memcpy( &m_bOldInUse, &g_pBlobNetworkBypass->bCurrentlyInUse, sizeof( m_bOldInUse ) ); m_iOldHighestIndexUsed = g_pBlobNetworkBypass->iHighestIndexUsed; } if( g_pBlobNetworkBypass->iHighestIndexUsed == 0 ) return; static ConVarRef cl_interpREF( "cl_interp" ); //now do the interpolation of positions still in use { float fInterpTime = gpGlobals->curtime - cl_interpREF.GetFloat(); CBitVec<BITS_PER_INT> *pIntParser = (CBitVec<BITS_PER_INT> *)&g_pBlobNetworkBypass->bCurrentlyInUse; int iStop = (g_pBlobNetworkBypass->iHighestIndexUsed / BITS_PER_INT) + 1; int iBaseIndex = 0; for( int i = 0; i != iStop; ++i ) { int j = 0; while( (j = pIntParser->FindNextSetBit( j )) != -1 ) { int iUpdateIndex = iBaseIndex + j; if( g_pBlobNetworkBypass->bDataUpdated ) { g_BlobParticleInterpolation.vInterpolatedPositions[iUpdateIndex] = g_pBlobNetworkBypass->vParticlePositions[iUpdateIndex]; s_PositionInterpolators[iUpdateIndex].NoteChanged( gpGlobals->curtime, g_pBlobNetworkBypass->fTimeDataUpdated, true ); g_BlobParticleInterpolation.vInterpolatedRadii[iUpdateIndex] = g_pBlobNetworkBypass->vParticleRadii[iUpdateIndex]; s_RadiusInterpolators[iUpdateIndex].NoteChanged( gpGlobals->curtime, g_pBlobNetworkBypass->fTimeDataUpdated, true ); g_BlobParticleInterpolation.vInterpolatedClosestSurfDir[iUpdateIndex] = g_pBlobNetworkBypass->vParticleClosestSurfDir[iUpdateIndex]; s_ClosestSurfDirInterpolators[iUpdateIndex].NoteChanged( gpGlobals->curtime, g_pBlobNetworkBypass->fTimeDataUpdated, true ); //s_PositionInterpolators[iUpdateIndex].AddToHead( gpGlobals->curtime, &g_pBlobNetworkBypass->vParticlePositions[iUpdateIndex], false ); } s_PositionInterpolators[iUpdateIndex].Interpolate( fInterpTime ); s_RadiusInterpolators[iUpdateIndex].Interpolate( fInterpTime ); s_ClosestSurfDirInterpolators[iUpdateIndex].Interpolate( fInterpTime ); ++j; if( j == BITS_PER_INT ) break; } iBaseIndex += BITS_PER_INT; ++pIntParser; } g_pBlobNetworkBypass->bDataUpdated = false; } }
//----------------------------------------------------------------------------- // Purpose: Advanced joystick setup //----------------------------------------------------------------------------- void CInput::Joystick_Advanced(void) { // called whenever an update is needed int i; DWORD dwTemp; if ( IsX360() ) { // Xbox always uses a joystick in_joystick.SetValue( 1 ); } // Initialize all the maps for ( i = 0; i < MAX_JOYSTICK_AXES; i++ ) { m_rgAxes[i].AxisMap = GAME_AXIS_NONE; m_rgAxes[i].ControlMap = JOY_ABSOLUTE_AXIS; } if ( !joy_advanced.GetBool() ) { // default joystick initialization // 2 axes only with joystick control m_rgAxes[JOY_AXIS_X].AxisMap = GAME_AXIS_YAW; m_rgAxes[JOY_AXIS_Y].AxisMap = GAME_AXIS_FORWARD; } else { if ( Q_stricmp( joy_name.GetString(), "joystick") != 0 ) { // notify user of advanced controller Msg( "Using joystick '%s' configuration\n", joy_name.GetString() ); } // advanced initialization here // data supplied by user via joy_axisn cvars dwTemp = ( joy_movement_stick.GetBool() ) ? (DWORD)joy_advaxisu.GetInt() : (DWORD)joy_advaxisx.GetInt(); m_rgAxes[JOY_AXIS_X].AxisMap = dwTemp & 0x0000000f; m_rgAxes[JOY_AXIS_X].ControlMap = dwTemp & JOY_RELATIVE_AXIS; DescribeJoystickAxis( "JOY_AXIS_X", &m_rgAxes[JOY_AXIS_X] ); dwTemp = ( joy_movement_stick.GetBool() ) ? (DWORD)joy_advaxisr.GetInt() : (DWORD)joy_advaxisy.GetInt(); m_rgAxes[JOY_AXIS_Y].AxisMap = dwTemp & 0x0000000f; m_rgAxes[JOY_AXIS_Y].ControlMap = dwTemp & JOY_RELATIVE_AXIS; DescribeJoystickAxis( "JOY_AXIS_Y", &m_rgAxes[JOY_AXIS_Y] ); dwTemp = (DWORD)joy_advaxisz.GetInt(); m_rgAxes[JOY_AXIS_Z].AxisMap = dwTemp & 0x0000000f; m_rgAxes[JOY_AXIS_Z].ControlMap = dwTemp & JOY_RELATIVE_AXIS; DescribeJoystickAxis( "JOY_AXIS_Z", &m_rgAxes[JOY_AXIS_Z] ); dwTemp = ( joy_movement_stick.GetBool() ) ? (DWORD)joy_advaxisy.GetInt() : (DWORD)joy_advaxisr.GetInt(); m_rgAxes[JOY_AXIS_R].AxisMap = dwTemp & 0x0000000f; m_rgAxes[JOY_AXIS_R].ControlMap = dwTemp & JOY_RELATIVE_AXIS; DescribeJoystickAxis( "JOY_AXIS_R", &m_rgAxes[JOY_AXIS_R] ); dwTemp = ( joy_movement_stick.GetBool() ) ? (DWORD)joy_advaxisx.GetInt() : (DWORD)joy_advaxisu.GetInt(); m_rgAxes[JOY_AXIS_U].AxisMap = dwTemp & 0x0000000f; m_rgAxes[JOY_AXIS_U].ControlMap = dwTemp & JOY_RELATIVE_AXIS; DescribeJoystickAxis( "JOY_AXIS_U", &m_rgAxes[JOY_AXIS_U] ); dwTemp = (DWORD)joy_advaxisv.GetInt(); m_rgAxes[JOY_AXIS_V].AxisMap = dwTemp & 0x0000000f; m_rgAxes[JOY_AXIS_V].ControlMap = dwTemp & JOY_RELATIVE_AXIS; DescribeJoystickAxis( "JOY_AXIS_V", &m_rgAxes[JOY_AXIS_V] ); Msg( "Advanced Joystick settings initialized\n" ); } // If we have an xcontroller, load the cfg file if it hasn't been loaded. static ConVarRef var( "joy_xcontroller_found" ); if ( var.IsValid() && var.GetBool() && in_joystick.GetBool() ) { if ( joy_xcontroller_cfg_loaded.GetInt() < 2 ) { engine->ClientCmd_Unrestricted( "exec 360controller.cfg" ); if ( IsLinux () ) { engine->ClientCmd_Unrestricted( "exec 360controller-linux.cfg" ); } joy_xcontroller_cfg_loaded.SetValue( 2 ); } } else if ( joy_xcontroller_cfg_loaded.GetInt() > 0 ) { engine->ClientCmd_Unrestricted( "exec undo360controller.cfg" ); joy_xcontroller_cfg_loaded.SetValue( 0 ); } }
void CDHLProjectile::PhysicsSimulate( void ) { //------------------------------------------------------------------------------- //Our own movement/physics simulation! //------------------------------------------------------------------------------- #ifdef CLIENT_DLL if ( m_bCollided ) return; if ( !m_pShooter && m_hShooter ) m_pShooter = m_hShooter.Get(); #else if ( m_flRemoveAt > 0.0f ) { if ( m_flRemoveAt < gpGlobals->curtime ) { m_flRemoveAt = 0.0f; SUB_Remove(); } return; } if ( IsMarkedForDeletion() ) return; #endif float flFrametime = gpGlobals->frametime; //Scale for slow motion if ( DHLRules() ) { if ( (m_iType == DHL_PROJECTILE_TYPE_BULLET || m_iType == DHL_PROJECTILE_TYPE_PELLET) ) flFrametime *= (dhl_bulletspeed.GetFloat() * DHLRules()->GetTimescale()); else if ( m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE ) flFrametime *= (dhl_knifespeed.GetFloat() * DHLRules()->GetTimescale()); else flFrametime *= DHLRules()->GetTimescale(); } Vector vecDir = vec3_origin; #ifndef CLIENT_DLL Vector vecStartPos = m_vecCurPosition; //This is where we are Vector vecEndPos = m_vecCurPosition; //This is where we're going Vector vecVelocity = m_vecCurVelocity; //Velocity #else Vector vecStartPos = GetLocalOrigin(); //This is where we are Vector vecEndPos = GetLocalOrigin(); //This is where we're going Vector vecVelocity = GetLocalVelocity(); //Velocity #endif //Find out where we should move to if ( vecVelocity != vec3_origin ) { static ConVarRef gravVar( "sv_gravity" ); //Gravity float newZVelocity = vecVelocity.z - ( flFrametime * gravVar.GetFloat() * GetGravity() ); vecVelocity.z = ( (vecVelocity.z + newZVelocity) / 2 ); vecDir = vecVelocity; VectorNormalize( vecDir ); //Gravity needs to be cumulative #ifndef CLIENT_DLL m_vecCurVelocity = vecVelocity; #else SetLocalVelocity( vecVelocity ); #endif vecVelocity *= flFrametime; vecEndPos = vecStartPos + vecVelocity; if ( vecEndPos.IsValid() ) { CTraceFilterSkipTwoEntities movetrfilter( this, m_pShooter, COLLISION_GROUP_NONE ); trace_t movetr; UTIL_TraceLine( vecStartPos, vecEndPos, MASK_SHOT, &movetrfilter, &movetr ); #ifndef CLIENT_DLL //Trace to triggers so we can hit surf glass and such CTakeDamageInfo triggerInfo( this, GetOwnerEntity(), m_iDamage, DMG_BULLET ); if ( m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE ) { //CalculateMeleeDamageForce( &triggerInfo, vecDir, movetr.endpos, 0.7f ); Vector vecForce = vecDir; VectorNormalize( vecForce ); //vecForce *= 10.0f; triggerInfo.SetDamageForce( vecForce ); } else CalculateBulletDamageForce( &triggerInfo, m_iAmmoType, vecDir, movetr.endpos, 1.0f ); triggerInfo.SetDamagePosition( movetr.endpos ); TraceAttackToTriggers( triggerInfo, movetr.startpos, movetr.endpos, vecDir ); #else //Hit ragdolls on the client CBaseEntity* pEnt = DHL_FX_AffectRagdolls( movetr.endpos, movetr.startpos, DMG_BULLET, &m_RagdollHitList ); //Keep track of ones we've hit if ( pEnt ) m_RagdollHitList.AddToTail( pEnt ); #endif if ( movetr.DidHit() ) if ( OnTouch( movetr, false, &movetrfilter ) ) return; MoveProjectileToPosition( vecEndPos ); m_flDistanceTravelled += vecEndPos.DistTo( vecStartPos ); #ifndef CLIENT_DLL //On rare occasions the projectile likes to fly right through the world and keep going forever, causing a memory leak if ( m_flDistanceTravelled > MAX_TRACE_LENGTH ) { SUB_Remove(); //SetThink( &CDHLProjectile::SUB_Remove ); //SetNextThink( gpGlobals->curtime + 0.1 ); } #endif } //Simulate Angles //QAngle angles; #ifdef CLIENT_DLL QAngle angles = GetLocalAngles(); //VectorAngles( vecDir, angles ); //angles.z = GetLocalAngles().z; //Vector conversion loses z QAngle angVel = GetLocalAngularVelocity(); angles += angVel * flFrametime; SetLocalAngles( angles ); SetNetworkAngles( angles ); #endif } }
//----------------------------------------------------------------------------- // Purpose: Render current view into specified rectangle // Input : *rect - is computed by CVideoMode_Common::GetClientViewRect() //----------------------------------------------------------------------------- void CViewRender::Render( vrect_t *rect ) { Assert(s_DbgSetupOrigin == m_View.origin); Assert(s_DbgSetupAngles == m_View.angles); VPROF_BUDGET( "CViewRender::Render", "CViewRender::Render" ); tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); vrect_t vr = *rect; // Stub out the material system if necessary. CMatStubHandler matStub; engine->EngineStats_BeginFrame(); // Assume normal vis m_bForceNoVis = false; C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); // Set for console commands, etc. render->SetMainView ( m_View.origin, m_View.angles ); for( StereoEye_t eEye = GetFirstEye(); eEye <= GetLastEye(); eEye = (StereoEye_t)(eEye+1) ) { CViewSetup &view = GetView( eEye ); #if 0 && defined( CSTRIKE_DLL ) const bool bPlayingBackReplay = g_pEngineClientReplay && g_pEngineClientReplay->IsPlayingReplayDemo(); if ( pPlayer && !bPlayingBackReplay ) { C_BasePlayer *pViewTarget = pPlayer; if ( pPlayer->IsObserver() && pPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) { pViewTarget = dynamic_cast<C_BasePlayer*>( pPlayer->GetObserverTarget() ); } if ( pViewTarget ) { float targetFOV = (float)pViewTarget->m_iFOV; if ( targetFOV == 0 ) { // FOV of 0 means use the default FOV targetFOV = g_pGameRules->DefaultFOV(); } float deltaFOV = view.fov - m_flLastFOV; float FOVDirection = targetFOV - pViewTarget->m_iFOVStart; // Clamp FOV changes to stop FOV oscillation if ( ( deltaFOV < 0.0f && FOVDirection > 0.0f ) || ( deltaFOV > 0.0f && FOVDirection < 0.0f ) ) { view.fov = m_flLastFOV; } // Catch case where FOV overshoots its target FOV if ( ( view.fov < targetFOV && FOVDirection <= 0.0f ) || ( view.fov > targetFOV && FOVDirection >= 0.0f ) ) { view.fov = targetFOV; } m_flLastFOV = view.fov; } } #endif static ConVarRef sv_restrict_aspect_ratio_fov( "sv_restrict_aspect_ratio_fov" ); float aspectRatio = engine->GetScreenAspectRatio() * 0.75f; // / (4/3) float limitedAspectRatio = aspectRatio; if ( ( sv_restrict_aspect_ratio_fov.GetInt() > 0 && engine->IsWindowedMode() && gpGlobals->maxClients > 1 ) || sv_restrict_aspect_ratio_fov.GetInt() == 2 ) { limitedAspectRatio = MIN( aspectRatio, 1.85f * 0.75f ); // cap out the FOV advantage at a 1.85:1 ratio (about the widest any legit user should be) } view.fov = ScaleFOVByWidthRatio( view.fov, limitedAspectRatio ); view.fovViewmodel = ScaleFOVByWidthRatio( view.fovViewmodel, aspectRatio ); // Let the client mode hook stuff. g_pClientMode->PreRender(&view); g_pClientMode->AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height ); ToolFramework_AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height ); float flViewportScale = mat_viewportscale.GetFloat(); view.m_nUnscaledX = vr.x; view.m_nUnscaledY = vr.y; view.m_nUnscaledWidth = vr.width; view.m_nUnscaledHeight = vr.height; switch( eEye ) { case STEREO_EYE_MONO: { #if 0 // Good test mode for debugging viewports that are not full-size. view.width = vr.width * flViewportScale * 0.75f; view.height = vr.height * flViewportScale * 0.75f; view.x = vr.x + view.width * 0.10f; view.y = vr.y + view.height * 0.20f; #else view.x = vr.x * flViewportScale; view.y = vr.y * flViewportScale; view.width = vr.width * flViewportScale; view.height = vr.height * flViewportScale; #endif float engineAspectRatio = engine->GetScreenAspectRatio(); view.m_flAspectRatio = ( engineAspectRatio > 0.0f ) ? engineAspectRatio : ( (float)view.width / (float)view.height ); } break; case STEREO_EYE_RIGHT: case STEREO_EYE_LEFT: { g_pSourceVR->GetViewportBounds( (ISourceVirtualReality::VREye)(eEye - 1 ), &view.x, &view.y, &view.width, &view.height ); view.m_nUnscaledWidth = view.width; view.m_nUnscaledHeight = view.height; view.m_nUnscaledX = view.x; view.m_nUnscaledY = view.y; } break; default: Assert ( false ); break; } // if we still don't have an aspect ratio, compute it from the view size if( view.m_flAspectRatio <= 0.f ) view.m_flAspectRatio = (float)view.width / (float)view.height; int nClearFlags = VIEW_CLEAR_DEPTH | VIEW_CLEAR_STENCIL; if( gl_clear_randomcolor.GetBool() ) { CMatRenderContextPtr pRenderContext( materials ); pRenderContext->ClearColor3ub( rand()%256, rand()%256, rand()%256 ); pRenderContext->ClearBuffers( true, false, false ); pRenderContext->Release(); } else if ( gl_clear.GetBool() ) { nClearFlags |= VIEW_CLEAR_COLOR; } else if ( IsPosix() ) { MaterialAdapterInfo_t adapterInfo; materials->GetDisplayAdapterInfo( materials->GetCurrentAdapter(), adapterInfo ); // On Posix, on ATI, we always clear color if we're antialiasing if ( adapterInfo.m_VendorID == 0x1002 ) { if ( g_pMaterialSystem->GetCurrentConfigForVideoCard().m_nAASamples > 0 ) { nClearFlags |= VIEW_CLEAR_COLOR; } } } // Determine if we should draw view model ( client mode override ) bool drawViewModel = g_pClientMode->ShouldDrawViewModel(); if ( cl_leveloverview.GetFloat() > 0 ) { SetUpOverView(); nClearFlags |= VIEW_CLEAR_COLOR; drawViewModel = false; } // Apply any player specific overrides if ( pPlayer ) { // Override view model if necessary if ( !pPlayer->m_Local.m_bDrawViewmodel ) { drawViewModel = false; } } int flags = 0; if( eEye == STEREO_EYE_MONO || eEye == STEREO_EYE_LEFT || ( g_ClientVirtualReality.ShouldRenderHUDInWorld() ) ) { flags = RENDERVIEW_DRAWHUD; } if ( drawViewModel ) { flags |= RENDERVIEW_DRAWVIEWMODEL; } if( eEye == STEREO_EYE_RIGHT ) { // we should use the monitor view from the left eye for both eyes flags |= RENDERVIEW_SUPPRESSMONITORRENDERING; } RenderView( view, nClearFlags, flags ); if ( UseVR() ) { bool bDoUndistort = ! engine->IsTakingScreenshot(); if ( bDoUndistort ) { g_ClientVirtualReality.PostProcessFrame( eEye ); } // logic here all cloned from code in viewrender.cpp around RenderHUDQuad: // figure out if we really want to draw the HUD based on freeze cam bool bInFreezeCam = ( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM ); // draw the HUD after the view model so its "I'm closer" depth queues work right. if( !bInFreezeCam && g_ClientVirtualReality.ShouldRenderHUDInWorld() ) { // TODO - a bit of a shonky test - basically trying to catch the main menu, the briefing screen, the loadout screen, etc. bool bTranslucent = !g_pMatSystemSurface->IsCursorVisible(); g_ClientVirtualReality.OverlayHUDQuadWithUndistort( view, bDoUndistort, g_pClientMode->ShouldBlackoutAroundHUD(), bTranslucent ); } } } // TODO: should these be inside or outside the stereo eye stuff? g_pClientMode->PostRender(); engine->EngineStats_EndFrame(); #if !defined( _X360 ) // Stop stubbing the material system so we can see the budget panel matStub.End(); #endif // Draw all of the UI stuff "fullscreen" // (this is not health, ammo, etc. Nor is it pre-game briefing interface stuff - this is the stuff that appears when you hit Esc in-game) // In stereo mode this is rendered inside of RenderView so it goes into the render target if( !g_ClientVirtualReality.ShouldRenderHUDInWorld() ) { CViewSetup view2d; view2d.x = rect->x; view2d.y = rect->y; view2d.width = rect->width; view2d.height = rect->height; render->Push2DView( view2d, 0, NULL, GetFrustum() ); render->VGui_Paint( PAINT_UIPANELS | PAINT_CURSOR ); render->PopView( GetFrustum() ); } }
//========================================================= //========================================================= bool C_GameInstructor::WriteSaveData() { if ( engine->IsPlayingDemo() ) return false; if ( !m_bDirtySaveData ) return true; #ifdef _X360 float flPlatTime = Plat_FloatTime(); static ConVarRef host_write_last_time( "host_write_last_time" ); if ( host_write_last_time.IsValid() ) { float flTimeSinceLastWrite = flPlatTime - host_write_last_time.GetFloat(); if ( flTimeSinceLastWrite < 3.5f ) { // Prevent writing to the same storage device twice in less than 3 second succession for TCR success! // This happens after leaving a game in splitscreen. //DevMsg( "Waiting to write Game Instructor for splitscreen slot %d... (%.1f seconds remain)\n", m_nSplitScreenSlot, 3.5f - flTimeSinceLastWrite ); return false; } } #endif // Always mark as clean state to avoid re-entry on // subsequent frames when storage device might be // in a yet-unmounted state. m_bDirtySaveData = false; #ifdef _X360 DevMsg( "Write Game Instructor for splitscreen slot %d at time: %.1f\n", m_nSplitScreenSlot, flPlatTime ); if ( m_nSplitScreenSlot < 0 ) return false; if ( m_nSplitScreenSlot >= (int) XBX_GetNumGameUsers() ) return false; int iController = XBX_GetUserId( m_nSplitScreenSlot ); if ( iController < 0 || XBX_GetUserIsGuest( iController ) ) { // Can't save data for guests return false; } DWORD nStorageDevice = XBX_GetStorageDeviceId( iController ); if ( !XBX_DescribeStorageDevice( nStorageDevice ) ) return false; #endif // Build key value data to save KeyValues *data = new KeyValues( "Game Instructor Counts" ); KeyValues::AutoDelete autoDelete(data); for ( int i = 0; i < m_Lessons.Count(); ++i ) { CBaseLesson *pLesson = m_Lessons[i]; int iDisplayCount = pLesson->GetDisplayCount(); int iSuccessCount = pLesson->GetSuccessCount(); if ( iDisplayCount || iSuccessCount ) { // We've got some data worth saving KeyValues *pKVData = new KeyValues( pLesson->GetName() ); if ( iDisplayCount ) pKVData->SetInt( "display", iDisplayCount ); if ( iSuccessCount ) pKVData->SetInt( "success", iSuccessCount ); data->AddSubKey( pKVData ); } } // Save it! CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); data->RecursiveSaveToFile( buf, 0 ); char szFilename[_MAX_PATH]; #ifdef _X360 if ( IsX360() ) { XBX_MakeStorageContainerRoot( iController, XBX_USER_SETTINGS_CONTAINER_DRIVE, szFilename, sizeof( szFilename ) ); int nLen = strlen( szFilename ); Q_snprintf( szFilename + nLen, sizeof( szFilename ) - nLen, ":\\game_instructor_counts.txt" ); } else #endif { Q_snprintf( szFilename, sizeof( szFilename ), "save/game_instructor_counts.txt" ); filesystem->CreateDirHierarchy( "save", "MOD" ); } bool bWriteSuccess = filesystem->WriteFile( szFilename, MOD_DIR, buf ); #ifdef _X360 if ( xboxsystem ) { xboxsystem->FinishContainerWrites( iController ); } #endif return bWriteSuccess; }