Ejemplo n.º 1
0
/*
==================
Sys_CreateThread
==================
*/
void Sys_CreateThread(xthread_t function, void *parms, xthreadInfo& info, const char *name) {
	Sys_EnterCriticalSection();

#if SDL_VERSION_ATLEAST(2, 0, 0)
	SDL_Thread *t = SDL_CreateThread(function, name, parms);
#else
	SDL_Thread *t = SDL_CreateThread(function, parms);
#endif

	if (!t) {
		common->Error("ERROR: SDL_thread for '%s' failed\n", name);
		Sys_LeaveCriticalSection();
		return;
	}

	info.name = name;
	info.threadHandle = t;
	info.threadId = SDL_GetThreadID(t);

	if (thread_count < MAX_THREADS)
		thread[thread_count++] = &info;
	else
		common->DPrintf("WARNING: MAX_THREADS reached\n");

	Sys_LeaveCriticalSection();
}
Ejemplo n.º 2
0
/*
============
Cbuf_ExecuteText
============
*/
void Cbuf_ExecuteText (int exec_when, const char *text)
{
	switch (exec_when)
	{
	case EXEC_NOW:
		
		Sys_EnterCriticalSection(CRIT_CBUF);
		
		if (text && strlen(text) > 0) {
			Com_DPrintf(S_COLOR_YELLOW "EXEC_NOW %s\n", text);
			Cmd_ExecuteString (text);
		} else {
			Cbuf_Execute();
			Com_DPrintf(S_COLOR_YELLOW "EXEC_NOW %s\n", cmd_text.data);
		}
		
		Sys_LeaveCriticalSection(CRIT_CBUF);
			
		break;
	case EXEC_INSERT:
		Cbuf_InsertText (text);
		break;
	case EXEC_APPEND:
		Cbuf_AddText (text);
		break;
	default:
		Com_Error (ERR_FATAL, "Cbuf_ExecuteText: bad exec_when");
	}
}
Ejemplo n.º 3
0
/*
=================
Sys_DoSignalAction
=================
*/
void Sys_DoSignalAction( int signal, const char* sigstring )
{
	static qboolean signalcaught = qfalse;
	char termmsg[MAX_STRING_CHARS];

	Com_Printf( "Received signal: %s, exiting...\n", sigstring );

	if( signalcaught )
	{
		Com_Printf( "DOUBLE SIGNAL FAULT: Received signal: %s, exiting...\n", sigstring);
	}

	else
	{
		signalcaught = qtrue;
		Com_Printf("Server received signal: %s\nShutting down server...\n", sigstring);
		Com_sprintf(termmsg, sizeof(termmsg), "\nServer received signal: %s\nTerminating server...", sigstring);
		SV_Shutdown( termmsg );

		Sys_EnterCriticalSection( 2 );

		Com_CloseLogFiles(); //close all open logfiles
		FS_Shutdown(qtrue);
	}

	if( signal == SIGTERM || signal == SIGINT )
		Sys_Exit( 1 );
	else
		Sys_Exit( 2 );
}
Ejemplo n.º 4
0
/*
==================
Sys_DestroyThread
==================
*/
void Sys_DestroyThread(xthreadInfo& info) {
	assert(info.threadHandle);

	SDL_WaitThread(info.threadHandle, NULL);

	info.name = NULL;
	info.threadHandle = NULL;
	info.threadId = 0;

	Sys_EnterCriticalSection();

	for (int i = 0; i < thread_count; i++) {
		if (&info == thread[i]) {
			thread[i] = NULL;

			int j;
			for (j = i + 1; j < thread_count; j++)
				thread[j - 1] = thread[j];

			thread[j - 1] = NULL;
			thread_count--;

			break;
		}
	}

	Sys_LeaveCriticalSection( );
}
Ejemplo n.º 5
0
/*
===================
idSoundEmitterLocal::StopSound

can pass SCHANNEL_ANY
===================
*/
void idSoundEmitterLocal::StopSound( const s_channelType channel ) {
	int i;
	if( idSoundSystemLocal::s_showStartSound.GetInteger() ) {
		common->Printf( "StopSound(%i,%i)\n", index, channel );
	}
	if( soundWorld && soundWorld->writeDemo ) {
		soundWorld->writeDemo->WriteInt( DS_SOUND );
		soundWorld->writeDemo->WriteInt( SCMD_STOP );
		soundWorld->writeDemo->WriteInt( index );
		soundWorld->writeDemo->WriteInt( channel );
	}
	Sys_EnterCriticalSection();
	for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) {
		idSoundChannel	*chan = &channels[i];
		if( !chan->triggerState ) {
			continue;
		}
		if( channel != SCHANNEL_ANY && chan->triggerChannel != channel ) {
			continue;
		}
		// stop it
		chan->Stop();
		// free hardware resources
		chan->ALStop();
		// if this was an onDemand sound, purge the sample now
		if( chan->leadinSample->onDemand ) {
			chan->leadinSample->PurgeSoundSample();
		}
		chan->leadinSample = NULL;
		chan->soundShader = NULL;
	}
	Sys_LeaveCriticalSection();
}
Ejemplo n.º 6
0
/*
==================
Sys_DestroyThread
==================
*/
void Sys_DestroyThread( xthreadInfo& info ) {
	// the target thread must have a cancelation point, otherwise pthread_cancel is useless
	assert( info.threadHandle );
	if ( pthread_cancel( ( pthread_t )info.threadHandle ) != 0 ) {
		common->Error( "ERROR: pthread_cancel %s failed\n", info.name );
	}
	if ( pthread_join( ( pthread_t )info.threadHandle, NULL ) != 0 ) {
		common->Error( "ERROR: pthread_join %s failed\n", info.name );
	}
	info.threadHandle = 0;
	Sys_EnterCriticalSection( );
	for( int i = 0 ; i < g_thread_count ; i++ ) {
		if ( &info == g_threads[ i ] ) {
			g_threads[ i ] = NULL;
			int j;
			for( j = i+1 ; j < g_thread_count ; j++ ) {
				g_threads[ j-1 ] = g_threads[ j ];
			}
			g_threads[ j-1 ] = NULL;
			g_thread_count--;
			Sys_LeaveCriticalSection( );
			return;
		}
	}
	Sys_LeaveCriticalSection( );
}
Ejemplo n.º 7
0
Archivo: sys_main.c Proyecto: dioda/apb
/*
=================
Sys_SigHandler
=================
*/
void Sys_SigHandler( int signal )
{
	static qboolean signalcaught = qfalse;

	fprintf( stderr, "Received signal: %s, exiting...\n",
		strsignal(signal) );

	if( signalcaught )
	{
		fprintf( stderr, "DOUBLE SIGNAL FAULT: Received signal: %s, exiting...\n",
			strsignal(signal));
	}

	else
	{
		signalcaught = qtrue;
		Com_Printf("Server received signal: %s\nShutting down server...", strsignal(signal));
		SV_Shutdown(va("\nServer received signal: %s\nTerminating server...", strsignal(signal)) );
		Sys_EnterCriticalSection( 2 );
		if(logfile)
			FS_FCloseFile(logfile);
		if(adminlogfile)
			FS_FCloseFile(adminlogfile);
		if(reliabledump)
			FS_FCloseFile(reliabledump);

		FS_Shutdown(qtrue);
	}

	if( signal == SIGTERM || signal == SIGINT )
		Sys_Exit( 1 );
	else
		Sys_Exit( 2 );
}
Ejemplo n.º 8
0
/*
==================
Sys_GetThreadName
find the name of the calling thread
==================
*/
const char *Sys_GetThreadName(int *index) {
	const char *name;

	Sys_EnterCriticalSection();

	unsigned int id = SDL_ThreadID();

	for (int i = 0; i < thread_count; i++) {
		if (id == thread[i]->threadId) {
			if (index)
				*index = i;

			name = thread[i]->name;

			Sys_LeaveCriticalSection();

			return name;
		}
	}

	if (index)
		*index = -1;

	Sys_LeaveCriticalSection();

	return "main";
}
void Com_PrintLogfile( const char *msg )
{

	Sys_EnterCriticalSection(5);

	if ( com_logfile && com_logfile->integer ) {
        // TTimo: only open the qconsole.log if the filesystem is in an initialized state
        // also, avoid recursing in the qconsole.log opening (i.e. if fs_debug is on)
	    if ( !logfile && FS_Initialized()) {
			struct tm *newtime;
			time_t aclock;

			time( &aclock );
			newtime = localtime( &aclock );

			logfile = FS_FOpenFileWrite( "qconsole.log" );

			if ( com_logfile->integer > 1 && logfile ) {
				// force it to not buffer so we get valid
				// data even if we are crashing
				FS_ForceFlush(logfile);
			}
			if ( logfile ) FS_Write(va("\nLogfile opened on %s\n", asctime( newtime )), strlen(va("\nLogfile opened on %s\n", asctime( newtime ))), logfile);
	    }
	    if ( logfile && FS_Initialized()) 
	    {
	    	FS_Write(msg, strlen(msg), logfile);
	    }
	}
	Sys_LeaveCriticalSection(5);
}
Ejemplo n.º 10
0
/*
====================
idWaveFile::OpenOGG
====================
*/
int idWaveFile::OpenOGG( const char* strFileName, waveformatex_t *pwfx ) {
	OggVorbis_File *ov;

	memset( pwfx, 0, sizeof( waveformatex_t ) );

	mhmmio = fileSystem->OpenFileRead( strFileName );
	if ( !mhmmio ) {
		return -1;
	}

	Sys_EnterCriticalSection( CRITICAL_SECTION_ONE );

	ov = new OggVorbis_File;

	if( ov_openFile( mhmmio, ov ) < 0 ) {
		delete ov;
		Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE );
		fileSystem->CloseFile( mhmmio );
		mhmmio = NULL;
		return -1;
	}

	mfileTime = mhmmio->Timestamp();

	vorbis_info *vi = ov_info( ov, -1 );

	mpwfx.Format.nSamplesPerSec = vi->rate;
	mpwfx.Format.nChannels = vi->channels;
	mpwfx.Format.wBitsPerSample = sizeof(short) * 8;
	mdwSize = ov_pcm_total( ov, -1 ) * vi->channels;	// pcm samples * num channels
	mbIsReadingFromMemory = false;

	if ( idSoundSystemLocal::s_realTimeDecoding.GetBool() ) {

		ov_clear( ov );
		fileSystem->CloseFile( mhmmio );
		mhmmio = NULL;
		delete ov;

		mpwfx.Format.wFormatTag = WAVE_FORMAT_TAG_OGG;
		mhmmio = fileSystem->OpenFileRead( strFileName );
		mMemSize = mhmmio->Length();

	} else {

		ogg = ov;

		mpwfx.Format.wFormatTag = WAVE_FORMAT_TAG_PCM;
		mMemSize = mdwSize * sizeof( short );
	}

	memcpy( pwfx, &mpwfx, sizeof( waveformatex_t ) );

	Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE );

	isOgg = true;

	return 0;
}
/*
=================
Sys_Print
=================
*/
void Sys_Print( const char *msg )
{
	Sys_EnterCriticalSection(CRIT_CONSOLE);

//	CON_LogWrite( msg );
	CON_Print( msg );

	Sys_LeaveCriticalSection(CRIT_CONSOLE);

}
Ejemplo n.º 12
0
/*
==================
Sys_TriggerEvent
==================
*/
void Sys_TriggerEvent( int index ) {
	assert( index >= 0 && index < MAX_TRIGGER_EVENTS );
	Sys_EnterCriticalSection( MAX_LOCAL_CRITICAL_SECTIONS - 1 );
	if ( waiting[ index ] ) {		
		pthread_cond_signal( &event_cond[ index ] );
	} else {
		// emulate windows behaviour: if no thread is waiting, leave the signal on so next wait keeps going
		signaled[ index ] = true;
	}
	Sys_LeaveCriticalSection( MAX_LOCAL_CRITICAL_SECTIONS - 1 );
}
Ejemplo n.º 13
0
__cdecl void Com_PrintMessage( int dumbIWvar, char *msg, msgtype_t type) {

	//secures calls to Com_PrintMessage from recursion while redirect printing
	static qboolean lock = qfalse;

	if(dumbIWvar == 6) return;

	int msglen = strlen(msg);

	if(type != MSG_NORDPRINT && !lock)
	{
	
		Sys_EnterCriticalSection(CRIT_REDIRECTPRINT);

		if ( !lock) {

			lock = qtrue;
			Com_PrintRedirect(msg, msglen);
			lock = qfalse;

			if ( rd_buffer ) {
				if(!rd_flush){
					Sys_LeaveCriticalSection(CRIT_REDIRECTPRINT);
					return;
				}
				if ((msglen + strlen(rd_buffer)) > (rd_buffersize - 1)) {

					lock = qtrue;
					rd_flush(rd_buffer, qfalse);
					lock = qfalse;

					*rd_buffer = 0;
				}
				Q_strcat(rd_buffer, rd_buffersize, msg);
				// TTimo nooo .. that would defeat the purpose
				//rd_flush(rd_buffer);
				//*rd_buffer = 0;
				Sys_LeaveCriticalSection(CRIT_REDIRECTPRINT);
				return;
			}
		}
		
		Sys_LeaveCriticalSection(CRIT_REDIRECTPRINT);
	
	}

	
	// echo to dedicated console and early console
	Sys_Print( msg );

	// logfile
	Com_PrintLogfile( msg );

}
Ejemplo n.º 14
0
/*
====================
idWaveFile::CloseOGG
====================
*/
int idWaveFile::CloseOGG( void ) {
	OggVorbis_File *ov = (OggVorbis_File *) ogg;
	if ( ov != NULL ) {
		Sys_EnterCriticalSection( CRITICAL_SECTION_ONE );
		ov_clear( ov );
		delete ov;
		Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE );
		fileSystem->CloseFile( mhmmio );
		mhmmio = NULL;
		ogg = NULL;
		return 0;
	}
	return -1;
}
Ejemplo n.º 15
0
/*
==================
Sys_WaitForEvent
==================
*/
void Sys_WaitForEvent( int index ) {
	assert( index >= 0 && index < MAX_TRIGGER_EVENTS );
	Sys_EnterCriticalSection( MAX_LOCAL_CRITICAL_SECTIONS - 1 );
	assert( !waiting[ index ] );	// WaitForEvent from multiple threads? that wouldn't be good
	if ( signaled[ index ] ) {
		// emulate windows behaviour: signal has been raised already. clear and keep going
		signaled[ index ] = false;
	} else {
		waiting[ index ] = true;
		pthread_cond_wait( &event_cond[ index ], &global_lock[ MAX_LOCAL_CRITICAL_SECTIONS - 1 ] );
		waiting[ index ] = false;
	}
	Sys_LeaveCriticalSection( MAX_LOCAL_CRITICAL_SECTIONS - 1 );
}
Ejemplo n.º 16
0
/*
============
Cbuf_InsertText

Adds command text immediately after the current command
Adds a \n to the text
============
*/
void Cbuf_InsertText( const char *text ) {
	int		len;
	int		i;
	byte*		new_buf;

	len = strlen( text ) + 1;

	Sys_EnterCriticalSection(CRIT_CBUF);

	
	if ( len + cmd_text.cursize > cmd_text.maxsize ) {

		if(cmd_text.data == cmd_text_buf)
		{
			new_buf = realloc(NULL, len + cmd_text.cursize);
			if(new_buf != NULL)
			{
				Com_Memcpy(new_buf, cmd_text_buf, len + cmd_text.cursize);
			}
		}else{
			new_buf = realloc(cmd_text.data, len + cmd_text.cursize);
		}

		if(new_buf == NULL)
		{
			Com_PrintError( "Cbuf_InsertText overflowed ; realloc failed\n" );
			
			Sys_LeaveCriticalSection(CRIT_CBUF);
			return;
		}
		cmd_text.data = new_buf;
		cmd_text.maxsize = len + cmd_text.cursize;
	}

	// move the existing command text
	for ( i = cmd_text.cursize - 1 ; i >= 0 ; i-- ) {
		cmd_text.data[ i + len ] = cmd_text.data[ i ];
	}

	// copy the new text in
	Com_Memcpy( cmd_text.data, text, len - 1 );

	// add a \n
	cmd_text.data[ len - 1 ] = '\n';

	cmd_text.cursize += len;
	
	Sys_LeaveCriticalSection(CRIT_CBUF);
}
Ejemplo n.º 17
0
/*
==================
Sys_TriggerEvent
==================
*/
void Sys_TriggerEvent(int index) {
	assert(index >= 0 && index < MAX_TRIGGER_EVENTS);

	Sys_EnterCriticalSection(CRITICAL_SECTION_SYS);

	if (waiting[index]) {
		if (SDL_CondSignal(cond[index]) != 0)
			common->Error("ERROR: SDL_CondSignal failed\n");
	} else {
		// emulate windows behaviour: if no thread is waiting, leave the signal on so next wait keeps going
		signaled[index] = true;
	}

	Sys_LeaveCriticalSection(CRITICAL_SECTION_SYS);
}
Ejemplo n.º 18
0
/*
==========
idAudioHardwareOSX::DeviceIOProc
==========
*/
OSStatus idAudioHardwareOSX::DeviceIOProc( AudioDeviceID			inDevice,
		const AudioTimeStamp	*inNow,
		const AudioBufferList	*inInputData,
		const AudioTimeStamp	*inInputTime,
		AudioBufferList			*outOutputData,
		const AudioTimeStamp	*inOutputTime,
		void					*inClientData ) {
	// setup similar to async thread
	Sys_EnterCriticalSection();
	soundSystem->AsyncMix( ( int )inOutputTime->mSampleTime, ( float * )outOutputData->mBuffers[ 0 ].mData );
	Sys_LeaveCriticalSection();
	// doom mixes sound to -32768.0f 32768.0f range, scale down to -1.0f 1.0f
	SIMDProcessor->Mul( ( Float32 * )outOutputData->mBuffers[ 0 ].mData, 1.0f / 32768.0f, ( Float32 * )outOutputData->mBuffers[ 0 ].mData, MIXBUFFER_SAMPLES * 2 );
	return kAudioHardwareNoError;
}
Ejemplo n.º 19
0
/*
==================
Sys_WaitForEvent
==================
*/
void Sys_WaitForEvent(int index) {
	assert(index >= 0 && index < MAX_TRIGGER_EVENTS);

	Sys_EnterCriticalSection(CRITICAL_SECTION_SYS);

	assert(!waiting[index]);	// WaitForEvent from multiple threads? that wouldn't be good
	if (signaled[index]) {
		// emulate windows behaviour: signal has been raised already. clear and keep going
		signaled[index] = false;
	} else {
		waiting[index] = true;
		if (SDL_CondWait(cond[index], mutex[CRITICAL_SECTION_SYS]) != 0)
			common->Error("ERROR: SDL_CondWait failed\n");
		waiting[index] = false;
	}

	Sys_LeaveCriticalSection(CRITICAL_SECTION_SYS);
}
Ejemplo n.º 20
0
/*
====================
idSampleDecoderLocal::ClearDecoder
====================
*/
void idSampleDecoderLocal::ClearDecoder( void ) {
	Sys_EnterCriticalSection( CRITICAL_SECTION_ONE );

	switch( lastFormat ) {
		case WAVE_FORMAT_TAG_PCM: {
			break;
		}
		case WAVE_FORMAT_TAG_OGG: {
			ov_clear( &ogg );
			memset( &ogg, 0, sizeof( ogg ) );
			break;
		}
	}

	Clear();

	Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE );
}
Ejemplo n.º 21
0
/*
==================
Sys_GetThreadName
find the name of the calling thread
==================
*/
const char* Sys_GetThreadName( int *index ) {
	Sys_EnterCriticalSection( );
	pthread_t thread = pthread_self();
	for( int i = 0 ; i < g_thread_count ; i++ ) {
		if ( thread == (pthread_t)g_threads[ i ]->threadHandle ) {
			if ( index ) {
				*index = i;
			}
			Sys_LeaveCriticalSection( );
			return g_threads[ i ]->name;
		}
	}
	if ( index ) {
		*index = -1;
	}
	Sys_LeaveCriticalSection( );
	return "main";
}
void QDECL SV_EnterLeaveLog( const char *fmt, ... ) {

	Sys_EnterCriticalSection(5);

	va_list		argptr;
	char		msg[MAXPRINTMSG];
	char		inputmsg[MAXPRINTMSG];
	struct tm 	*newtime;
	char*		ltime;
	time_t		realtime;

        // logfile
	if ( com_logfile && com_logfile->integer ) {
        // TTimo: only open the qconsole.log if the filesystem is in an initialized state
        // also, avoid recursing in the qconsole.log opening (i.e. if fs_debug is on)

	    va_start (argptr,fmt);
	    Q_vsnprintf (inputmsg, sizeof(inputmsg), fmt, argptr);
	    va_end (argptr);

	    Com_UpdateRealtime();
	    realtime = Com_GetRealtime();
	    newtime = localtime( &realtime );
	    ltime = asctime( newtime );
	    ltime[strlen(ltime)-1] = 0;

	    if ( !enterleavelogfile && FS_Initialized()) {

			enterleavelogfile = FS_FOpenFileAppend( "enterleave.log" );
			// force it to not buffer so we get valid
			if ( enterleavelogfile ){
				FS_ForceFlush(enterleavelogfile);
				FS_Write(va("\nLogfile opened on %s\n\n", ltime), strlen(va("\nLogfile opened on %s\n\n", ltime)), enterleavelogfile);
			}
	    }

	    if ( enterleavelogfile && FS_Initialized()) {
		Com_sprintf(msg, sizeof(msg), "%s: %s\n", ltime, inputmsg);
		FS_Write(msg, strlen(msg), enterleavelogfile);
	    }

	}
	Sys_LeaveCriticalSection(5);
}
Ejemplo n.º 23
0
/*
==================
Sys_CreateThread
==================
*/
void Sys_CreateThread( xthread_t function, void *parms, xthreadPriority priority, xthreadInfo& info, const char *name, xthreadInfo **threads, int *thread_count ) {
	Sys_EnterCriticalSection( );		
	pthread_attr_t attr;
	pthread_attr_init( &attr );
	if ( pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ) != 0 ) {
		common->Error( "ERROR: pthread_attr_setdetachstate %s failed\n", name );
	}
	if ( pthread_create( ( pthread_t* )&info.threadHandle, &attr, ( pthread_function_t )function, parms ) != 0 ) {
		common->Error( "ERROR: pthread_create %s failed\n", name );
	}
	pthread_attr_destroy( &attr );
	info.name = name;
	if ( *thread_count < MAX_THREADS ) {
		threads[ ( *thread_count )++ ] = &info;
	} else {
		common->DPrintf( "WARNING: MAX_THREADS reached\n" );
	}
	Sys_LeaveCriticalSection( );
}
void QDECL Com_PrintAdministrativeLog( const char *msg ) {

	Sys_EnterCriticalSection(5);

	struct tm 	*newtime;
	char*		ltime;
	time_t		realtime;

        // logfile
	if ( com_logfile && com_logfile->integer ) {
        // TTimo: only open the qconsole.log if the filesystem is in an initialized state
        //   also, avoid recursing in the qconsole.log opening (i.e. if fs_debug is on)


	    if ( !adminlogfile && FS_Initialized()) {

			Com_UpdateRealtime();
			realtime = Com_GetRealtime();
			newtime = localtime( &realtime );
			ltime = asctime( newtime );
			ltime[strlen(ltime)-1] = 0;


			adminlogfile = FS_FOpenFileAppend( "adminactions.log" );
			// force it to not buffer so we get valid
			if ( adminlogfile ){
				FS_ForceFlush(adminlogfile);
				FS_Write(va("\nLogfile opened on %s\n\n", ltime), strlen(va("\nLogfile opened on %s\n\n", ltime)), adminlogfile);
			}
	    }

	    if ( adminlogfile && FS_Initialized())
	    {
		FS_Write(msg, strlen(msg), adminlogfile);
	    }

	}
	Sys_LeaveCriticalSection(5);
}
Ejemplo n.º 25
0
/*
====================
idSampleDecoderLocal::Decode
====================
*/
void idSampleDecoderLocal::Decode( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ) {
	int readSamples44k;

	if ( sample->objectInfo.wFormatTag != lastFormat || sample != lastSample ) {
		ClearDecoder();
	}

	lastDecodeTime = soundSystemLocal.CurrentSoundTime;

	if ( failed ) {
		memset( dest, 0, sampleCount44k * sizeof( dest[0] ) );
		return;
	}

	// samples can be decoded both from the sound thread and the main thread for shakes
	Sys_EnterCriticalSection( CRITICAL_SECTION_ONE );

	switch( sample->objectInfo.wFormatTag ) {
		case WAVE_FORMAT_TAG_PCM: {
			readSamples44k = DecodePCM( sample, sampleOffset44k, sampleCount44k, dest );
			break;
		}
		case WAVE_FORMAT_TAG_OGG: {
			readSamples44k = DecodeOGG( sample, sampleOffset44k, sampleCount44k, dest );
			break;
		}
		default: {
			readSamples44k = 0;
			break;
		}
	}

	Sys_LeaveCriticalSection( CRITICAL_SECTION_ONE );

	if ( readSamples44k < sampleCount44k ) {
		memset( dest + readSamples44k, 0, ( sampleCount44k - readSamples44k ) * sizeof( dest[0] ) );
	}
}
Ejemplo n.º 26
0
/*
============
Cbuf_AddText

Adds command text at the end of the buffer, does NOT add a final \n
============
*/
void Cbuf_AddText( const char *text ) {
	int		len;
	byte*		new_buf;
	len = strlen (text) +1;

	Sys_EnterCriticalSection(CRIT_CBUF);
	
	if ( len + cmd_text.cursize > cmd_text.maxsize ) {

		if(cmd_text.data == cmd_text_buf)
		{
			new_buf = realloc(NULL, len + cmd_text.cursize);
			if(new_buf != NULL)
			{
				Com_Memcpy(new_buf, cmd_text_buf, len + cmd_text.cursize);
			}
		}else{
			new_buf = realloc(cmd_text.data, len + cmd_text.cursize);
		}

		if(new_buf == NULL)
		{
			Com_PrintError( "Cbuf_AddText overflowed ; realloc failed\n" );
			Sys_LeaveCriticalSection(CRIT_CBUF);
			return;
		}
		cmd_text.data = new_buf;
		cmd_text.maxsize = len + cmd_text.cursize;
	}

	Com_Memcpy(&cmd_text.data[cmd_text.cursize], text, len -1);
	cmd_text.cursize += len -1;

	Sys_LeaveCriticalSection(CRIT_CBUF);
	
}
Ejemplo n.º 27
0
/*
=====================
idSoundEmitterLocal::StartSound

returns the length of the started sound in msec
=====================
*/
int idSoundEmitterLocal::StartSound( const idSoundShader *shader, const s_channelType channel, float diversity, int soundShaderFlags, bool allowSlow ) {
	int i;

	if ( !shader ) {
		return 0;
	}

	if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) {
		common->Printf( "StartSound %ims (%i,%i,%s) = ", soundWorld->gameMsec, index, (int)channel, shader->GetName() );
	}

	if ( soundWorld && soundWorld->writeDemo ) {
		soundWorld->writeDemo->WriteInt( DS_SOUND );
		soundWorld->writeDemo->WriteInt( SCMD_START );
		soundWorld->writeDemo->WriteInt( index );

		soundWorld->writeDemo->WriteHashString( shader->GetName() );

		soundWorld->writeDemo->WriteInt( channel );
		soundWorld->writeDemo->WriteFloat( diversity );
		soundWorld->writeDemo->WriteInt( soundShaderFlags );
	}

	// build the channel parameters by taking the shader parms and optionally overriding
	soundShaderParms_t	chanParms;

	chanParms = shader->parms;
	OverrideParms( &chanParms, &this->parms, &chanParms );
	chanParms.soundShaderFlags |= soundShaderFlags;

	if ( chanParms.shakes > 0.0f ) {
		shader->CheckShakesAndOgg();
	}

	// this is the sample time it will be first mixed
	int start44kHz;
	
	if ( soundWorld->fpa[0] ) {
		// if we are recording an AVI demo, don't use hardware time
		start44kHz = soundWorld->lastAVI44kHz + MIXBUFFER_SAMPLES;
	} else {
		start44kHz = soundSystemLocal.GetCurrent44kHzTime() + MIXBUFFER_SAMPLES;
	}

	//
	// pick which sound to play from the shader
	//
	if ( !shader->numEntries ) {
		if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) {
			common->Printf( "no samples in sound shader\n" );
		}
		return 0;				// no sounds
	}
	int choice;

	// pick a sound from the list based on the passed diversity
	choice = (int)(diversity * shader->numEntries);
	if ( choice < 0 || choice >= shader->numEntries ) {
		choice = 0;
	}

	// bump the choice if the exact sound was just played and we are NO_DUPS
	if ( chanParms.soundShaderFlags & SSF_NO_DUPS ) {
		idSoundSample	*sample;
		if ( shader->leadins[ choice ] ) {
			sample = shader->leadins[ choice ];
		} else {
			sample = shader->entries[ choice ];
		}
		for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) {
			idSoundChannel	*chan = &channels[i];
			if ( chan->leadinSample == sample ) {
				choice = ( choice + 1 ) % shader->numEntries;
				break;
			}
		}
	}

	// PLAY_ONCE sounds will never be restarted while they are running
	if ( chanParms.soundShaderFlags & SSF_PLAY_ONCE ) {
		for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) {
			idSoundChannel	*chan = &channels[i];
			if ( chan->triggerState && chan->soundShader == shader ) {
				if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) {
					common->Printf( "PLAY_ONCE not restarting\n" );
				}
				return 0;
			}
		}
	}

	// never play the same sound twice with the same starting time, even
	// if they are on different channels
	for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) {
		idSoundChannel	*chan = &channels[i];
		if ( chan->triggerState && chan->soundShader == shader && chan->trigger44kHzTime == start44kHz ) {
			if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) {
				common->Printf( "already started this frame\n" );
			}
			return 0;
		}
	}

	Sys_EnterCriticalSection();

	// kill any sound that is currently playing on this channel
	if ( channel != SCHANNEL_ANY ) {
		for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) {
			idSoundChannel	*chan = &channels[i];
			if ( chan->triggerState && chan->soundShader && chan->triggerChannel == channel ) {
				if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) {
					common->Printf( "(override %s)", chan->soundShader->base->GetName() );
				}
				
				chan->Stop();

				// if this was an onDemand sound, purge the sample now
				if ( chan->leadinSample->onDemand ) {
					chan->ALStop();
					chan->leadinSample->PurgeSoundSample();
				}
				break;
			}
		}
	}

	// find a free channel to play the sound on
	idSoundChannel	*chan;
	for( i = 0; i < SOUND_MAX_CHANNELS; i++ ) {
		chan = &channels[i];
		if ( !chan->triggerState ) {
			break;
		}
	}

	if ( i == SOUND_MAX_CHANNELS ) {
		// we couldn't find a channel for it
		Sys_LeaveCriticalSection();
		if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) {
			common->Printf( "no channels available\n" );
		}
		return 0;
	}

	chan = &channels[i];

	if ( shader->leadins[ choice ] ) {
		chan->leadinSample = shader->leadins[ choice ];
	} else {
		chan->leadinSample = shader->entries[ choice ];
	}

	// if the sample is onDemand (voice mails, etc), load it now
	if ( chan->leadinSample->purged ) {
		int		start = Sys_Milliseconds();
		chan->leadinSample->Load();
		int		end = Sys_Milliseconds();
		session->TimeHitch( end - start );
		// recalculate start44kHz, because loading may have taken a fair amount of time
		if ( !soundWorld->fpa[0] ) {
			start44kHz = soundSystemLocal.GetCurrent44kHzTime() + MIXBUFFER_SAMPLES;
		}
	}

	if ( idSoundSystemLocal::s_showStartSound.GetInteger() ) {
		common->Printf( "'%s'\n", chan->leadinSample->name.c_str() );
	}

	if ( idSoundSystemLocal::s_skipHelltimeFX.GetBool() ) {
		chan->disallowSlow = true;
	} else {
		chan->disallowSlow = !allowSlow;
	}

	ResetSlowChannel( chan );

	// the sound will start mixing in the next async mix block
	chan->triggered = true;
	chan->openalStreamingOffset = 0;
	chan->trigger44kHzTime = start44kHz;
	chan->parms = chanParms;
	chan->triggerGame44kHzTime = soundWorld->game44kHz;
	chan->soundShader = shader;
	chan->triggerChannel = channel;
	chan->Start();

	// we need to start updating the def and mixing it in
	playing = true;

	// spatialize it immediately, so it will start the next mix block
	// even if that happens before the next PlaceOrigin()
	Spatialize( soundWorld->listenerPos, soundWorld->listenerArea, soundWorld->rw );

	// return length of sound in milliseconds
	int length = chan->leadinSample->LengthIn44kHzSamples();

	if ( chan->leadinSample->objectInfo.nChannels == 2 ) {
		length /= 2;	// stereo samples
	}

	// adjust the start time based on diversity for looping sounds, so they don't all start
	// at the same point
	if ( chan->parms.soundShaderFlags & SSF_LOOPING && !chan->leadinSample->LengthIn44kHzSamples() ) {
		chan->trigger44kHzTime -= diversity * length;
		chan->trigger44kHzTime &= ~7;		// so we don't have to worry about the 22kHz and 11kHz expansions
											// starting in fractional samples
		chan->triggerGame44kHzTime -= diversity * length;
		chan->triggerGame44kHzTime &= ~7;
	}
	
	length *= 1000 / (float)PRIMARYFREQ;

	Sys_LeaveCriticalSection();

	return length;
}