int RageSoundReader_Extend::Read( float *pBuffer, int iFrames )
{
	int iFramesRead = GetData( pBuffer, iFrames );
	if( iFramesRead == RageSoundReader::END_OF_FILE )
	{
		if( (m_iLengthFrames != -1 && m_iPositionFrames < GetEndFrame()) ||
			m_StopMode == M_CONTINUE )
		{
			iFramesRead = iFrames;
			if( m_StopMode != M_CONTINUE )
				iFramesRead = min( GetEndFrame() - m_iPositionFrames, iFramesRead );
			memset( pBuffer, 0, iFramesRead * sizeof(float) * this->GetNumChannels() );
		}
	}

	if( iFramesRead > 0 )
	{
		int iFullVolumePositionFrames = 0;
		int iSilencePositionFrames = 0;
		if( m_iFadeInFrames != 0 && !m_bIgnoreFadeInFrames )
		{
			iSilencePositionFrames = 0;
			iFullVolumePositionFrames = m_iFadeInFrames;
		}

		/* We want to fade when there's m_iFadeFrames frames left, but if
		 * m_LengthFrames is -1, we don't know the length we're playing.
		 * (m_LengthFrames is the length to play, not the length of the
		 * source.)  If we don't know the length, don't fade. */
		if( m_iFadeOutFrames != 0 && m_iLengthFrames != -1 )
		{
			iSilencePositionFrames = GetEndFrame();
			iFullVolumePositionFrames = iSilencePositionFrames - m_iFadeOutFrames;
		}

		if( iSilencePositionFrames != iFullVolumePositionFrames )
		{
			const int iStartSecond = m_iPositionFrames;
			const int iEndSecond = m_iPositionFrames + iFramesRead;
			const float fStartVolume = SCALE( iStartSecond, iFullVolumePositionFrames, iSilencePositionFrames, 1.0f, 0.0f );
			const float fEndVolume = SCALE( iEndSecond, iFullVolumePositionFrames, iSilencePositionFrames, 1.0f, 0.0f );
			RageSoundUtil::Fade( pBuffer, iFramesRead, this->GetNumChannels(), fStartVolume, fEndVolume );
		}

		m_iPositionFrames += iFramesRead;
	}

	if( iFramesRead == RageSoundReader::END_OF_FILE && m_StopMode == M_LOOP )
	{
		this->SetPosition( m_iStartFrames );

		/* If we're not fading out at the end, then only fade in once.  Ignore
		 * m_iFadeInFrames until seeked, so we only fade in once. */
		if( m_iFadeOutFrames == 0 )
			m_bIgnoreFadeInFrames = true;
		return STREAM_LOOPED;
	}

	return iFramesRead;
}
int RageSoundReader_Extend::GetData( float *pBuffer, int iFrames )
{
	int iFramesToRead = iFrames;
	if( m_iLengthFrames != -1 )
	{
		int iFramesLeft = GetEndFrame() - m_iPositionFrames;
		iFramesLeft = max( 0, iFramesLeft );
		iFramesToRead = min( iFramesToRead, iFramesLeft );
	}

	if( iFrames && !iFramesToRead )
		return RageSoundReader::END_OF_FILE;

	if( m_iPositionFrames < 0 )
	{
		iFramesToRead = min( iFramesToRead, -m_iPositionFrames );
		memset( pBuffer, 0, iFramesToRead * sizeof(float) * this->GetNumChannels() );
		return iFramesToRead;
	}

	int iNewPositionFrames = m_pSource->GetNextSourceFrame();
	int iRet = RageSoundReader_Filter::Read( pBuffer, iFramesToRead );

	/* Update the position from the source.  If the source is at EOF, skip this,
	 * so we'll extrapolate in M_CONTINUE. */
	if( iRet != RageSoundReader::END_OF_FILE )
		m_iPositionFrames = iNewPositionFrames;
	return iRet;
}
int RageSoundReader_Extend::SetPosition( int iFrame )
{
	m_bIgnoreFadeInFrames = false;

	m_iPositionFrames = iFrame;
	int iRet = m_pSource->SetPosition( max(iFrame, 0) );
	if( iRet < 0 )
		return iRet;

	if( m_iLengthFrames != -1 )
		return m_iPositionFrames < GetEndFrame();

	/* If we're in CONTINUE and we seek past the end of the file, don't return EOF. */
	if( m_StopMode == M_CONTINUE )
		return 1;

	return iRet;
}
Ejemplo n.º 4
0
void Vessel::SetFrameGroupWithRandomFrame(StartAndEndFrameInfo* pFameInfo, float FrameSpeed)
{
	SetFrameGroup(pFameInfo,FrameSpeed);
	SetFrame( GetFrameStart() + ( rand()% (int)(GetEndFrame() - GetFrameStart()) ) );
}
Ejemplo n.º 5
0
void GereTrack(Cinematic * c, float fpscurr, bool resized, bool play) {
	
	if(!CKTrack || !CKTrack->nbkey)
		return;
	
	int num;
	
	if(play && CKTrack->pause)
		return;
	
	if(!play && !CKTrack->pause)
		return;
	
	CinematicKeyframe * current = GetKey((int) CKTrack->currframe, &num);

	if(!current)
		return;

	CinematicKeyframe * next = (num == CKTrack->nbkey) ? current : current + 1;
	
	float a;
	
	if(next->frame != current->frame)
		a = (CKTrack->currframe - (float)current->frame) / ((float)(next->frame - current->frame));
	else
		a = 1.f;
	
	float unmoinsa;
	
	c->a = unmoinsa = 1.0f - a;

	c->numbitmap		= current->numbitmap;
	c->m_nextNumbitmap	= next->numbitmap;
	c->ti				= current->typeinterp;
	c->fx				= current->fx;
	c->m_nextFx			= next->fx;
	c->color			= current->color;
	c->colord			= current->colord;
	c->colorflash		= current->colorf;
	c->speed			= current->speed;
	c->idsound			= current->idsound;
	c->force			= current->force;
	
	CinematicKeyframe * lightprec;
	
	if((current->fx & CinematicFxAllMask) == FX_LIGHT) {
		lightprec = current;
	} else {
		lightprec = current->light.prev;
	}

	CinematicKeyframe * lightnext = current->light.next;
	c->m_lightd = lightnext->light;
	
	float alight = 0;
	
	if(lightprec != lightnext) {
		alight = (CKTrack->currframe - (float)lightprec->frame) / ((float)(lightnext->frame - lightprec->frame));

		if(alight > 1.f)
			alight = 1.f;
	} else {
		if(current == (CKTrack->key + CKTrack->nbkey - 1)) {
			alight			= 1.f;
		} else {
			//alight can't be used because it is not initialized
//ARX_BEGIN: jycorbel (2010-07-19) - Set light coeff to 0 to keep null all possibly light created from uninitialyzed var.
/*
alight = unmoinsalight = 0.f; //default values needed when : k->typeinterp == INTERP_BEZIER (0) || k->typeinterp == INTERP_LINEAR (1)
consequences on light :
				c->light : position = (0,0,0);
				c->light : color	= (0,0,0); == BLACK
				c->light : fallin	= fallout		= 0;
				c->light : intensite = intensiternd	= 0;
			arx_assert( k->typeinterp != INTERP_BEZIER && k->typeinterp != INTERP_LINEAR );
*/
//ARX_END: jycorbel (2010-07-19)
			//ARX_END: jycorbel (2010-06-28)
			c->m_lightd = current->light;
			lightprec = current;
		}
	}

	c->posgrille = current->posgrille;
	c->angzgrille = current->angzgrille;
	c->m_nextPosgrille = next->posgrille;
	c->m_nextAngzgrille = next->angzgrille;
	
	if(!play)
		if(current->numbitmap < 0 || next->numbitmap < 0)
			return;
	
	switch(current->typeinterp) {
		case INTERP_NO:
			c->pos = current->pos;
			c->angz = current->angz;
			c->m_nextPos = next->pos;
			c->m_nextAngz = next->angz;
			c->m_light = lightprec->light;
			c->speedtrack = current->speedtrack;
			break;
		case INTERP_LINEAR:
			c->pos = next->pos * a + current->pos * unmoinsa;
			c->angz = current->angz + a * GetAngleInterpolation(current->angz, next->angz);
			c->speedtrack = a * next->speedtrack + unmoinsa * current->speedtrack;

			interpolateLight(alight, lightprec, c);
			break;
		case INTERP_BEZIER: {
			if(play)
				c->m_light = current->light;
			
			CinematicKeyframe * ksuivsuiv = ((num + 1) < CKTrack->nbkey) ? next + 1 : next;
			CinematicKeyframe * kprec = (num > 1) ? current - 1 : current;
			
			const Vec3f prevPos = kprec->pos;
			const Vec3f currentPos = current->pos;
			const Vec3f nextPos = next->pos;
			const Vec3f next2Pos = ksuivsuiv->pos;
			
			c->pos = glm::catmullRom(prevPos, currentPos, nextPos, next2Pos, a);
			
			c->angz = current->angz + a * GetAngleInterpolation(current->angz, next->angz);
			
			{ // TODO use glm::catmullRom
			const float t1 = a;
			const float t2 = t1 * t1;
			const float t3 = t2 * t1;
			const float f0 = 2.f * t3 - 3.f * t2 + 1.f;
			const float f1 = -2.f * t3 + 3.f * t2;
			const float f2 = t3 - 2.f * t2 + t1;
			const float f3 = t3 - t2;
			
			const float tempsp = next->speedtrack;
			const float p0sp = 0.5f * (tempsp - kprec->speedtrack);
			const float p1sp = 0.5f * (ksuivsuiv->speedtrack - current->speedtrack);
			c->speedtrack = f0 * current->speedtrack + f1 * tempsp + f2 * p0sp + f3 * p1sp;
			}

			interpolateLight(alight, lightprec, c);
			break;
		}
	}
	
	updateFadeOut(c, CKTrack, num, a, current != c->key || (resized && play));

	if(current != c->key) {
		c->key = current;
		c->changekey = true;
	}
	
	if(play) {
	
	c->flTime += fpscurr;
	CKTrack->currframe = (((float)(c->flTime)) / 1000.f) * ((float)(GetEndFrame() - GetStartFrame())) / (float)GetTimeKeyFramer();
	
	// TODO this assert fails if you pause the gametime before a cinematic starts and unpause after
	arx_assert(CKTrack->currframe >= 0);
	
	if(CKTrack->currframe > (float)CKTrack->endframe) {
		CKTrack->currframe = (float)CKTrack->startframe;
		c->key = NULL;
		arxtime.update();
		c->flTime = arxtime.now_f();
	}
	}
}