//-----------------------------------------------------------------------------
// Think for all entities that need it
//-----------------------------------------------------------------------------
void CClientThinkList::PerformThinkFunctions()
{
	VPROF_("Client Thinks", 1, VPROF_BUDGETGROUP_CLIENT_SIM, false, BUDGETFLAG_CLIENT);

	int nMaxList = m_ThinkEntries.Count();
	if ( nMaxList == 0 )
		return;

	++m_nIterEnum;

	// Build a list of entities to think this frame, in order of hierarchy.
	// Do this because the list may be modified during the thinking and also to
	// prevent bad situations where an entity can think more than once in a frame.
	ThinkEntry_t **ppThinkEntryList = (ThinkEntry_t**)stackalloc( nMaxList * sizeof(ThinkEntry_t*) );
	int nThinkCount = 0;
	for ( unsigned short iCur=m_ThinkEntries.Head(); iCur != m_ThinkEntries.InvalidIndex(); iCur = m_ThinkEntries.Next( iCur ) )
	{
		AddEntityToFrameThinkList( &m_ThinkEntries[iCur], false, nThinkCount, ppThinkEntryList );
		Assert( nThinkCount <= nMaxList );
	}

	// While we're in the loop, no changes to the think list are allowed
	m_bInThinkLoop = true;

	// Perform thinks on all entities that need it
	int i;
	for ( i = 0; i < nThinkCount; ++i )
	{
		PerformThinkFunction( ppThinkEntryList[i], gpGlobals->curtime );		
	}

	m_bInThinkLoop = false;

	// Apply changes to the think list
	int nCount = m_aChangeList.Count();
	for ( i = 0; i < nCount; ++i )
	{
		ClientThinkHandle_t hThink = m_aChangeList[i].m_hThink;
		if ( hThink != INVALID_THINK_HANDLE )
		{
			// This can happen if the same think handle was removed twice
			if ( !m_ThinkEntries.IsInList( (unsigned long)hThink ) )
				continue;

			// NOTE: This is necessary for the case where the client entity handle
			// is slammed to NULL during a think interval; the hThink will get stuck
			// in the list and can never leave.
			SetNextClientThink( hThink, m_aChangeList[i].m_flNextTime );
		}
		else
		{
			SetNextClientThink( m_aChangeList[i].m_hEnt, m_aChangeList[i].m_flNextTime );
		}
	}
	m_aChangeList.RemoveAll();

	// Clear out the client-side entity deletion list.
	CleanUpDeleteList();
}
Exemple #2
0
// This is called by cdll_client_int to setup view model origins. This has to be done before
// simulation so entities can access attachment points on view models during simulation.
void CViewRender::OnRenderStart()
{
	VPROF_("CViewRender::OnRenderStart", 2, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0);

    SetUpViews();

	// Adjust mouse sensitivity based upon the current FOV
	C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
	if ( player )
	{
		default_fov.SetValue( player->m_iDefaultFOV );

		//Update our FOV, including any zooms going on
		int iDefaultFOV = default_fov.GetInt();
		int	localFOV	= player->GetFOV();
		int min_fov		= player->GetMinFOV();

		// Don't let it go too low
		localFOV = MAX( min_fov, localFOV );

		gHUD.m_flFOVSensitivityAdjust = 1.0f;
#ifndef _XBOX
		if ( gHUD.m_flMouseSensitivityFactor )
		{
			gHUD.m_flMouseSensitivity = sensitivity.GetFloat() * gHUD.m_flMouseSensitivityFactor;
		}
		else
#endif
		{
			// No override, don't use huge sensitivity
			if ( localFOV == iDefaultFOV )
			{
#ifndef _XBOX
				// reset to saved sensitivity
				gHUD.m_flMouseSensitivity = 0;
#endif
			}
			else
			{  
				// Set a new sensitivity that is proportional to the change from the FOV default and scaled
				//  by a separate compensating factor
				if ( iDefaultFOV == 0 )
				{
					Assert(0); // would divide by zero, something is broken with iDefatulFOV
					iDefaultFOV = 1;
				}
				gHUD.m_flFOVSensitivityAdjust = 
					((float)localFOV / (float)iDefaultFOV) * // linear fov downscale
					zoom_sensitivity_ratio.GetFloat(); // sensitivity scale factor
#ifndef _XBOX
				gHUD.m_flMouseSensitivity = gHUD.m_flFOVSensitivityAdjust * sensitivity.GetFloat(); // regular sensitivity
#endif
			}
		}
	}
}
void CColorCorrectionMgr::ResetColorCorrectionWeights()
{
	VPROF_("ResetColorCorrectionWeights", 2, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0);
	// FIXME: Where should I put this? It needs to happen prior to SimulateEntities()
	// which is where the client thinks for c_colorcorrection + c_colorcorrectionvolumes
	// update the color correction weights.
	CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
	pRenderContext->ResetLookupWeights();
	m_nActiveWeightCount = 0;
	m_bHaveExclusiveWeight = false;
	m_flExclusiveWeight = 0.0f;
	m_colorCorrectionWeights.RemoveAll();
}
//-----------------------------------------------------------------------------
int CAudioMixerWave::MixDataToDevice_( IAudioDevice *pDevice, channel_t *pChannel, int sampleCount, int outputRate, int outputOffset, bool bSkipAllMixing )
{
	// shouldn't be playing this if finished, but return if we are
	if ( m_finished )
		return 0;

	// save this to compute total output
	int startingOffset = outputOffset;

	double inputRate = (pChannel->pitch * m_pData->Source().SampleRate());
	double rate_max = inputRate / outputRate;
	
	// If we are terminating this wave prematurely, then make sure we detect the limit
	if ( m_forcedEndSample )
	{
		// How many total input samples will we need?
		int samplesRequired = (int)(sampleCount * rate_max);
		// will this hit the end?
		if ( m_fsample_index + samplesRequired >= m_forcedEndSample )
		{
			// yes, mark finished and truncate the sample request
			m_finished = true;
			sampleCount = (int)( (m_forcedEndSample - m_fsample_index) / rate_max );
		}
	}

	/*
	Example:
	rate = 1.2, sampleCount = 3 (ie: # of samples to return )

	______load 4 samples_____       ________load 4 samples____     ___load 3 samples__

	0		1		2		3		4		5		6		7		8		9		10		sample_index     (whole samples)

	^         ^         ^        ^        ^         ^         ^         ^         ^
	|         |         |        |        |         |         |         |         |     
	0		 1.2	   2.4      3.6      4.8       6.0       7.2	    8.4		  9.6		m_fsample_index  (rate*sample)
	_______return 3_______      _______return 3_______       _______return 3__________
	 						 ^   ^
							 |   |
	m_sample_loaded_index-----   |     		(after first load 4 samples, this is where pointers are)
		  m_fsample_index---------
	*/
	while ( sampleCount > 0 )
	{	
		bool advanceSample = true;
		int samples_loaded, outputSampleCount;
		char *pData = NULL;
		double fsample_index_prev = m_fsample_index;		// save so we can modify in LoadMixBuffer
		bool bInterpolated_pitch = FUseHighQualityPitch( pChannel );
		double rate;

		VPROF_( bInterpolated_pitch ? "CAudioMixerWave::MixData innerloop interpolated" : "CAudioMixerWave::MixData innerloop not interpolated", 2, VPROF_BUDGETGROUP_OTHER_SOUND, false, BUDGETFLAG_OTHER );

		// process samples in paintbuffer-sized batches
		int sampleCountOut = min( sampleCount, PAINTBUFFER_SIZE );
	
		// cap rate so that we never overflow the input copy buffer.
		rate = MIX_GetMaxRate( rate_max, sampleCountOut );

		if ( m_delaySamples > 0 )
		{
			// If we are preceding sample playback with a delay, 
			// just fill data buffer with 0 value samples.
			// Because there is no pitch shift applied, outputSampleCount == sampleCountOut.
			int num_zero_samples = min( m_delaySamples, sampleCountOut );

			// Decrement delay counter
			m_delaySamples -= num_zero_samples;

			int sampleSize = GetMixSampleSize(); 
			int readBytes = sampleSize * num_zero_samples;

			// make sure we don't overflow temp copy buffer (g_temppaintbuffer)
			Assert ( (TEMP_COPY_BUFFER_SIZE * sizeof(portable_samplepair_t)) > readBytes );
			pData = (char *)g_temppaintbuffer;

			// Now copy in some zeroes
			memset( pData, 0, readBytes );
						
			// we don't pitch shift these samples, so outputSampleCount == samples_loaded
			samples_loaded	  = num_zero_samples;
			outputSampleCount = num_zero_samples;		

			advanceSample = false;

			// the zero samples are at the output rate, so set the input/output ratio to 1.0
			rate = 1.0f;
		}
		else
		{	
			// ask the source for the data...
			// temp buffer req'd by some data loaders
			char copyBuf[AUDIOSOURCE_COPYBUF_SIZE];

			// compute number of new samples to load at 'rate' so we can 
			// output 'sampleCount' samples, from m_fsample_index to fsample_index_end (inclusive)
			int sample_load_request = GetSampleLoadRequest( rate, sampleCountOut, bInterpolated_pitch );

			// return pointer to a new copy buffer (g_temppaintbuffer) loaded with sample_load_request samples +
			// first sample(s), which are always the last sample(s) from the previous load.
			// Always returns sample_load_request samples. Updates m_sample_max_loaded, m_sample_loaded_index.
			pData = LoadMixBuffer( pChannel, sample_load_request, &samples_loaded, copyBuf );

			// LoadMixBuffer should always return requested samples.
			Assert ( !pData || ( samples_loaded == sample_load_request ) );

			outputSampleCount = sampleCountOut;
		}	
		
		// no samples available
		if ( !pData )
		{
			break;
		}
		
		// get sample fraction from 0th sample in copy buffer
		double sampleFraction = m_fsample_index - floor( m_fsample_index );
		
		// if just skipping samples in source, don't mix, just keep reading
		if ( !bSkipAllMixing )
		{
			// mix this data to all active paintbuffers
			// Verify that we won't get a buffer overrun.
			Assert( floor( sampleFraction + RoundToFixedPoint(rate, (outputSampleCount-1), bInterpolated_pitch) ) <= samples_loaded );

			int saveIndex = MIX_GetCurrentPaintbufferIndex();
			for ( int i = 0 ; i < CPAINTBUFFERS; i++ )
			{
				if ( g_paintBuffers[i].factive )
				{
					// mix channel into all active paintbuffers
					MIX_SetCurrentPaintbuffer( i );

					Mix( 
						pDevice,						// Device.
						pChannel,						// Channel.
						pData,							// Input buffer.
						outputOffset,					// Output position.
						FIX_FLOAT( sampleFraction ),	// Iterators.
						FIX_FLOAT( rate ), 
						outputSampleCount,	
						0 );
				}
			}
			MIX_SetCurrentPaintbuffer( saveIndex );
		}

		if ( advanceSample )
		{
			// update sample index to point to the next sample to output
			// if we're not delaying
			// Use fixed point math to make sure we exactly match results of mix
			// iterators.			
			m_fsample_index = fsample_index_prev + RoundToFixedPoint( rate, outputSampleCount, bInterpolated_pitch );
		}

		outputOffset += outputSampleCount;
		sampleCount -= outputSampleCount;
	}

	// Did we run out of samples? if so, mark finished
	if ( sampleCount > 0 )
	{
		m_finished = true;
	}

	// total number of samples mixed !!! at the output clock rate !!!
	return outputOffset - startingOffset;
}
Exemple #5
0
// This is called by cdll_client_int to setup view model origins. This has to be done before
// simulation so entities can access attachment points on view models during simulation.
void CViewRender::OnRenderStart()
{
	VPROF_("CViewRender::OnRenderStart", 2, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0);
	IterateRemoteSplitScreenViewSlots_Push( true );
	FOR_EACH_VALID_SPLITSCREEN_PLAYER( hh )
	{
		ACTIVE_SPLITSCREEN_PLAYER_GUARD_VGUI( hh );

		// This will fill in one of the m_UserView[ hh ] slots
		SetUpView();

		// Adjust mouse sensitivity based upon the current FOV
		C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
		if ( player )
		{
			default_fov.SetValue( player->m_iDefaultFOV );

			//Update our FOV, including any zooms going on
			int iDefaultFOV = default_fov.GetInt();
			int	localFOV	= player->GetFOV();
			int min_fov		= player->GetMinFOV();

			// Don't let it go too low
			localFOV = MAX( min_fov, localFOV );

			GetHud().m_flFOVSensitivityAdjust = 1.0f;
	#ifndef _XBOX
			if ( GetHud().m_flMouseSensitivityFactor )
			{
				GetHud().m_flMouseSensitivity = sensitivity.GetFloat() * GetHud().m_flMouseSensitivityFactor;
			}
			else
	#endif
			{
				// No override, don't use huge sensitivity
				if ( localFOV == iDefaultFOV )
				{
	#ifndef _XBOX
					// reset to saved sensitivity
					GetHud().m_flMouseSensitivity = 0;
	#endif
				}
				else
				{  
					// Set a new sensitivity that is proportional to the change from the FOV default and scaled
					//  by a separate compensating factor
					if ( iDefaultFOV == 0 )
					{
						Assert(0); // would divide by zero, something is broken with iDefatulFOV
						iDefaultFOV = 1;
					}
					GetHud().m_flFOVSensitivityAdjust = 
						((float)localFOV / (float)iDefaultFOV) * // linear fov downscale
						zoom_sensitivity_ratio.GetFloat(); // sensitivity scale factor
	#ifndef _XBOX
					GetHud().m_flMouseSensitivity = GetHud().m_flFOVSensitivityAdjust * sensitivity.GetFloat(); // regular sensitivity
	#endif
				}
			}
		}
	}

	// Setup the frustum cache for this frame.
	m_bAllowViewAccess = true;
	FOR_EACH_VALID_SPLITSCREEN_PLAYER( iSlot )
	{
		const CViewSetup &view = GetView( iSlot );
		FrustumCache()->Add( &view, iSlot );
	}
	FrustumCache()->SetUpdated();
	m_bAllowViewAccess = false;

	IterateRemoteSplitScreenViewSlots_Pop();
}