Example #1
0
/*
** GLimp_Init
**
** This is the platform specific OpenGL initialization function.  It
** is responsible for loading OpenGL, initializing it, setting
** extensions, creating a window of the appropriate size, doing
** fullscreen manipulations, etc.  Its overall responsibility is
** to make sure that a functional OpenGL subsystem is operating
** when it returns to the ref.
*/
void GLimp_Init( void ) {
	char buf[1024];
	cvar_t *lastValidRenderer = ri.Cvar_Get( "r_lastValidRenderer", "(uninitialized)", CVAR_ARCHIVE );
	cvar_t  *cv;

	ri.Printf( PRINT_ALL, "Initializing OpenGL subsystem\n" );

	//
	// check OS version to see if we can do fullscreen display changes
	//
	if ( !GLW_CheckOSVersion() ) {
		ri.Error( ERR_VID_FATAL, "GLimp_Init() - incorrect operating system\n" );
	}

	// save off hInstance and wndproc
	cv = ri.Cvar_Get( "win_hinstance", "", 0 );
	sscanf( cv->string, "%i", (int *)&g_wv.hInstance );

	cv = ri.Cvar_Get( "win_wndproc", "", 0 );
	sscanf( cv->string, "%i", (int *)&glw_state.wndproc );

	r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH );
	r_maskMinidriver = ri.Cvar_Get( "r_maskMinidriver", "0", CVAR_LATCH );

	// load appropriate DLL and initialize subsystem
	GLW_StartOpenGL();

	// get our config strings
	Q_strncpyz( glConfig.vendor_string, qglGetString( GL_VENDOR ), sizeof( glConfig.vendor_string ) );
	Q_strncpyz( glConfig.renderer_string, qglGetString( GL_RENDERER ), sizeof( glConfig.renderer_string ) );
	Q_strncpyz( glConfig.version_string, qglGetString( GL_VERSION ), sizeof( glConfig.version_string ) );
	Q_strncpyz( glConfig.extensions_string, qglGetString( GL_EXTENSIONS ), sizeof( glConfig.extensions_string ) );
	// TTimo - safe check
	if ( strlen( qglGetString( GL_EXTENSIONS ) ) >= sizeof( glConfig.extensions_string ) ) {
		Com_Printf( S_COLOR_YELLOW "WARNNING: GL extensions string too long (%d), truncated to %d\n", strlen( qglGetString( GL_EXTENSIONS ) ), sizeof( glConfig.extensions_string ) );
	}

	//
	// chipset specific configuration
	//
	Q_strncpyz( buf, glConfig.renderer_string, sizeof( buf ) );
	Q_strlwr( buf );

	//
	// NOTE: if changing cvars, do it within this block.  This allows them
	// to be overridden when testing driver fixes, etc. but only sets
	// them to their default state when the hardware is first installed/run.
	//
	if ( Q_stricmp( lastValidRenderer->string, glConfig.renderer_string ) ) {
		glConfig.hardwareType = GLHW_GENERIC;

		ri.Cvar_Set( "r_textureMode", "GL_LINEAR_MIPMAP_NEAREST" );

		// VOODOO GRAPHICS w/ 2MB
		if ( strstr( buf, "voodoo graphics/1 tmu/2 mb" ) ) {
			ri.Cvar_Set( "r_picmip", "2" );
			ri.Cvar_Get( "r_picmip", "1", CVAR_ARCHIVE | CVAR_LATCH );
		} else
		{

//----(SA)	FIXME: RETURN TO DEFAULT  Another id build change for DK/DM
			ri.Cvar_Set( "r_picmip", "1" );   //----(SA)	was "1" // JPW NERVE back to 1
//----(SA)

			if ( strstr( buf, "rage 128" ) || strstr( buf, "rage128" ) ) {
				ri.Cvar_Set( "r_finish", "0" );
			}
			// Savage3D and Savage4 should always have trilinear enabled
			else if ( strstr( buf, "savage3d" ) || strstr( buf, "s3 savage4" ) ) {
				ri.Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" );
			}
		}
	}

	//
	// this is where hardware specific workarounds that should be
	// detected/initialized every startup should go.
	//
	if ( strstr( buf, "banshee" ) || strstr( buf, "voodoo3" ) ) {
		glConfig.hardwareType = GLHW_3DFX_2D3D;
	}
	// VOODOO GRAPHICS w/ 2MB
	else if ( strstr( buf, "voodoo graphics/1 tmu/2 mb" ) ) {
	} else if ( strstr( buf, "glzicd" ) )    {
	} else if ( strstr( buf, "rage pro" ) /*|| strstr( buf, "Rage Pro")*/ || strstr( buf, "ragepro" ) )     {
		glConfig.hardwareType = GLHW_RAGEPRO;
		ri.Printf( PRINT_WARNING, "WARNING: Rage Pro hardware is unsupported. Rendering errors may occur.\n" );
	} else if ( strstr( buf, "rage 128" ) )    {
	} else if ( strstr( buf, "permedia2" ) )    {
		glConfig.hardwareType = GLHW_PERMEDIA2;
		ri.Printf( PRINT_WARNING, "WARNING: Permedia hardware is unsupported. Rendering errors may occur.\n" );
	} else if ( strstr( buf, "riva 128" ) )    {
		glConfig.hardwareType = GLHW_RIVA128;
		ri.Printf( PRINT_WARNING, "WARNING: Riva 128 hardware is unsupported. Rendering errors may occur.\n" );
	} else if ( strstr( buf, "matrox" ) )     {
	} else if ( strstr( buf, "riva tnt " ) )    {
	}

	if ( strstr( buf, "geforce3" ) ||
		 strstr( buf, "geforce4 ti" ) ||
		 strstr( buf, "geforce fx 5600" ) ||
		 strstr( buf, "geforce fx 5800" ) ||
		 strstr( buf, "radeon 8500" ) ||
		 strstr( buf, "radeon 9000" ) ||
		 strstr( buf, "radeon 9500" ) ||
		 strstr( buf, "radeon 9600" ) ||
		 strstr( buf, "radeon 9700" ) ||
		 strstr( buf, "radeon 9800" ) ||
		 strstr( buf, "nv20" ) ||
		 strstr( buf, "nv30" ) ) {
		ri.Cvar_Set( "r_highQualityVideo", "1" );
	} else {
		ri.Cvar_Set( "r_highQualityVideo", "0" );
	}

	ri.Cvar_Set( "r_lastValidRenderer", glConfig.renderer_string );

	GLW_InitExtensions();
	WG_CheckHardwareGamma();

	// initialise default lists
	GLW_GenDefaultLists();
}
Example #2
0
/*
====================
RE_RegisterModel

Loads in a model for the given name

Zero will be returned if the model fails to load.
An entry will be retained for failed models as an
optimization to prevent disk rescanning if they are
asked for again.
====================
*/
qhandle_t RE_RegisterModel( const char *name )
{
	model_t   *mod;
	unsigned  *buffer;
	int       bufferLen = 0;
	int       lod;
	int       ident;
	qboolean  loaded;
	qhandle_t hModel;
	int       numLoaded;

	if ( !name || !name[ 0 ] )
	{
		ri.Printf( PRINT_ALL, "RE_RegisterModel: NULL name\n" );
		return 0;
	}

	if ( strlen( name ) >= MAX_QPATH )
	{
		Com_Printf( "Model name exceeds MAX_QPATH\n" );
		return 0;
	}

	// search the currently loaded models
	for ( hModel = 1; hModel < tr.numModels; hModel++ )
	{
		mod = tr.models[ hModel ];

		if ( !strcmp( mod->name, name ) )
		{
			if ( mod->type == MOD_BAD )
			{
				return 0;
			}

			return hModel;
		}
	}

	// allocate a new model_t
	if ( ( mod = R_AllocModel() ) == NULL )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterModel: R_AllocModel() failed for '%s'\n", name );
		return 0;
	}

	// only set the name after the model has been successfully loaded
	Q_strncpyz( mod->name, name, sizeof( mod->name ) );

	// make sure the render thread is stopped
	R_SyncRenderThread();

	mod->numLods = 0;

	// load the files
	numLoaded = 0;

#if defined( COMPAT_ET )

	if ( strstr( name, ".mds" ) || strstr( name, ".mdm" ) || strstr( name, ".mdx" ) || strstr( name, ".md5mesh" ) || strstr( name, ".psk" ) )
#else
	if ( strstr( name, ".md5mesh" ) || strstr( name, ".psk" ) )
#endif
	{
		// try loading skeletal file

		loaded = qfalse;
		bufferLen = ri.FS_ReadFile( name, ( void ** ) &buffer );

		if ( buffer )
		{
			loadmodel = mod;

			ident = LittleLong( * ( unsigned * ) buffer );
#if defined( COMPAT_ET )
#if 0

			if ( ident == MDS_IDENT )
			{
				loaded = R_LoadMDS( mod, buffer, name );
			}
			else
#endif
				if ( ident == MDM_IDENT )
				{
					loaded = R_LoadMDM( mod, buffer, name );
				}
				else if ( ident == MDX_IDENT )
				{
					loaded = R_LoadMDX( mod, buffer, name );
				}

#endif

#if defined( USE_REFENTITY_ANIMATIONSYSTEM )

			if ( !Q_stricmpn( ( const char * ) buffer, "MD5Version", 10 ) )
			{
				loaded = R_LoadMD5( mod, buffer, bufferLen, name );
			}
			else if ( !Q_stricmpn( ( const char * ) buffer, PSK_IDENTSTRING, PSK_IDENTLEN ) )
			{
				loaded = R_LoadPSK( mod, buffer, bufferLen, name );
			}

#endif
			ri.FS_FreeFile( buffer );
		}

		if ( loaded )
		{
			// make sure the VBO glState entries are save
			R_BindNullVBO();
			R_BindNullIBO();

			return mod->index;
		}
	}

	for ( lod = MD3_MAX_LODS - 1; lod >= 0; lod-- )
	{
		char filename[ 1024 ];

		strcpy( filename, name );

		if ( lod != 0 )
		{
			char namebuf[ 80 ];

			if ( strrchr( filename, '.' ) )
			{
				*strrchr( filename, '.' ) = 0;
			}

			sprintf( namebuf, "_%d.md3", lod );
			strcat( filename, namebuf );
		}

		filename[ strlen( filename ) - 1 ] = '3';  // try MD3 first
		ri.FS_ReadFile( filename, ( void ** ) &buffer );

		if ( !buffer )
		{
			filename[ strlen( filename ) - 1 ] = 'c';  // try MDC second
			ri.FS_ReadFile( filename, ( void ** ) &buffer );

			if ( !buffer )
			{
				continue;
			}
		}

		loadmodel = mod;

		ident = LittleLong( * ( unsigned * ) buffer );

		if ( ident == MD3_IDENT )
		{
			loaded = R_LoadMD3( mod, lod, buffer, bufferLen, name );
			ri.FS_FreeFile( buffer );
		}

#if defined( COMPAT_ET )
		else if ( ident == MDC_IDENT )
		{
			loaded = R_LoadMDC( mod, lod, buffer, bufferLen, name );
			ri.FS_FreeFile( buffer );
		}

#endif
		else
		{
			ri.FS_FreeFile( buffer );

			ri.Printf( PRINT_WARNING, "RE_RegisterModel: unknown fileid for %s\n", name );
			goto fail;
		}

		if ( !loaded )
		{
			if ( lod == 0 )
			{
				goto fail;
			}
			else
			{
				break;
			}
		}
		else
		{
			// make sure the VBO glState entries are save
			R_BindNullVBO();
			R_BindNullIBO();

			mod->numLods++;
			numLoaded++;
			// if we have a valid model and are biased
			// so that we won't see any higher detail ones,
			// stop loading them
//          if ( lod <= r_lodbias->integer ) {
//              break;
//          }
		}
	}

	// make sure the VBO glState entries are save
	R_BindNullVBO();
	R_BindNullIBO();

	if ( numLoaded )
	{
		// duplicate into higher lod spots that weren't
		// loaded, in case the user changes r_lodbias on the fly
		for ( lod--; lod >= 0; lod-- )
		{
			mod->numLods++;
			mod->mdv[ lod ] = mod->mdv[ lod + 1 ];
		}

		return mod->index;
	}

#ifndef NDEBUG
	else
	{
		ri.Printf( PRINT_WARNING, "couldn't load '%s'\n", name );
	}

#endif

fail:
	// we still keep the model_t around, so if the model name is asked for
	// again, we won't bother scanning the filesystem
	mod->type = MOD_BAD;

	// make sure the VBO glState entries are save
	R_BindNullVBO();
	R_BindNullIBO();

	return 0;
}
Example #3
0
static qboolean R_LoadMD5Anim( skelAnimation_t *skelAnim, void *buffer, int bufferSize, const char *name )
{
	int            i, j;
	md5Animation_t *anim;
	md5Frame_t     *frame;
	md5Channel_t   *channel;
	char           *token;
	int            version;
	char           *buf_p;

	buf_p = buffer;

	skelAnim->type = AT_MD5;
	skelAnim->md5 = anim = ri.Hunk_Alloc( sizeof( *anim ), h_low );

	// skip MD5Version indent string
	COM_ParseExt2( &buf_p, qfalse );

	// check version
	token = COM_ParseExt2( &buf_p, qfalse );
	version = atoi( token );

	if ( version != MD5_VERSION )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: '%s' has wrong version (%i should be %i)\n", name, version, MD5_VERSION );
		return qfalse;
	}

	// skip commandline <arguments string>
	token = COM_ParseExt2( &buf_p, qtrue );
	token = COM_ParseExt2( &buf_p, qtrue );

	// parse numFrames <number>
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "numFrames" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected 'numFrames' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );
	anim->numFrames = atoi( token );

	// parse numJoints <number>
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "numJoints" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected 'numJoints' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );
	anim->numChannels = atoi( token );

	// parse frameRate <number>
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "frameRate" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected 'frameRate' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );
	anim->frameRate = atoi( token );

	// parse numAnimatedComponents <number>
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "numAnimatedComponents" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected 'numAnimatedComponents' found '%s' in model '%s'\n", token,
		           name );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );
	anim->numAnimatedComponents = atoi( token );

	// parse hierarchy {
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "hierarchy" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected 'hierarchy' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );

	if ( Q_stricmp( token, "{" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '{' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	// parse all the channels
	anim->channels = ri.Hunk_Alloc( sizeof( md5Channel_t ) * anim->numChannels, h_low );

	for ( i = 0, channel = anim->channels; i < anim->numChannels; i++, channel++ )
	{
		token = COM_ParseExt2( &buf_p, qtrue );
		Q_strncpyz( channel->name, token, sizeof( channel->name ) );

		//ri.Printf(PRINT_ALL, "RE_RegisterAnimation: '%s' has channel '%s'\n", name, channel->name);

		token = COM_ParseExt2( &buf_p, qfalse );
		channel->parentIndex = atoi( token );

		if ( channel->parentIndex >= anim->numChannels )
		{
			ri.Error( ERR_DROP, "RE_RegisterAnimation: '%s' has channel '%s' with bad parent index %i while numBones is %i\n",
			          name, channel->name, channel->parentIndex, anim->numChannels );
		}

		token = COM_ParseExt2( &buf_p, qfalse );
		channel->componentsBits = atoi( token );

		token = COM_ParseExt2( &buf_p, qfalse );
		channel->componentsOffset = atoi( token );
	}

	// parse }
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "}" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '}' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	// parse bounds {
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "bounds" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected 'bounds' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );

	if ( Q_stricmp( token, "{" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '{' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	anim->frames = ri.Hunk_Alloc( sizeof( md5Frame_t ) * anim->numFrames, h_low );

	for ( i = 0, frame = anim->frames; i < anim->numFrames; i++, frame++ )
	{
		// skip (
		token = COM_ParseExt2( &buf_p, qtrue );

		if ( Q_stricmp( token, "(" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '(' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}

		for ( j = 0; j < 3; j++ )
		{
			token = COM_ParseExt2( &buf_p, qfalse );
			frame->bounds[ 0 ][ j ] = atof( token );
		}

		// skip )
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, ")" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected ')' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}

		// skip (
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, "(" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '(' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}

		for ( j = 0; j < 3; j++ )
		{
			token = COM_ParseExt2( &buf_p, qfalse );
			frame->bounds[ 1 ][ j ] = atof( token );
		}

		// skip )
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, ")" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected ')' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}
	}

	// parse }
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "}" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '}' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	// parse baseframe {
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "baseframe" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected 'baseframe' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	token = COM_ParseExt2( &buf_p, qfalse );

	if ( Q_stricmp( token, "{" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '{' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	for ( i = 0, channel = anim->channels; i < anim->numChannels; i++, channel++ )
	{
		// skip (
		token = COM_ParseExt2( &buf_p, qtrue );

		if ( Q_stricmp( token, "(" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '(' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}

		for ( j = 0; j < 3; j++ )
		{
			token = COM_ParseExt2( &buf_p, qfalse );
			channel->baseOrigin[ j ] = atof( token );
		}

		// skip )
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, ")" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected ')' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}

		// skip (
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, "(" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '(' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}

		for ( j = 0; j < 3; j++ )
		{
			token = COM_ParseExt2( &buf_p, qfalse );
			channel->baseQuat[ j ] = atof( token );
		}

		QuatCalcW( channel->baseQuat );

		// skip )
		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, ")" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected ')' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}
	}

	// parse }
	token = COM_ParseExt2( &buf_p, qtrue );

	if ( Q_stricmp( token, "}" ) )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '}' found '%s' in model '%s'\n", token, name );
		return qfalse;
	}

	for ( i = 0, frame = anim->frames; i < anim->numFrames; i++, frame++ )
	{
		// parse frame <number> {
		token = COM_ParseExt2( &buf_p, qtrue );

		if ( Q_stricmp( token, "frame" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected 'baseframe' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}

		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, va( "%i", i ) ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '%i' found '%s' in model '%s'\n", i, token, name );
			return qfalse;
		}

		token = COM_ParseExt2( &buf_p, qfalse );

		if ( Q_stricmp( token, "{" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '{' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}

		frame->components = ri.Hunk_Alloc( sizeof( float ) * anim->numAnimatedComponents, h_low );

		for ( j = 0; j < anim->numAnimatedComponents; j++ )
		{
			token = COM_ParseExt2( &buf_p, qtrue );
			frame->components[ j ] = atof( token );
		}

		// parse }
		token = COM_ParseExt2( &buf_p, qtrue );

		if ( Q_stricmp( token, "}" ) )
		{
			ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: expected '}' found '%s' in model '%s'\n", token, name );
			return qfalse;
		}
	}

	// everything went ok
	return qtrue;
}
Example #4
0
/*
============
Cmd_ArgsBuffer

The interpreted versions use this because
they can't have pointers returned to them
============
*/
M_EXPORT void	M_DECL Cmd_ArgsBuffer( char *buffer, int bufferLength ) {
	Q_strncpyz( buffer, Cmd_Args(), bufferLength );
}
Example #5
0
/*
==========================
UI_RegisterClientModelname
==========================
*/
qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName, const char *headModelSkinName, const char *teamName ) {
    char		modelName[MAX_QPATH];
    char		skinName[MAX_QPATH];
    char		headModelName[MAX_QPATH];
    char		headSkinName[MAX_QPATH];
    char		filename[MAX_QPATH];
    char		*slash;

    pi->torsoModel = 0;
    pi->headModel = 0;

    if ( !modelSkinName[0] ) {
        return qfalse;
    }

    Q_strncpyz( modelName, modelSkinName, sizeof( modelName ) );

    slash = strchr( modelName, '/' );
    if ( !slash ) {
        // modelName did not include a skin name
        Q_strncpyz( skinName, "default", sizeof( skinName ) );
    } else {
        Q_strncpyz( skinName, slash + 1, sizeof( skinName ) );
        *slash = '\0';
    }

    Q_strncpyz( headModelName, headModelSkinName, sizeof( headModelName ) );
    slash = strchr( headModelName, '/' );
    if ( !slash ) {
        // modelName did not include a skin name
        Q_strncpyz( headSkinName, "default", sizeof( skinName ) );
    } else {
        Q_strncpyz( headSkinName, slash + 1, sizeof( skinName ) );
        *slash = '\0';
    }

    // load cmodels before models so filecache works

    Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower.md3", modelName );
    pi->legsModel = trap_R_RegisterModel( filename );
    if ( !pi->legsModel ) {
        Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/lower.md3", modelName );
        pi->legsModel = trap_R_RegisterModel( filename );
        if ( !pi->legsModel ) {
            Com_Printf( "Failed to load model file %s\n", filename );
            return qfalse;
        }
    }

    Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper.md3", modelName );
    pi->torsoModel = trap_R_RegisterModel( filename );
    if ( !pi->torsoModel ) {
        Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/upper.md3", modelName );
        pi->torsoModel = trap_R_RegisterModel( filename );
        if ( !pi->torsoModel ) {
            Com_Printf( "Failed to load model file %s\n", filename );
            return qfalse;
        }
    }

    if (headModelName[0] == '*' ) {
        Com_sprintf( filename, sizeof( filename ), "models/players/heads/%s/%s.md3", &headModelName[1], &headModelName[1] );
    }
    else {
        Com_sprintf( filename, sizeof( filename ), "models/players/%s/head.md3", headModelName );
    }
    pi->headModel = trap_R_RegisterModel( filename );
    if ( !pi->headModel && headModelName[0] != '*') {
        Com_sprintf( filename, sizeof( filename ), "models/players/heads/%s/%s.md3", headModelName, headModelName );
        pi->headModel = trap_R_RegisterModel( filename );
    }

    if (!pi->headModel) {
        Com_Printf( "Failed to load model file %s\n", filename );
        return qfalse;
    }

    // if any skins failed to load, fall back to default
    if ( !UI_RegisterClientSkin( pi, modelName, skinName, headModelName, headSkinName, teamName) ) {
        if ( !UI_RegisterClientSkin( pi, modelName, "default", headModelName, "default", teamName ) ) {
            Com_Printf( "Failed to load skin file: %s : %s\n", modelName, skinName );
            return qfalse;
        }
    }

    // load the animations
    Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", modelName );
    if ( !UI_ParseAnimationFile( filename, pi->animations ) ) {
        Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/animation.cfg", modelName );
        if ( !UI_ParseAnimationFile( filename, pi->animations ) ) {
            Com_Printf( "Failed to load animation file %s\n", filename );
            return qfalse;
        }
    }

    return qtrue;
}
Example #6
0
/*
============
Cmd_TokenizeString

Parses the given string into command line tokens.
The text is copied to a seperate buffer and 0 characters
are inserted in the apropriate place, The argv array
will point into this temporary buffer.
============
*/
static void Cmd_TokenizeString2(const char *text_in, qboolean ignoreQuotes)
{
	const char *text;
	char       *textOut;

	// clear previous args
	cmd_argc = 0;

	if (!text_in)
	{
		return;
	}

	Q_strncpyz(cmd_cmd, text_in, sizeof(cmd_cmd));

	text    = text_in;
	textOut = cmd_tokenized;

	while (1)
	{
		if (cmd_argc == MAX_STRING_TOKENS)
		{
			return;         // this is usually something malicious
		}

		while (1)
		{
			// skip whitespace
			while (*text && *text <= ' ')
			{
				text++;
			}
			if (!*text)
			{
				return;         // all tokens parsed
			}

			// skip // comments
			if (text[0] == '/' && text[1] == '/')
			{
				// lets us put 'http://' in commandlines
				if (text == text_in || (text > text_in && text[-1] != ':'))
				{
					return;         // all tokens parsed
				}
			}

			// skip /* */ comments
			if (text[0] == '/' && text[1] == '*')
			{
				while (*text && (text[0] != '*' || text[1] != '/'))
				{
					text++;
				}
				if (!*text)
				{
					return;     // all tokens parsed
				}
				text += 2;
			}
			else
			{
				break;          // we are ready to parse a token
			}
		}

		// handle quoted strings
		// NOTE: this doesn't handle \" escaping
		if (!ignoreQuotes && *text == '"')
		{
			cmd_argv[cmd_argc] = textOut;
			cmd_argc++;
			text++;
			while (*text && *text != '"')
			{
				*textOut++ = *text++;
			}
			*textOut++ = 0;
			if (!*text)
			{
				return;     // all tokens parsed
			}
			text++;
			continue;
		}

		// regular token
		cmd_argv[cmd_argc] = textOut;
		cmd_argc++;

		// skip until whitespace, quote, or command
		while (*text > ' ')
		{
			if (!ignoreQuotes && text[0] == '"')
			{
				break;
			}

			if (text[0] == '/' && text[1] == '/')
			{
				// lets us put 'http://' in commandlines
				if (text == text_in || (text > text_in && text[-1] != ':'))
				{
					break;
				}
			}

			// skip /* */ comments
			if (text[0] == '/' && text[1] == '*')
			{
				break;
			}

			*textOut++ = *text++;
		}

		*textOut++ = 0;

		if (!*text)
		{
			return;     // all tokens parsed
		}
	}
}
Example #7
0
/*
=================
UI_SPPostgameMenu_f
=================
*/
void UI_SPPostgameMenu_f( void ) {
    int			playerGameRank;
    int			playerClientNum;
    int			n;
    int			oldFrags, newFrags;
    const char	*arena;
    int			awardValues[6];
    char		map[MAX_QPATH];
    char		info[MAX_INFO_STRING];

    memset( &postgameMenuInfo, 0, sizeof(postgameMenuInfo) );

    trap_GetConfigString( CS_SYSTEMINFO, info, sizeof(info) );
    postgameMenuInfo.serverId = atoi( Info_ValueForKey( info, "sv_serverid" ) );

    trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
    Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) );
    arena = UI_GetArenaInfoByMap( map );
    if ( !arena ) {
        return;
    }
    Q_strncpyz( arenainfo, arena, sizeof(arenainfo) );

    postgameMenuInfo.level = atoi( Info_ValueForKey( arenainfo, "num" ) );

    postgameMenuInfo.numClients = atoi( UI_Argv( 1 ) );
    playerClientNum = atoi( UI_Argv( 2 ) );
    playerGameRank = 8;		// in case they ended game as a spectator

    if( postgameMenuInfo.numClients > MAX_SCOREBOARD_CLIENTS ) {
        postgameMenuInfo.numClients = MAX_SCOREBOARD_CLIENTS;
    }

    for( n = 0; n < postgameMenuInfo.numClients; n++ ) {
        postgameMenuInfo.clientNums[n] = atoi( UI_Argv( 8 + n * 3 + 1 ) );
        postgameMenuInfo.ranks[n] = atoi( UI_Argv( 8 + n * 3 + 2 ) );
        postgameMenuInfo.scores[n] = atoi( UI_Argv( 8 + n * 3 + 3 ) );

        if( postgameMenuInfo.clientNums[n] == playerClientNum ) {
            playerGameRank = (postgameMenuInfo.ranks[n] & ~RANK_TIED_FLAG) + 1;
        }
    }

    UI_SetBestScore( postgameMenuInfo.level, playerGameRank );

    // process award stats and prepare presentation data
    awardValues[AWARD_ACCURACY] = atoi( UI_Argv( 3 ) );
    awardValues[AWARD_IMPRESSIVE] = atoi( UI_Argv( 4 ) );
    awardValues[AWARD_EXCELLENT] = atoi( UI_Argv( 5 ) );
    awardValues[AWARD_GAUNTLET] = atoi( UI_Argv( 6 ) );
    awardValues[AWARD_FRAGS] = atoi( UI_Argv( 7 ) );
    awardValues[AWARD_PERFECT] = atoi( UI_Argv( 8 ) );

    postgameMenuInfo.numAwards = 0;

    if( awardValues[AWARD_ACCURACY] >= 50 ) {
        UI_LogAwardData( AWARD_ACCURACY, 1 );
        postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_ACCURACY;
        postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_ACCURACY];
        postgameMenuInfo.numAwards++;
    }

    if( awardValues[AWARD_IMPRESSIVE] ) {
        UI_LogAwardData( AWARD_IMPRESSIVE, awardValues[AWARD_IMPRESSIVE] );
        postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_IMPRESSIVE;
        postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_IMPRESSIVE];
        postgameMenuInfo.numAwards++;
    }

    if( awardValues[AWARD_EXCELLENT] ) {
        UI_LogAwardData( AWARD_EXCELLENT, awardValues[AWARD_EXCELLENT] );
        postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_EXCELLENT;
        postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_EXCELLENT];
        postgameMenuInfo.numAwards++;
    }

    if( awardValues[AWARD_GAUNTLET] ) {
        UI_LogAwardData( AWARD_GAUNTLET, awardValues[AWARD_GAUNTLET] );
        postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_GAUNTLET;
        postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = awardValues[AWARD_GAUNTLET];
        postgameMenuInfo.numAwards++;
    }

    oldFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100;
    UI_LogAwardData( AWARD_FRAGS, awardValues[AWARD_FRAGS] );
    newFrags = UI_GetAwardLevel( AWARD_FRAGS ) / 100;
    if( newFrags > oldFrags ) {
        postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_FRAGS;
        postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = newFrags * 100;
        postgameMenuInfo.numAwards++;
    }

    if( awardValues[AWARD_PERFECT] ) {
        UI_LogAwardData( AWARD_PERFECT, 1 );
        postgameMenuInfo.awardsEarned[postgameMenuInfo.numAwards] = AWARD_PERFECT;
        postgameMenuInfo.awardsLevels[postgameMenuInfo.numAwards] = 1;
        postgameMenuInfo.numAwards++;
    }

    if ( playerGameRank == 1 ) {
        postgameMenuInfo.won = UI_TierCompleted( postgameMenuInfo.level );
    }
    else {
        postgameMenuInfo.won = -1;
    }

    postgameMenuInfo.starttime = uis.realtime;
    postgameMenuInfo.scoreboardtime = uis.realtime;

    trap_Key_SetCatcher( KEYCATCH_UI );
    uis.menusp = 0;

    UI_SPPostgameMenu_Init();
    UI_PushMenu( &postgameMenuInfo.menu );

    if ( playerGameRank == 1 ) {
        Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_next );
    }
    else {
        Menu_SetCursorToItem( &postgameMenuInfo.menu, &postgameMenuInfo.item_again );
    }

    Prepname( 0 );
    Prepname( 1 );
    Prepname( 2 );

    if ( playerGameRank != 1 ) {
        postgameMenuInfo.winnerSound = trap_S_RegisterSound( va( "sound/player/announce/%s_wins.wav", postgameMenuInfo.placeNames[0] ), qfalse );
        trap_Cmd_ExecuteText( EXEC_APPEND, "music music/loss\n" );
    }
    else {
        postgameMenuInfo.winnerSound = trap_S_RegisterSound( "sound/player/announce/youwin.wav", qfalse );
        trap_Cmd_ExecuteText( EXEC_APPEND, "music music/win\n" );
    }

    postgameMenuInfo.phase = 1;

    postgameMenuInfo.lastTier = UI_GetNumSPTiers();
    if ( UI_GetSpecialArenaInfo( "final" ) ) {
        postgameMenuInfo.lastTier++;
    }
    trap_Cvar_Set( "cl_postgame", "1" );
}
Example #8
0
/*
=====================
Cvar_InfoStringBuffer
=====================
*/
void Cvar_InfoStringBuffer( int bit, char* buff, int buffsize ) {
	Q_strncpyz(buff,Cvar_InfoString(bit),buffsize);
}
Example #9
0
/*
====================
RE_RegisterModel
 
Loads in a model for the given name
 
Zero will be returned if the model fails to load.
An entry will be retained for failed models as an
optimization to prevent disk rescanning if they are
asked for again.
====================
*/
qhandle_t RE_RegisterModel( const char *name )
{
    model_t		*mod;
    unsigned	*buf;
    int			lod;
    int			ident;
    qboolean	loaded;
    qhandle_t	hModel;
    int			numLoaded;

    if ( !name || !name[0] )
    {
        CL_RefPrintf( PRINT_ALL, "RE_RegisterModel: NULL name\n" );
        return 0;
    }

    if ( strlen( name ) >= MAX_QPATH )
    {
        Com_Printf( "Model name exceeds MAX_QPATH\n" );
        return 0;
    }

    //
    // search the currently loaded models
    //
    for ( hModel = 1 ; hModel < tr.numModels; hModel++ )
    {
        mod = tr.models[hModel];
        if ( !strcmp( mod->name, name ) )
        {
            if( mod->type == MOD_BAD )
            {
                return 0;
            }
            return hModel;
        }
    }

    // allocate a new model_t

    if ( ( mod = R_AllocModel() ) == NULL )
    {
        CL_RefPrintf( PRINT_WARNING, "RE_RegisterModel: R_AllocModel() failed for '%s'\n", name);
        return 0;
    }

    // only set the name after the model has been successfully loaded
    Q_strncpyz( mod->name, name, sizeof( mod->name ) );


    // make sure the render thread is stopped
    R_SyncRenderThread();

    mod->numLods = 0;

    //
    // load the files
    //
    numLoaded = 0;

    for ( lod = MD3_MAX_LODS - 1 ; lod >= 0 ; lod-- )
    {
        char filename[1024];

        strcpy( filename, name );

        if ( lod != 0 )
        {
            char namebuf[80];

            if ( strrchr( filename, '.' ) )
            {
                *strrchr( filename, '.' ) = 0;
            }
            sprintf( namebuf, "_%d.md3", lod );
            strcat( filename, namebuf );
        }

        FS_ReadFile( filename, (void **)&buf );
        if ( !buf )
        {
            continue;
        }

        loadmodel = mod;

        ident = LittleLong(*(unsigned *)buf);
        if ( ident == MD4_IDENT )
        {
            loaded = R_LoadMD4( mod, buf, name );
        }
        else
        {
            if ( ident != MD3_IDENT )
            {
                CL_RefPrintf (PRINT_WARNING,"RE_RegisterModel: unknown fileid for %s\n", name);
                goto fail;
            }

            loaded = R_LoadMD3( mod, lod, buf, name );
        }

        FS_FreeFile (buf);

        if ( !loaded )
        {
            if ( lod == 0 )
            {
                goto fail;
            }
            else
            {
                break;
            }
        }
        else
        {
            mod->numLods++;
            numLoaded++;
            // if we have a valid model and are biased
            // so that we won't see any higher detail ones,
            // stop loading them
//			if ( lod <= r_lodbias->integer ) {
//				break;
//			}
        }
    }

    if ( numLoaded )
    {
        // duplicate into higher lod spots that weren't
        // loaded, in case the user changes r_lodbias on the fly
        for ( lod-- ; lod >= 0 ; lod-- )
        {
            mod->numLods++;
            mod->md3[lod] = mod->md3[lod+1];
        }

        return mod->index;
    }
#ifdef _DEBUG
    else
    {
        CL_RefPrintf (PRINT_WARNING,"RE_RegisterModel: couldn't load %s\n", name);
    }
#endif

fail:
    // we still keep the model_t around, so if the model name is asked for
    // again, we won't bother scanning the filesystem
    mod->type = MOD_BAD;
    return 0;
}
Example #10
0
void G_Say( gentity_t *ent, gentity_t *target, int mode, const char *chatText ) {
	int			j;
	gentity_t	*other;
	int			color;
	char		name[64];
	// don't let text be too long for malicious reasons
	char		text[MAX_SAY_TEXT];
	char		location[64];

	if ( g_gametype.integer < GT_TEAM && mode == SAY_TEAM ) {
		mode = SAY_ALL;
	}

	/* LQ3A: Spectators can only talk to other spectators when muted. */
	if ((ent->client->sess.sessionTeam == TEAM_SPECTATOR) && g_spectatorMute.integer)
	{
		mode = SAY_TEAM;
	}

	switch ( mode ) {
	default:
	case SAY_ALL:
		G_LogPrintf( "say: %s: %s\n", ent->client->pers.netname, chatText );
		Com_sprintf (name, sizeof(name), "%s%c%c"EC": ", ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE );
		color = COLOR_GREEN;
		break;
	case SAY_TEAM:
		G_LogPrintf( "sayteam: %s: %s\n", ent->client->pers.netname, chatText );
		if (Team_GetLocationMsg(ent, location, sizeof(location)))
			Com_sprintf (name, sizeof(name), EC"(%s%c%c"EC") (%s)"EC": ", 
				ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location);
		else
			Com_sprintf (name, sizeof(name), EC"(%s%c%c"EC")"EC": ", 
				ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE );
		color = COLOR_CYAN;
		break;
	case SAY_TELL:
		if (target && g_gametype.integer >= GT_TEAM &&
			target->client->sess.sessionTeam == ent->client->sess.sessionTeam &&
			Team_GetLocationMsg(ent, location, sizeof(location)))
			Com_sprintf (name, sizeof(name), EC"[%s%c%c"EC"] (%s)"EC": ", ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE, location );
		else
			Com_sprintf (name, sizeof(name), EC"[%s%c%c"EC"]"EC": ", ent->client->pers.netname, Q_COLOR_ESCAPE, COLOR_WHITE );
		color = COLOR_MAGENTA;
		break;
	}

	Q_strncpyz( text, chatText, sizeof(text) );

	if ( target ) {
		G_SayTo( ent, target, mode, color, name, text );
		return;
	}

	// echo the text to the console
	if ( g_dedicated.integer ) {
		G_Printf( "%s%s\n", name, text);
	}

	// send it to all the apropriate clients
	for (j = 0; j < level.maxclients; j++) {
		other = &g_entities[j];
		G_SayTo( ent, other, mode, color, name, text );
	}
}
Example #11
0
/*
==================
Cmd_CallTeamVote_f
==================
*/
void Cmd_CallTeamVote_f( gentity_t *ent ) {
	int		i, team, cs_offset;
	char	arg1[MAX_STRING_TOKENS];
	char	arg2[MAX_STRING_TOKENS];

	team = ent->client->sess.sessionTeam;
	if ( team == TEAM_RED )
		cs_offset = 0;
	else if ( team == TEAM_BLUE )
		cs_offset = 1;
	else
		return;

	if ( !g_allowVote.integer ) {
		trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here.\n\"" );
		return;
	}

	if ( level.teamVoteTime[cs_offset] ) {
		trap_SendServerCommand( ent-g_entities, "print \"A team vote is already in progress.\n\"" );
		return;
	}
	if ( ent->client->pers.teamVoteCount >= MAX_VOTE_COUNT ) {
		trap_SendServerCommand( ent-g_entities, "print \"You have called the maximum number of team votes.\n\"" );
		return;
	}
	if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
		trap_SendServerCommand( ent-g_entities, "print \"Not allowed to call a vote as spectator.\n\"" );
		return;
	}

	// make sure it is a valid command to vote on
	trap_Argv( 1, arg1, sizeof( arg1 ) );
	arg2[0] = '\0';
	for ( i = 2; i < trap_Argc(); i++ ) {
		if (i > 2)
			strcat(arg2, " ");
		trap_Argv( i, &arg2[strlen(arg2)], sizeof( arg2 ) - strlen(arg2) );
	}

	if( strchr( arg1, ';' ) || strchr( arg2, ';' ) ) {
		trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
		return;
	}

	if ( !Q_stricmp( arg1, "leader" ) ) {
		char netname[MAX_NETNAME], leader[MAX_NETNAME];

		if ( !arg2[0] ) {
			i = ent->client->ps.clientNum;
		}
		else {
			// numeric values are just slot numbers
			for (i = 0; i < 3; i++) {
				if ( !arg2[i] || arg2[i] < '0' || arg2[i] > '9' )
					break;
			}
			if ( i >= 3 || !arg2[i]) {
				i = atoi( arg2 );
				if ( i < 0 || i >= level.maxclients ) {
					trap_SendServerCommand( ent-g_entities, va("print \"Bad client slot: %i\n\"", i) );
					return;
				}

				if ( !g_entities[i].inuse ) {
					trap_SendServerCommand( ent-g_entities, va("print \"Client %i is not active\n\"", i) );
					return;
				}
			}
			else {
				Q_strncpyz(leader, arg2, sizeof(leader));
				Q_CleanStr(leader);
				for ( i = 0 ; i < level.maxclients ; i++ ) {
					if ( level.clients[i].pers.connected == CON_DISCONNECTED )
						continue;
					if (level.clients[i].sess.sessionTeam != team)
						continue;
					Q_strncpyz(netname, level.clients[i].pers.netname, sizeof(netname));
					Q_CleanStr(netname);
					if ( !Q_stricmp(netname, leader) ) {
						break;
					}
				}
				if ( i >= level.maxclients ) {
					trap_SendServerCommand( ent-g_entities, va("print \"%s is not a valid player on your team.\n\"", arg2) );
					return;
				}
			}
		}
		Com_sprintf(arg2, sizeof(arg2), "%d", i);
	} else {
		trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
		trap_SendServerCommand( ent-g_entities, "print \"Team vote commands are: leader <player>.\n\"" );
		return;
	}

	Com_sprintf( level.teamVoteString[cs_offset], sizeof( level.teamVoteString[cs_offset] ), "%s %s", arg1, arg2 );

	for ( i = 0 ; i < level.maxclients ; i++ ) {
		if ( level.clients[i].pers.connected == CON_DISCONNECTED )
			continue;
		if (level.clients[i].sess.sessionTeam == team)
			trap_SendServerCommand( i, va("print \"%s called a team vote.\n\"", ent->client->pers.netname ) );
	}

	// start the voting, the caller autoamtically votes yes
	level.teamVoteTime[cs_offset] = level.time;
	level.teamVoteYes[cs_offset] = 1;
	level.teamVoteNo[cs_offset] = 0;

	for ( i = 0 ; i < level.maxclients ; i++ ) {
		if (level.clients[i].sess.sessionTeam == team)
			level.clients[i].ps.eFlags &= ~EF_TEAMVOTED;
	}
	ent->client->ps.eFlags |= EF_TEAMVOTED;

	trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, va("%i", level.teamVoteTime[cs_offset] ) );
	trap_SetConfigstring( CS_TEAMVOTE_STRING + cs_offset, level.teamVoteString[cs_offset] );
	trap_SetConfigstring( CS_TEAMVOTE_YES + cs_offset, va("%i", level.teamVoteYes[cs_offset] ) );
	trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset, va("%i", level.teamVoteNo[cs_offset] ) );
}
Example #12
0
void BG_SiegeParseClassFile(const char *filename, siegeClassDesc_t *descBuffer)
{
	fileHandle_t f;
	int len;
	int i;
	char classInfo[4096];
	char parseBuf[4096];

	len = trap->FS_Open( filename, &f, FS_READ );

	if (!f || len >= 4096)
	{
		return;
	}

	trap->FS_Read( classInfo, len, f );

	trap->FS_Close( f );

	classInfo[len] = 0;

	//first get the description if we have a buffer for it
	if (descBuffer)
	{
		if (!BG_SiegeGetPairedValue(classInfo, "description", descBuffer->desc))
		{
			Q_strncpyz(descBuffer->desc, "DESCRIPTION UNAVAILABLE", sizeof(descBuffer->desc));
		}

		//Hit this assert?  Memory has already been trashed.  Increase
		//SIEGE_CLASS_DESC_LEN.
		assert(strlen(descBuffer->desc) < SIEGE_CLASS_DESC_LEN);
	}

	BG_SiegeGetValueGroup(classInfo, "ClassInfo", classInfo);

	//Parse name
	if (BG_SiegeGetPairedValue(classInfo, "name", parseBuf))
	{
		Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].name, parseBuf, sizeof(bgSiegeClasses[0].name));
	}
	else
	{
		Com_Error(ERR_DROP, "Siege class without name entry");
	}

	//Parse forced model
	if (BG_SiegeGetPairedValue(classInfo, "model", parseBuf))
	{
		Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].forcedModel, parseBuf, sizeof(bgSiegeClasses[0].forcedModel));
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].forcedModel[0] = 0;
	}

	//Parse forced skin
	if (BG_SiegeGetPairedValue(classInfo, "skin", parseBuf))
	{
		Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].forcedSkin, parseBuf, sizeof(bgSiegeClasses[0].forcedSkin));
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].forcedSkin[0] = 0;
	}

	//Parse first saber
	if (BG_SiegeGetPairedValue(classInfo, "saber1", parseBuf))
	{
		Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].saber1, parseBuf, sizeof(bgSiegeClasses[0].saber1));
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].saber1[0] = 0;
	}

	//Parse second saber
	if (BG_SiegeGetPairedValue(classInfo, "saber2", parseBuf))
	{
		Q_strncpyz(bgSiegeClasses[bgNumSiegeClasses].saber2, parseBuf, sizeof(bgSiegeClasses[0].saber2));
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].saber2[0] = 0;
	}

	//Parse forced saber stance
	if (BG_SiegeGetPairedValue(classInfo, "saberstyle", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].saberStance = BG_SiegeTranslateGenericTable(parseBuf, StanceTable, qtrue);
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].saberStance = 0;
	}

	//Parse forced saber color
	if (BG_SiegeGetPairedValue(classInfo, "sabercolor", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].forcedSaberColor = atoi(parseBuf);
		bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qtrue;
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].hasForcedSaberColor = qfalse;
	}

	//Parse forced saber2 color
	if (BG_SiegeGetPairedValue(classInfo, "saber2color", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].forcedSaber2Color = atoi(parseBuf);
		bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qtrue;
	}
	else
	{ //It's ok if there isn't one, it's optional.
		bgSiegeClasses[bgNumSiegeClasses].hasForcedSaber2Color = qfalse;
	}

	//Parse weapons
	if (BG_SiegeGetPairedValue(classInfo, "weapons", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].weapons = BG_SiegeTranslateGenericTable(parseBuf, WPTable, qtrue);
	}
	else
	{
		Com_Error(ERR_DROP, "Siege class without weapons entry");
	}

	if (!(bgSiegeClasses[bgNumSiegeClasses].weapons & (1 << WP_SABER)))
	{ //make sure it has melee if there's no saber
		bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_MELEE);

		//always give them this too if they are not a saber user
		//bgSiegeClasses[bgNumSiegeClasses].weapons |= (1 << WP_BRYAR_PISTOL);
	}

	//Parse forcepowers
	if (BG_SiegeGetPairedValue(classInfo, "forcepowers", parseBuf))
	{
		BG_SiegeTranslateForcePowers(parseBuf, &bgSiegeClasses[bgNumSiegeClasses]);
	}
	else
	{ //fine, clear out the powers.
		i = 0;
		while (i < NUM_FORCE_POWERS)
		{
			bgSiegeClasses[bgNumSiegeClasses].forcePowerLevels[i] = 0;
			i++;
		}
	}

	//Parse classflags
	if (BG_SiegeGetPairedValue(classInfo, "classflags", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].classflags = BG_SiegeTranslateGenericTable(parseBuf, bgSiegeClassFlagNames, qtrue);
	}
	else
	{ //fine, we'll 0 it.
		bgSiegeClasses[bgNumSiegeClasses].classflags = 0;
	}

	//Parse maxhealth
	if (BG_SiegeGetPairedValue(classInfo, "maxhealth", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].maxhealth = atoi(parseBuf);
	}
	else
	{ //It's alright, just default to 100 then.
		bgSiegeClasses[bgNumSiegeClasses].maxhealth = 100;
	}

	//Parse starthealth
	if (BG_SiegeGetPairedValue(classInfo, "starthealth", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].starthealth = atoi(parseBuf);
	}
	else
	{ //It's alright, just default to 100 then.
		bgSiegeClasses[bgNumSiegeClasses].starthealth = bgSiegeClasses[bgNumSiegeClasses].maxhealth;
	}


	//Parse startarmor
	if (BG_SiegeGetPairedValue(classInfo, "maxarmor", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].maxarmor = atoi(parseBuf);
	}
	else
	{ //It's alright, just default to 0 then.
		bgSiegeClasses[bgNumSiegeClasses].maxarmor = 0;
	}

	//Parse startarmor
	if (BG_SiegeGetPairedValue(classInfo, "startarmor", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].startarmor = atoi(parseBuf);
		if (!bgSiegeClasses[bgNumSiegeClasses].maxarmor)
		{ //if they didn't specify a damn max armor then use this.
			bgSiegeClasses[bgNumSiegeClasses].maxarmor = bgSiegeClasses[bgNumSiegeClasses].startarmor;
		}
	}
	else
	{ //default to maxarmor.
		bgSiegeClasses[bgNumSiegeClasses].startarmor = bgSiegeClasses[bgNumSiegeClasses].maxarmor;
	}

	//Parse speed (this is a multiplier value)
	if (BG_SiegeGetPairedValue(classInfo, "speed", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].speed = atof(parseBuf);
	}
	else
	{ //It's alright, just default to 1 then.
		bgSiegeClasses[bgNumSiegeClasses].speed = 1.0f;
	}

	//Parse shader for ui to use
	if (BG_SiegeGetPairedValue(classInfo, "uishader", parseBuf))
	{
		#if defined(_GAME)
			bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0;
			memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait));
		#elif defined(_CGAME)
			bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = 0;
			memset(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,0,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait));
		#elif defined(_UI) //ui
			bgSiegeClasses[bgNumSiegeClasses].uiPortraitShader = trap->R_RegisterShaderNoMip(parseBuf);
			memcpy(bgSiegeClasses[bgNumSiegeClasses].uiPortrait,parseBuf,sizeof(bgSiegeClasses[bgNumSiegeClasses].uiPortrait));
		#endif
	}
	else
	{ //I guess this is an essential.. we don't want to render bad shaders or anything.
		Com_Error(ERR_DROP, "Siege class without uishader entry");
	}

	//Parse shader for ui to use
	if (BG_SiegeGetPairedValue(classInfo, "class_shader", parseBuf))
	{
	#ifdef _GAME
		bgSiegeClasses[bgNumSiegeClasses].classShader = 0;
	#else //cgame, ui
		#if defined(_CGAME)
			bgSiegeClasses[bgNumSiegeClasses].classShader = trap->R_RegisterShaderNoMip(parseBuf);
		#elif defined(_UI)
			bgSiegeClasses[bgNumSiegeClasses].classShader = trap->R_RegisterShaderNoMip(parseBuf);
		#endif
		assert( bgSiegeClasses[bgNumSiegeClasses].classShader );
		if ( !bgSiegeClasses[bgNumSiegeClasses].classShader )
		{
			//Com_Error( ERR_DROP, "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name );
			Com_Printf( "ERROR: could not find class_shader %s for class %s\n", parseBuf, bgSiegeClasses[bgNumSiegeClasses].name );
		}
		// A very hacky way to determine class . . .
		else
	#endif
		{
			// Find the base player class based on the icon name - very bad, I know.
			int titleLength, arrayTitleLength;
			char *holdBuf;

			titleLength = strlen(parseBuf);
			for (i=0;i<SPC_MAX;i++)
			{
				// Back up
				arrayTitleLength = strlen(classTitles[i]);
				if (arrayTitleLength>titleLength)	// Too long
				{
					break;
				}

				holdBuf = parseBuf + ( titleLength - arrayTitleLength);
				if (!strcmp(holdBuf,classTitles[i]))
				{
					bgSiegeClasses[bgNumSiegeClasses].playerClass = i;
					break;
				}
			}

			// In case the icon name doesn't match up
			if (i>=SPC_MAX)
			{
				bgSiegeClasses[bgNumSiegeClasses].playerClass = SPC_INFANTRY;
			}
		}
	}
	else
	{ //No entry!  Bad bad bad
		//Com_Error( ERR_DROP, "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name );
		Com_Printf( "ERROR: no class_shader defined for class %s\n", bgSiegeClasses[bgNumSiegeClasses].name );
	}

	//Parse holdable items to use
	if (BG_SiegeGetPairedValue(classInfo, "holdables", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].invenItems = BG_SiegeTranslateGenericTable(parseBuf, HoldableTable, qtrue);
	}
	else
	{ //Just don't start out with any then.
		bgSiegeClasses[bgNumSiegeClasses].invenItems = 0;
	}

	//Parse powerups to use
	if (BG_SiegeGetPairedValue(classInfo, "powerups", parseBuf))
	{
		bgSiegeClasses[bgNumSiegeClasses].powerups = BG_SiegeTranslateGenericTable(parseBuf, PowerupTable, qtrue);
	}
	else
	{ //Just don't start out with any then.
		bgSiegeClasses[bgNumSiegeClasses].powerups = 0;
	}

	//A successful read.
	bgNumSiegeClasses++;
}
Example #13
0
//======================================
//Class loading functions
//======================================
void BG_SiegeTranslateForcePowers(char *buf, siegeClass_t *siegeClass)
{
	char checkPower[1024];
	char checkLevel[256];
	int l = 0;
	int k = 0;
	int j = 0;
	int i = 0;
	int parsedLevel = 0;
	qboolean allPowers = qfalse;
	qboolean noPowers = qfalse;

	if (!Q_stricmp(buf, "FP_ALL"))
	{ //this is a special case, just give us all the powers on level 3
		allPowers = qtrue;
	}

	if (buf[0] == '0' && !buf[1])
	{ //no powers then
		noPowers = qtrue;
	}

	//First clear out the powers, or in the allPowers case, give us all level 3.
	while (i < NUM_FORCE_POWERS)
	{
		if (allPowers)
		{
			siegeClass->forcePowerLevels[i] = FORCE_LEVEL_3;
		}
		else
		{
			siegeClass->forcePowerLevels[i] = 0;
		}
		i++;
	}

	if (allPowers || noPowers)
	{ //we're done now then.
		return;
	}

	i = 0;
	while (buf[i])
	{ //parse through the list which is seperated by |, and add all the weapons into a bitflag
		if (buf[i] != ' ' && buf[i] != '|')
		{
			j = 0;

			while (buf[i] && buf[i] != ' ' && buf[i] != '|' && buf[i] != ',')
			{
				checkPower[j] = buf[i];
				j++;
				i++;
			}
			checkPower[j] = 0;

			if (buf[i] == ',')
			{ //parse the power level
				i++;
				l = 0;
				while (buf[i] && buf[i] != ' ' && buf[i] != '|')
				{
					checkLevel[l] = buf[i];
					l++;
					i++;
				}
				checkLevel[l] = 0;
				parsedLevel = atoi(checkLevel);

				//keep sane limits on the powers
				if (parsedLevel < 0)
				{
					parsedLevel = 0;
				}
				if (parsedLevel > FORCE_LEVEL_5)
				{
					parsedLevel = FORCE_LEVEL_5;
				}
			}
			else
			{ //if it's not there, assume level 3 I guess.
				parsedLevel = 3;
			}

			if (checkPower[0])
			{ //Got the name, compare it against the weapon table strings.
				k = 0;

				if (!Q_stricmp(checkPower, "FP_JUMP"))
				{ //haqery
					Q_strncpyz(checkPower, "FP_LEVITATION", sizeof(checkPower));
				}

				while (FPTable[k].id != -1 && FPTable[k].name[0])
				{
					if (!Q_stricmp(checkPower, FPTable[k].name))
					{ //found it, add the weapon into the weapons value
						siegeClass->forcePowerLevels[k] = parsedLevel;
						break;
					}
					k++;
				}
			}
		}

		if (!buf[i])
		{
			break;
		}
		i++;
	}
}
Example #14
0
void BG_SiegeParseTeamFile(const char *filename)
{
	fileHandle_t f;
	int len;
	char teamInfo[2048];
	char parseBuf[1024];
	char lookString[256];
	int i = 1;
	qboolean success = qtrue;

	len = trap->FS_Open(filename, &f, FS_READ);

	if (!f || len >= 2048)
	{
		return;
	}

	trap->FS_Read( teamInfo, len, f );
	trap->FS_Close( f );

	teamInfo[len] = 0;

	if (BG_SiegeGetPairedValue(teamInfo, "name", parseBuf))
	{
		Q_strncpyz(bgSiegeTeams[bgNumSiegeTeams].name, parseBuf, sizeof(bgSiegeTeams[0].name));
	}
	else
	{
		Com_Error(ERR_DROP, "Siege team with no name definition");
	}

	//I don't entirely like doing things this way but it's the easiest way.
	#ifdef _CGAME
		if (BG_SiegeGetPairedValue(teamInfo, "FriendlyShader", parseBuf))
			bgSiegeTeams[bgNumSiegeTeams].friendlyShader = trap->R_RegisterShaderNoMip(parseBuf);
	#else
		bgSiegeTeams[bgNumSiegeTeams].friendlyShader = 0;
	#endif

	bgSiegeTeams[bgNumSiegeTeams].numClasses = 0;

	if (BG_SiegeGetValueGroup(teamInfo, "Classes", teamInfo))
	{
		while (success && i < MAX_SIEGE_CLASSES)
		{ //keep checking for group values named class# up to MAX_SIEGE_CLASSES until we can't find one.
			Q_strncpyz(lookString, va("class%i", i), sizeof(lookString));

			success = BG_SiegeGetPairedValue(teamInfo, lookString, parseBuf);

			if (!success)
			{
				break;
			}

			bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses] = BG_SiegeFindClassByName(parseBuf);

			if (!bgSiegeTeams[bgNumSiegeTeams].classes[bgSiegeTeams[bgNumSiegeTeams].numClasses])
			{
				Com_Printf( "Invalid class specified: '%s'\n", parseBuf);
			}

			bgSiegeTeams[bgNumSiegeTeams].numClasses++;

			i++;
		}
	}

	if (!bgSiegeTeams[bgNumSiegeTeams].numClasses)
	{
		Com_Error(ERR_DROP, "Team defined with no allowable classes\n");
	}

	//If we get here then it was a success, so increment the team number
	bgNumSiegeTeams++;
}
Example #15
0
/**
 * @brief Recursively removes files matching a given pattern from homepath.
 *
 * Useful for removing incomplete downloads and other garbage.
 * Files listed in the com_cleanWhitelist cvar are protected from deletion.
 * Additionally, executable and configuration files are protected unless 'force'
 * argument is passed to this command.
 */
void Cmd_CleanHomepath_f(void)
{
	int      i, j, patternFiles = 0, delFiles = 0, totalFiles = 0;
	char     path[MAX_OSPATH];
	qboolean force = qfalse, pretend = qfalse;

	// *.so and *.dll are denied per default in FS_Remove but throw a Com_Error() -> game aborts
	const char whitelist[] = ".txt .cfg .dat .gm .way .so .dll";

	if (Cmd_Argc() < 3)
	{
		// files in fs_homepath are downloaded again when required - but better print a warning for inexperienced users
		Com_Printf("usage: clean [force | pretend] [modname / all] [pattern 1] [pattern n]\n"
		           "example: clean all *tmp */zzz* etmain/etkey\n"
		           "Warning: This command deletes files in fs_homepath. If you are not sure how to use this command do not play with fire!\n");
		return;
	}

	// if home- and basepath are same better don't start to clean ...
	if (FS_IsSamePath(Cvar_VariableString("fs_homepath"), Cvar_VariableString("fs_basepath")))
	{
		Com_Printf("Invalid configuration to run clean cmd - 'fs_homepath' and 'fs_basepath' are equal.\n");
		return;
	}

	// avoid unreferenced pk3 runtime issues (not on HD but still referenced in game)
#ifndef DEDICATED
	if (cls.state != CA_DISCONNECTED)
	{
		Com_Printf("You are connected to a server - enter '/disconnect' to run '/clean'.\n");
		return;
	}
#else
	if (com_sv_running && com_sv_running->integer)
	{
		Com_Printf("Server is running - enter '/killserver' to run '/clean'.\n");
		return;
	}
#endif // DEDICATED

	Cvar_VariableStringBuffer("fs_homepath", path, sizeof(path));

	// if there are any command options, they must be at the very beginning
	for (i = 1; i < Cmd_Argc(); i++)
	{
		if (!Q_stricmp(Cmd_Argv(i), "force") || !Q_stricmp(Cmd_Argv(i), "f"))
		{
			force = qtrue;
			continue;
		}

		if (!Q_stricmp(Cmd_Argv(i), "pretend") || !Q_stricmp(Cmd_Argv(i), "p"))
		{
			pretend = qtrue;
			continue;
		}

		break;
	}

	// if the first argument is "all" or "*", search the whole homepath
	if (Q_stricmp(Cmd_Argv(i), "all") && Q_stricmp(Cmd_Argv(i), "*"))
	{
		Q_strcat(path, sizeof(path), va("%c%s", PATH_SEP, Cmd_Argv(i)));

		// check if it points to a valid directory
		if (FS_OSStatFile(path) != 1)
		{
			Com_Printf("Cannot commence cleaning, because \"%s\" is not a valid directory under fs_homepath (%s)\n", Cmd_Argv(i), path);
			return;
		}
	}

	for (i++; i < Cmd_Argc(); i++)
	{
		char **pFiles = NULL;

		pFiles = Sys_ListFiles(path, NULL, Cmd_Argv(i), &patternFiles, qtrue);

		Com_Printf("Found %i files matching the pattern \"%s\" under %s\n", patternFiles, Cmd_Argv(i), path);

		for (j = 0; j < patternFiles; j++)
		{
			char     *tokens;
			char     tmp_whitelist[MAX_OSPATH];
			qboolean whitelisted = qfalse;

			totalFiles++;

			Q_strncpyz(tmp_whitelist, (force ? Cvar_VariableString("com_cleanwhitelist") : va("%s %s", Cvar_VariableString("com_cleanwhitelist"), whitelist)), sizeof(tmp_whitelist));

			// Check if this file is in the whitelist
			tokens = strtok(tmp_whitelist, " ,;");

			while (tokens != NULL)
			{
				if (strstr(pFiles[j], tokens))
				{
					Com_Printf("- skipping file[%i]: %s%c%s (whitelisted by pattern: %s)\n", j + 1, path, PATH_SEP, pFiles[j], tokens);
					whitelisted = qtrue;
					break;
				}
				tokens = strtok(NULL, " ,;");
			}

			if (whitelisted)
			{
				continue;
			}

			if (!pretend)
			{
				Com_Printf("- removing file[%i]: %s%c%s\n", j + 1, path, PATH_SEP, pFiles[j]);

				if (force)
				{
					remove(va("%s%c%s", path, PATH_SEP, pFiles[j])); // enable *.so & *.dll lib deletion
				}
				else
				{
					FS_Remove(va("%s%c%s", path, PATH_SEP, pFiles[j]));
				}
				delFiles++;
			}
			else
			{
				Com_Printf("- pretending to remove file[%i]: %s%c%s\n", j + 1, path, PATH_SEP, pFiles[j]);
			}
		}

		Sys_FreeFileList(pFiles);
		patternFiles = 0;
	}
	Com_Printf("Path of fs_homepath cleaned - %i matches - %i files skipped - %i files deleted.\n", totalFiles, totalFiles - delFiles, delFiles);
}
Example #16
0
void RadioBroadcast (edict_t * ent, int partner, char *msg)
{
	int j, i, msg_len, numSnds;
	edict_t *other;
	radio_msg_t *radio_msgs;
	int  msg_soundIndex = 0;
	char msgname_num[8], filteredmsg[48];
	qboolean found = false;
	radio_t *radio;

	if (!IS_ALIVE(ent))
		return;

	if (!teamplay->value)
	{
		if (!DMFLAGS( (DF_MODELTEAMS | DF_SKINTEAMS) ))
			return;			// don't allow in a non-team setup...
	}

	radio = &ent->client->resp.radio;
	if (radio->power_off)
	{
		gi.centerprintf (ent, "Your radio is off!");
		return;
	}

	if (partner && radio->partner == NULL)
	{
		gi.cprintf (ent, PRINT_HIGH, "You don't have a partner.\n");
		return;
	}

	if (radio->gender)
	{
		radio_msgs = female_radio_msgs;
		numSnds = numFemaleSnds;
	}
	else
	{
		radio_msgs = male_radio_msgs;
		numSnds = numMaleSnds;
	}

	i = found = 0;
	msg_len = 0;

	Q_strncpyz(filteredmsg, msg, sizeof(filteredmsg));

	for(i = 0; i < numSnds; i++)
	{
		if (!Q_stricmp(radio_msgs[i].msg, filteredmsg))
		{
			found = true;
			msg_soundIndex = radio_msgs[i].sndIndex;
			msg_len = radio_msgs[i].length;
			break;
		}
	}

	if (!found)
	{
		gi.centerprintf (ent, "'%s' is not a valid radio message", filteredmsg);
		return;
	}

	if (radiolog->value)
	{
		gi.cprintf (NULL, PRINT_CHAT, "[%s RADIO] %s: %s\n",
			partner ? "PARTNER" : "TEAM", ent->client->pers.netname, filteredmsg);
	}

	//TempFile BEGIN
	if (Q_stricmp (filteredmsg, "enemyd") == 0)
	{
		if (ent->client->radio_num_kills > 1 && ent->client->radio_num_kills <= 10)
		{
			// If we are reporting enemy down, add the number of kills.
			sprintf( msgname_num, "%i", ent->client->radio_num_kills );
			ent->client->radio_num_kills = 0;	// prevent from getting into an endless loop

			RadioBroadcast(ent, partner, msgname_num);	// Now THAT'S recursion! =)
		}
		ent->client->radio_num_kills = 0;
	}
//TempFile END
	//AQ2:TNG Slicer
	if (radio_repeat->value)
	{  //SLIC2 Optimization
		if (CheckForRepeat (ent, i) == false)
			return;
	}

	if (radio_max->value)
	{
		if (CheckForFlood (ent) == false)
			return;
	}


	//AQ2:TNG END
	for (j = 1; j <= game.maxclients; j++)
	{
		other = &g_edicts[j];
		if (!other->inuse)
			continue;
		if (!other->client)
			continue;
		if (!OnSameTeam(ent, other))
			continue;
		if (partner && other != radio->partner)
			continue;
		AddRadioMsg( &other->client->resp.radio, msg_soundIndex, msg_len, ent );
	}
}
Example #17
0
/*
============
Cmd_ArgsBuffer

The interpreted versions use this because
they can't have pointers returned to them
============
*/
void Cmd_ArgsBuffer(char *buffer, int bufferLength)
{
	Q_strncpyz(buffer, Cmd_Args(), bufferLength);
}
Example #18
0
/*
=============
NET_StringToAdr

Traps "localhost" for loopback, passes everything else to system
return 0 on address not found, 1 on address found with port, 2 on address found without port.
=============
*/
int NET_StringToAdr( const char* s, netadr_t* a, netadrtype_t family )
{
	char    base[MAX_STRING_CHARS], *search;
	char*   port = NULL;
	
	if ( !strcmp( s, "localhost" ) )
	{
		memset( a, 0, sizeof( *a ) );
		a->type = NA_LOOPBACK;
		// as NA_LOOPBACK doesn't require ports report port was given.
		return 1;
	}
	
	Q_strncpyz( base, s, sizeof( base ) );
	
	if ( *base == '[' || Q_CountChar( base, ':' ) > 1 )
	{
		// This is an ipv6 address, handle it specially.
		search = strchr( base, ']' );
		if ( search )
		{
			*search = '\0';
			search++;
			
			if ( *search == ':' )
				port = search + 1;
		}
		
		if ( *base == '[' )
			search = base + 1;
		else
			search = base;
	}
	else
	{
		// look for a port number
		port = strchr( base, ':' );
		
		if ( port )
		{
			*port = '\0';
			port++;
		}
		
		search = base;
	}
	
	if ( !Sys_StringToAdr( search, a, family ) )
	{
		a->type = NA_BAD;
		return 0;
	}
	
	if ( port )
	{
		a->port = BigShort( ( short ) atoi( port ) );
		return 1;
	}
	else
	{
		a->port = BigShort( PORT_SERVER );
		return 2;
	}
}
Example #19
0
/*
================
SV_SpawnServer

Change the server to a new map, taking all connected
clients along with it.
This is NOT called for map_restart
================
*/
void SV_SpawnServer( char *server, qboolean killBots ) {
	int			i;
	int			checksum;
	qboolean	isBot;
	char		systemInfo[16384];
	const char	*p;

	// shut down the existing game if it is running
	SV_ShutdownGameProgs();

	Com_Printf ("------ Server Initialization ------\n");
	Com_Printf ("Server: %s\n",server);

	// if not running a dedicated server CL_MapLoading will connect the client to the server
	// also print some status stuff
	CL_MapLoading();

	// make sure all the client stuff is unloaded
	CL_ShutdownAll(qfalse);

	// clear the whole hunk because we're (re)loading the server
	Hunk_Clear();

	// clear collision map data
	CM_ClearMap();

	// init client structures and svs.numSnapshotEntities 
	if ( !Cvar_VariableValue("sv_running") ) {
		SV_Startup();
	} else {
		// check for maxclients change
		if ( sv_maxclients->modified ) {
			SV_ChangeMaxClients();
		}
	}

	// clear pak references
	FS_ClearPakReferences(0);

	// allocate the snapshot entities on the hunk
	svs.snapshotEntities = Hunk_Alloc( sizeof(entityState_t)*svs.numSnapshotEntities, h_high );
	svs.nextSnapshotEntities = 0;

	// toggle the server bit so clients can detect that a
	// server has changed
	svs.snapFlagServerBit ^= SNAPFLAG_SERVERCOUNT;

	// set nextmap to the same map, but it may be overriden
	// by the game startup or another console command
	Cvar_Set( "nextmap", "map_restart 0");
//	Cvar_Set( "nextmap", va("map %s", server) );

	for (i=0 ; i<sv_maxclients->integer ; i++) {
		// save when the server started for each client already connected
		if (svs.clients[i].state >= CS_CONNECTED) {
			svs.clients[i].oldServerTime = sv.time;
		}
	}

	// wipe the entire per-level structure
	SV_ClearServer();
	for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) {
		sv.configstrings[i] = CopyString("");
	}

	// make sure we are not paused
	Cvar_Set("cl_paused", "0");

	// get a new checksum feed and restart the file system
	sv.checksumFeed = ( ((int) rand() << 16) ^ rand() ) ^ Com_Milliseconds();
	FS_Restart( sv.checksumFeed );

	CM_LoadMap( va("maps/%s.bsp", server), qfalse, &checksum );

	// set serverinfo visible name
	Cvar_Set( "mapname", server );

	Cvar_Set( "sv_mapChecksum", va("%i",checksum) );

	// serverid should be different each time
	sv.serverId = com_frameTime;
	sv.restartedServerId = sv.serverId; // I suppose the init here is just to be safe
	sv.checksumFeedServerId = sv.serverId;
	Cvar_Set( "sv_serverid", va("%i", sv.serverId ) );

	// clear physics interaction links
	SV_ClearWorld ();
	
	// media configstring setting should be done during
	// the loading stage, so connected clients don't have
	// to load during actual gameplay
	sv.state = SS_LOADING;

	// load and spawn all other entities
	SV_InitGameProgs();

	// don't allow a map_restart if game is modified
	sv_gametype->modified = qfalse;

	// run a few frames to allow everything to settle
	for (i = 0;i < 3; i++)
	{
		VM_Call (gvm, GAME_RUN_FRAME, sv.time);
		SV_BotFrame (sv.time);
		sv.time += 100;
		svs.time += 100;
	}

	// create a baseline for more efficient communications
	SV_CreateBaseline ();

	for (i=0 ; i<sv_maxclients->integer ; i++) {
		// send the new gamestate to all connected clients
		if (svs.clients[i].state >= CS_CONNECTED) {
			char	*denied;

			if ( svs.clients[i].netchan.remoteAddress.type == NA_BOT ) {
				if ( killBots ) {
					SV_DropClient( &svs.clients[i], "" );
					continue;
				}
				isBot = qtrue;
			}
			else {
				isBot = qfalse;
			}

			// connect the client again
			denied = VM_ExplicitArgPtr( gvm, VM_Call( gvm, GAME_CLIENT_CONNECT, i, qfalse, isBot ) );	// firstTime = qfalse
			if ( denied ) {
				// this generally shouldn't happen, because the client
				// was connected before the level change
				SV_DropClient( &svs.clients[i], denied );
			} else {
				if( !isBot ) {
					// when we get the next packet from a connected client,
					// the new gamestate will be sent
					svs.clients[i].state = CS_CONNECTED;
				}
				else {
					client_t		*client;
					sharedEntity_t	*ent;

					client = &svs.clients[i];
					client->state = CS_ACTIVE;
					ent = SV_GentityNum( i );
					ent->s.number = i;
					client->gentity = ent;

					client->deltaMessage = -1;
					client->lastSnapshotTime = 0;	// generate a snapshot immediately

					VM_Call( gvm, GAME_CLIENT_BEGIN, i );
				}
			}
		}
	}	

	// run another frame to allow things to look at all the players
	VM_Call (gvm, GAME_RUN_FRAME, sv.time);
	SV_BotFrame (sv.time);
	sv.time += 100;
	svs.time += 100;

	if ( sv_pure->integer ) {
		// the server sends these to the clients so they will only
		// load pk3s also loaded at the server
		p = FS_LoadedPakChecksums();
		Cvar_Set( "sv_paks", p );
		if (strlen(p) == 0) {
			Com_Printf( "WARNING: sv_pure set but no PK3 files loaded\n" );
		}
		p = FS_LoadedPakNames();
		Cvar_Set( "sv_pakNames", p );

		// if a dedicated pure server we need to touch the cgame because it could be in a
		// seperate pk3 file and the client will need to load the latest cgame.qvm
		if ( com_dedicated->integer ) {
			SV_TouchCGame();
		}
	}
	else {
		Cvar_Set( "sv_paks", "" );
		Cvar_Set( "sv_pakNames", "" );
	}
	// the server sends these to the clients so they can figure
	// out which pk3s should be auto-downloaded
	p = FS_ReferencedPakChecksums();
	Cvar_Set( "sv_referencedPaks", p );
	p = FS_ReferencedPakNames();
	Cvar_Set( "sv_referencedPakNames", p );

	// save systeminfo and serverinfo strings
	Q_strncpyz( systemInfo, Cvar_InfoString_Big( CVAR_SYSTEMINFO ), sizeof( systemInfo ) );
	cvar_modifiedFlags &= ~CVAR_SYSTEMINFO;
	SV_SetConfigstring( CS_SYSTEMINFO, systemInfo );

	SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) );
	cvar_modifiedFlags &= ~CVAR_SERVERINFO;

	// any media configstring setting now should issue a warning
	// and any configstring changes should be reliably transmitted
	// to all clients
	sv.state = SS_GAME;

	// send a heartbeat now so the master will get up to date info
	SV_Heartbeat_f();

	Hunk_SetMark();

#ifndef DEDICATED
	if ( com_dedicated->integer ) {
		// restart renderer in order to show console for dedicated servers
		// launched through the regular binary
		CL_StartHunkUsers( qtrue );
	}
#endif

	Com_Printf ("-----------------------------------\n");
}
Example #20
0
void Rocket_QuakeToRMLBuffer( const char *in, char *out, int length )
{
	Q_strncpyz( out, Rocket_QuakeToRML( in, RP_EMOTICONS ).CString(), length );
}
Example #21
0
/*
============
Cmd_ArgvBuffer

The interpreted versions use this because
they can't have pointers returned to them
============
*/
void	Cmd_ArgvBuffer( int arg, char *buffer, int bufferLength ) {
	Q_strncpyz( buffer, Cmd_Argv( arg ), bufferLength );
}
Example #22
0
/**
 * @brief Loads the given savegame from an xml File.
 * @return true on load success false on failures
 * @param[in] file The Filename to load from (without extension)
 * @param[out] error On failure an errormessage may be set.
 */
qboolean SAV_GameLoad (const char *file, const char **error)
{
	uLongf len;
	char filename[MAX_OSPATH];
	qFILE f;
	byte *cbuf, *buf;
	int i, clen;
	xmlNode_t *topNode, *node;
	saveFileHeader_t header;

	Q_strncpyz(filename, file, sizeof(filename));

	/* open file */
	FS_OpenFile(va("save/%s.%s", filename, SAVEGAME_EXTENSION), &f, FILE_READ);
	if (!f.f) {
		Com_Printf("Couldn't open file '%s'\n", filename);
		*error = "File not found";
		return qfalse;
	}

	clen = FS_FileLength(&f);
	cbuf = (byte *) Mem_PoolAlloc(sizeof(byte) * clen, cp_campaignPool, 0);
	if (FS_Read(cbuf, clen, &f) != clen)
		Com_Printf("Warning: Could not read %i bytes from savefile\n", clen);
	FS_CloseFile(&f);
	Com_Printf("Loading savegame xml (size %d)\n", clen);

	memcpy(&header, cbuf, sizeof(header));
	/* swap all int values if needed */
	header.compressed = LittleLong(header.compressed);
	header.version = LittleLong(header.version);
	header.xmlSize = LittleLong(header.xmlSize);
	/* doing some header verification */
	if (!SAV_VerifyHeader(&header)) {
		/* our header is not valid, we MUST abort loading the game! */
		Com_Printf("The Header of the savegame '%s.%s' is corrupted. Loading aborted\n", filename, SAVEGAME_EXTENSION);
		Mem_Free(cbuf);
		*error = "Corrupted header";
		return qfalse;
	}

	Com_Printf("Loading savegame\n"
			"...version: %i\n"
			"...game version: %s\n"
			"...xml Size: %i, compressed? %c\n",
			header.version, header.gameVersion, header.xmlSize, header.compressed ? 'y' : 'n');
	len = header.xmlSize + 50;
	buf = (byte *) Mem_PoolAlloc(sizeof(byte) * len, cp_campaignPool, 0);

	if (header.compressed) {
		/* uncompress data, skipping comment header */
		const int res = uncompress(buf, &len, cbuf + sizeof(header), clen - sizeof(header));
		Mem_Free(cbuf);

		if (res != Z_OK) {
			Mem_Free(buf);
			*error = _("Error decompressing data");
			Com_Printf("Error decompressing data in '%s'.\n", filename);
			return qfalse;
		}
		topNode = XML_Parse((const char*)buf);
		if (!topNode) {
			Mem_Free(buf);
			Com_Printf("Error: Failure in loading the xml data!\n");
			*error = "Corrupted xml data";
			return qfalse;
		}
	} else {
		/*memcpy(buf, cbuf + sizeof(header), clen - sizeof(header));*/
		topNode = XML_Parse((const char*)(cbuf + sizeof(header)));
		Mem_Free(cbuf);
		if (!topNode) {
			Com_Printf("Error: Failure in loading the xml data!\n");
			*error = "Corrupted xml data";
			return qfalse;
		}
	}
	Mem_Free(buf);

	/* doing a subsystem run */
	GAME_ReloadMode();
	node = XML_GetNode(topNode, SAVE_ROOTNODE);
	if (!node) {
		Com_Printf("Error: Failure in loading the xml data! (savegame node not found)\n");
		mxmlDelete(topNode);
		*error = "Invalid xml data";
		return qfalse;
	}

	Com_Printf("Load '%s' %d subsystems\n", filename, saveSubsystemsAmount);
	for (i = 0; i < saveSubsystemsAmount; i++) {
		Com_Printf("...Running subsystem '%s'\n", saveSubsystems[i].name);
		if (!saveSubsystems[i].load(node)) {
			Com_Printf("...subsystem '%s' returned false - savegame could not be loaded\n",
					saveSubsystems[i].name);
			*error = va("Could not load subsystem %s", saveSubsystems[i].name);
			return qfalse;
		} else
			Com_Printf("...subsystem '%s' - loaded.\n", saveSubsystems[i].name);
	}
	mxmlDelete(node);
	mxmlDelete(topNode);

	if (!SAV_GameActionsAfterLoad()) {
		Com_Printf("Savegame postprocessing returned false - savegame could not be loaded\n");
		*error = "Postprocessing failed";
		return qfalse;
	}

	Com_Printf("File '%s' successfully loaded from %s xml savegame.\n",
			filename, header.compressed ? "compressed" : "");

	UI_InitStack("geoscape", NULL, qtrue, qtrue);
	return qtrue;
}
Example #23
0
// NOTE TTimo define that to track tokenization issues
//#define TKN_DBG
void Cmd_TokenizeString( const char *text_in ) {
	const char	*text;
	char	*textOut;

#ifdef TKN_DBG
  // FIXME TTimo blunt hook to try to find the tokenization of userinfo
  Com_DPrintf("Cmd_TokenizeString: %s\n", text_in);
#endif

	// clear previous args
	cmd_argc = 0;

	if ( !text_in ) {
		return;
	}
	
	Q_strncpyz( cmd_cmd, text_in, sizeof(cmd_cmd) );

	text = text_in;
	textOut = cmd_tokenized;

	while ( 1 ) {
		if ( cmd_argc == MAX_STRING_TOKENS ) {
			return;			// this is usually something malicious
		}

		while ( 1 ) {
			// skip whitespace
			while ( *text && *text <= ' ' ) {
				text++;
			}
			if ( !*text ) {
				return;			// all tokens parsed
			}

			// skip // comments
			if ( text[0] == '/' && text[1] == '/' ) {
				return;			// all tokens parsed
			}

			// skip /* */ comments
			if ( text[0] == '/' && text[1] =='*' ) {
				while ( *text && ( text[0] != '*' || text[1] != '/' ) ) {
					text++;
				}
				if ( !*text ) {
					return;		// all tokens parsed
				}
				text += 2;
			} else {
				break;			// we are ready to parse a token
			}
		}

		// handle quoted strings
    // NOTE TTimo this doesn't handle \" escaping
		if ( *text == '"' ) {
			cmd_argv[cmd_argc] = textOut;
			cmd_argc++;
			text++;
			while ( *text && *text != '"' ) {
				*textOut++ = *text++;
			}
			*textOut++ = 0;
			if ( !*text ) {
				return;		// all tokens parsed
			}
			text++;
			continue;
		}

		// regular token
		cmd_argv[cmd_argc] = textOut;
		cmd_argc++;

		// skip until whitespace, quote, or command
		while ( *text > ' ' ) {
			if ( text[0] == '"' ) {
				break;
			}

			if ( text[0] == '/' && text[1] == '/' ) {
				break;
			}

			// skip /* */ comments
			if ( text[0] == '/' && text[1] =='*' ) {
				break;
			}

			*textOut++ = *text++;
		}

		*textOut++ = 0;

		if ( !*text ) {
			return;		// all tokens parsed
		}
	}
	
}
Example #24
0
/**
 * @brief This is a savegame function which stores the game in xml-Format.
 * @param[in] filename The Filename to save to (without extension)
 * @param[in] comment Description of the savegame
 * @param[out] error On failure an errormessage may be set.
 */
static qboolean SAV_GameSave (const char *filename, const char *comment, char **error)
{
	xmlNode_t *topNode, *node;
	char savegame[MAX_OSPATH];
	int res;
	int requiredBufferLength;
	byte *buf, *fbuf;
	uLongf bufLen;
	saveFileHeader_t header;
	char dummy[2];
	int i;
	dateLong_t date;
	char message[30];
	char timeStampBuffer[32];

	if (!CP_IsRunning()) {
		*error = _("No campaign active.");
		Com_Printf("Error: No campaign active.\n");
		return qfalse;
	}

	if (!B_AtLeastOneExists()) {
		*error = _("Nothing to save yet.");
		Com_Printf("Error: Nothing to save yet.\n");
		return qfalse;
	}

	Com_MakeTimestamp(timeStampBuffer, sizeof(timeStampBuffer));
	Com_sprintf(savegame, sizeof(savegame), "save/%s.%s", filename, SAVEGAME_EXTENSION);
	topNode = mxmlNewXML("1.0");
	node = XML_AddNode(topNode, SAVE_ROOTNODE);
	/* writing  Header */
	XML_AddInt(node, SAVE_SAVEVERSION, SAVE_FILE_VERSION);
	XML_AddString(node, SAVE_COMMENT, comment);
	XML_AddString(node, SAVE_UFOVERSION, UFO_VERSION);
	XML_AddString(node, SAVE_REALDATE, timeStampBuffer);
	CP_DateConvertLong(&ccs.date, &date);
	Com_sprintf(message, sizeof(message), _("%i %s %02i"),
		date.year, Date_GetMonthName(date.month - 1), date.day);
	XML_AddString(node, SAVE_GAMEDATE, message);
	/* working through all subsystems. perhaps we should redesign it, order is not important anymore */
	Com_Printf("Calling subsystems\n");
	for (i = 0; i < saveSubsystemsAmount; i++) {
		if (!saveSubsystems[i].save(node))
			Com_Printf("...subsystem '%s' failed to save the data\n", saveSubsystems[i].name);
		else
			Com_Printf("...subsystem '%s' - saved\n", saveSubsystems[i].name);
	}

	/* calculate the needed buffer size */
	OBJZERO(header);
	header.compressed = LittleLong(save_compressed->integer);
	header.version = LittleLong(SAVE_FILE_VERSION);
	header.subsystems = LittleLong(saveSubsystemsAmount);
	Q_strncpyz(header.name, comment, sizeof(header.name));
	Q_strncpyz(header.gameVersion, UFO_VERSION, sizeof(header.gameVersion));
	CP_DateConvertLong(&ccs.date, &date);
	Com_sprintf(header.gameDate, sizeof(header.gameDate), _("%i %s %02i"),
		date.year, Date_GetMonthName(date.month - 1), date.day);
	Q_strncpyz(header.realDate, timeStampBuffer, sizeof(header.realDate));

	requiredBufferLength = mxmlSaveString(topNode, dummy, 2, MXML_NO_CALLBACK);

	header.xmlSize = LittleLong(requiredBufferLength);
	buf = (byte *) Mem_PoolAlloc(sizeof(byte) * requiredBufferLength + 1, cp_campaignPool, 0);
	if (!buf) {
		mxmlDelete(topNode);
		*error = _("Could not allocate enough memory to save this game");
		Com_Printf("Error: Could not allocate enough memory to save this game\n");
		return qfalse;
	}
	res = mxmlSaveString(topNode, (char*)buf, requiredBufferLength + 1, MXML_NO_CALLBACK);
	mxmlDelete(topNode);
	Com_Printf("XML Written to buffer (%d Bytes)\n", res);

	if (header.compressed)
		bufLen = compressBound(requiredBufferLength);
	else
		bufLen = requiredBufferLength;

	fbuf = (byte *) Mem_PoolAlloc(sizeof(byte) * bufLen + sizeof(header), cp_campaignPool, 0);
	memcpy(fbuf, &header, sizeof(header));

	if (header.compressed) {
		res = compress(fbuf + sizeof(header), &bufLen, buf, requiredBufferLength + 1);
		Mem_Free(buf);

		if (res != Z_OK) {
			Mem_Free(fbuf);
			*error = _("Memory error compressing save-game data - set save_compressed cvar to 0");
			Com_Printf("Memory error compressing save-game data (%s) (Error: %i)!\n", comment, res);
			return qfalse;
		}
	} else {
		memcpy(fbuf + sizeof(header), buf, requiredBufferLength + 1);
		Mem_Free(buf);
	}

	/* last step - write data */
	res = FS_WriteFile(fbuf, bufLen + sizeof(header), savegame);
	Mem_Free(fbuf);

	return qtrue;
}
Example #25
0
int RE_LerpTagET( orientation_t *tag, const refEntity_t *refent, const char *tagNameIn, int startIndex )
{
	mdvTag_t  *start, *end;
	int       i;
	float     frontLerp, backLerp;
	model_t   *model;
	char      tagName[ MAX_QPATH ]; //, *ch;
	int       retval;
	qhandle_t handle;
	int       startFrame, endFrame;
	float     frac;

	handle = refent->hModel;
	startFrame = refent->oldframe;
	endFrame = refent->frame;
	frac = 1.0 - refent->backlerp;

	Q_strncpyz( tagName, tagNameIn, MAX_QPATH );

	/*
	        // if the tagName has a space in it, then it is passing through the starting tag number
	        if (ch = strrchr(tagName, ' ')) {
	                *ch = 0;
	                ch++;
	                startIndex = atoi(ch);
	        }
	*/
	model = R_GetModelByHandle( handle );

	/*
	if(!model->mdv[0]) //if(!model->model.md3[0] && !model->model.mdc[0] && !model->model.mds)
	{
	        AxisClear(tag->axis);
	        VectorClear(tag->origin);
	        return -1;
	}
	*/

	frontLerp = frac;
	backLerp = 1.0 - frac;

	start = end = NULL;

	/*
	        else if(model->type == MOD_MDS)
	        {
	                // use bone lerping
	                retval = R_GetBoneTag(tag, model->model.mds, startIndex, refent, tagNameIn);

	                if(retval >= 0)
	                {
	                        return retval;
	                }

	                // failed
	                return -1;

	        }
	        */
	if ( model->type == MOD_MDM )
	{
		// use bone lerping
		retval = R_MDM_GetBoneTag( tag, model->mdm, startIndex, refent, tagNameIn );

		if ( retval >= 0 )
		{
			return retval;
		}

		// failed
		return -1;
	}
	else if ( model->type == MOD_MD5 )
	{
		vec3_t tmp;

		retval = RE_BoneIndex( handle, tagName );

		if ( retval <= 0 )
		{
			return -1;
		}

		VectorCopy( refent->skeleton.bones[ retval ].origin, tag->origin );
		QuatToAxis( refent->skeleton.bones[ retval ].rotation, tag->axis );
		VectorCopy( tag->axis[ 2 ], tmp );
		VectorCopy( tag->axis[ 1 ], tag->axis[ 2 ] );
		VectorCopy( tag->axis[ 0 ], tag->axis[ 1 ] );
		VectorCopy( tmp, tag->axis[ 0 ] );
		VectorNormalize( tag->axis[ 0 ] );
		VectorNormalize( tag->axis[ 1 ] );
		VectorNormalize( tag->axis[ 2 ] );
		return retval;
	}

	/*
	else
	{
	        // psuedo-compressed MDC tags
	        mdcTag_t       *cstart, *cend;

	        retval = R_GetMDCTag((byte *) model->model.mdc[0], startFrame, tagName, startIndex, &cstart);
	        retval = R_GetMDCTag((byte *) model->model.mdc[0], endFrame, tagName, startIndex, &cend);

	        // uncompress the MDC tags into MD3 style tags
	        if(cstart && cend)
	        {
	                for(i = 0; i < 3; i++)
	                {
	                        ustart.origin[i] = (float)cstart->xyz[i] * MD3_XYZ_SCALE;
	                        uend.origin[i] = (float)cend->xyz[i] * MD3_XYZ_SCALE;
	                        sangles[i] = (float)cstart->angles[i] * MDC_TAG_ANGLE_SCALE;
	                        eangles[i] = (float)cend->angles[i] * MDC_TAG_ANGLE_SCALE;
	                }

	                AnglesToAxis(sangles, ustart.axis);
	                AnglesToAxis(eangles, uend.axis);

	                start = &ustart;
	                end = &uend;
	        }
	        else
	        {
	                start = NULL;
	                end = NULL;
	        }
	}
	*/
	else if ( model->type == MOD_MESH )
	{
		// old MD3 style
		retval = R_GetTag( model->mdv[ 0 ], startFrame, tagName, startIndex, &start );
		retval = R_GetTag( model->mdv[ 0 ], endFrame, tagName, startIndex, &end );
	

		if ( !start || !end )
		{
			AxisClear( tag->axis );
			VectorClear( tag->origin );
			return -1;
		}

		for ( i = 0; i < 3; i++ )
		{
			tag->origin[ i ] = start->origin[ i ] * backLerp + end->origin[ i ] * frontLerp;
			tag->axis[ 0 ][ i ] = start->axis[ 0 ][ i ] * backLerp + end->axis[ 0 ][ i ] * frontLerp;
			tag->axis[ 1 ][ i ] = start->axis[ 1 ][ i ] * backLerp + end->axis[ 1 ][ i ] * frontLerp;
			tag->axis[ 2 ][ i ] = start->axis[ 2 ][ i ] * backLerp + end->axis[ 2 ][ i ] * frontLerp;
		}

		VectorNormalize( tag->axis[ 0 ] );
		VectorNormalize( tag->axis[ 1 ] );
		VectorNormalize( tag->axis[ 2 ] );

		return retval;
	}
	
	return -1;
}
Example #26
0
/*
=================
CG_ServerCommand

The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/
static void CG_ServerCommand( void )
{
	const char *cmd;
	char       text[ MAX_SAY_TEXT ];

	cmd = CG_Argv( 0 );

	if ( !cmd[ 0 ] )
	{
		// server claimed the command
		return;
	}

	if ( !strcmp( cmd, "cp" ) )
	{
		CG_CenterPrint( CG_Argv( 1 ), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cs" ) )
	{
		CG_ConfigStringModified();
		return;
	}

	if ( !strcmp( cmd, "print" ) )
	{
		CG_Printf( "%s", CG_Argv( 1 ) );
		return;
	}

	if ( !strcmp( cmd, "chat" ) )
	{
		if ( !cg_teamChatsOnly.integer )
		{
			trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
			Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
			CG_RemoveChatEscapeChar( text );
			CG_Printf( "%s\n", text );
		}

		return;
	}

	if ( !strcmp( cmd, "tchat" ) )
	{
		if ( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
		{
			trap_S_StartLocalSound( cgs.media.alienTalkSound, CHAN_LOCAL_SOUND );
		}
		else if ( cg.snap->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
		{
			trap_S_StartLocalSound( cgs.media.humanTalkSound, CHAN_LOCAL_SOUND );
		}
		else
		{
			trap_S_StartLocalSound( cgs.media.talkSound, CHAN_LOCAL_SOUND );
		}

		Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
		CG_RemoveChatEscapeChar( text );
		CG_AddToTeamChat( text );
		CG_Printf( "%s\n", text );
		return;
	}

	if ( !strcmp( cmd, "scores" ) )
	{
		CG_ParseScores();
		return;
	}

	if ( !strcmp( cmd, "tinfo" ) )
	{
		CG_ParseTeamInfo();
		return;
	}

	if ( !strcmp( cmd, "map_restart" ) )
	{
		CG_MapRestart();
		return;
	}

	if ( Q_stricmp( cmd, "remapShader" ) == 0 )
	{
		if ( trap_Argc() == 4 )
		{
			trap_R_RemapShader( CG_Argv( 1 ), CG_Argv( 2 ), CG_Argv( 3 ) );
		}
	}

	//the server has triggered a menu
	if ( !strcmp( cmd, "servermenu" ) )
	{
		if ( trap_Argc() == 2 && !cg.demoPlayback )
		{
			CG_Menu( atoi( CG_Argv( 1 ) ) );
		}

		return;
	}

	//the server thinks this client should close all menus
	if ( !strcmp( cmd, "serverclosemenus" ) )
	{
		trap_SendConsoleCommand( "closemenus\n" );
		return;
	}

	//poison cloud effect needs to be reliable
	if ( !strcmp( cmd, "poisoncloud" ) )
	{
		cg.poisonedTime = cg.time;

		if ( CG_IsParticleSystemValid( &cg.poisonCloudPS ) )
		{
			cg.poisonCloudPS = CG_SpawnNewParticleSystem( cgs.media.poisonCloudPS );
			CG_SetAttachmentCent( &cg.poisonCloudPS->attachment, &cg.predictedPlayerEntity );
			CG_AttachToCent( &cg.poisonCloudPS->attachment );
		}

		return;
	}

	if ( !strcmp( cmd, "weaponswitch" ) )
	{
		CG_Printf( "client weaponswitch\n" );

		if ( trap_Argc() == 2 )
		{
			cg.weaponSelect = atoi( CG_Argv( 1 ) );
			cg.weaponSelectTime = cg.time;
		}

		return;
	}

	// server requests a ptrc
	if ( !strcmp( cmd, "ptrcrequest" ) )
	{
		int code = CG_ReadPTRCode();

		trap_SendClientCommand( va( "ptrcverify %d", code ) );
		return;
	}

	// server issues a ptrc
	if ( !strcmp( cmd, "ptrcissue" ) )
	{
		if ( trap_Argc() == 2 )
		{
			int code = atoi( CG_Argv( 1 ) );

			CG_WritePTRCode( code );
		}

		return;
	}

	// reply to ptrcverify
	if ( !strcmp( cmd, "ptrcconfirm" ) )
	{
		trap_SendConsoleCommand( "menu ptrc_popmenu\n" );

		return;
	}

	CG_Printf( "Unknown client game command: %s\n", cmd );
}
Example #27
0
/*
===============
RE_RegisterAnimation
===============
*/
qhandle_t RE_RegisterAnimation( const char *name )
{
	qhandle_t       hAnim;
	skelAnimation_t *anim;
	char            *buffer;
	int             bufferLen;
	qboolean        loaded = qfalse;

	if ( !name || !name[ 0 ] )
	{
		ri.Printf( PRINT_WARNING, "Empty name passed to RE_RegisterAnimation\n" );
		return 0;
	}

	//ri.Printf(PRINT_ALL, "RE_RegisterAnimation(%s)\n", name);

	if ( strlen( name ) >= MAX_QPATH )
	{
		ri.Printf( PRINT_WARNING, "Animation name exceeds MAX_QPATH\n" );
		return 0;
	}

	// search the currently loaded animations
	for ( hAnim = 1; hAnim < tr.numAnimations; hAnim++ )
	{
		anim = tr.animations[ hAnim ];

		if ( !Q_stricmp( anim->name, name ) )
		{
			if ( anim->type == AT_BAD )
			{
				return 0;
			}

			return hAnim;
		}
	}

	// allocate a new model_t
	if ( ( anim = R_AllocAnimation() ) == NULL )
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: R_AllocAnimation() failed for '%s'\n", name );
		return 0;
	}

	// only set the name after the animation has been successfully allocated
	Q_strncpyz( anim->name, name, sizeof( anim->name ) );

	// make sure the render thread is stopped
	R_SyncRenderThread();

	// load and parse the .md5anim file
	bufferLen = ri.FS_ReadFile( name, ( void ** ) &buffer );

	if ( !buffer )
	{
		return 0;
	}

	if ( !Q_stricmpn( ( const char * ) buffer, "MD5Version", 10 ) )
	{
		loaded = R_LoadMD5Anim( anim, buffer, bufferLen, name );
	}
	else
	{
		ri.Printf( PRINT_WARNING, "RE_RegisterAnimation: unknown fileid for '%s'\n", name );
	}

	ri.FS_FreeFile( buffer );

	if ( !loaded )
	{
		ri.Printf( PRINT_WARNING, "couldn't load '%s'\n", name );

		// we still keep the model_t around, so if the model name is asked for
		// again, we won't bother scanning the filesystem
		anim->type = AT_BAD;
	}

	return anim->index;
}
Example #28
0
/*
================
CG_ConfigStringModified

================
*/
static void CG_ConfigStringModified( void )
{
	const char *str;
	int        num;

	num = atoi( CG_Argv( 1 ) );

	// get the gamestate from the client system, which will have the
	// new configstring already integrated
	trap_GetGameState( &cgs.gameState );

	// look up the individual string that was modified
	str = CG_ConfigString( num );

	// do something with it if necessary
	if ( num == CS_MUSIC )
	{
		CG_StartMusic();
	}
	else if ( num == CS_SERVERINFO )
	{
		CG_ParseServerinfo();
	}
	else if ( num == CS_WARMUP )
	{
		CG_ParseWarmup();
	}
	else if ( num == CS_SCORES1 )
	{
		cgs.scores1 = atoi( str );
	}
	else if ( num == CS_SCORES2 )
	{
		cgs.scores2 = atoi( str );
	}
	else if ( num == CS_BUILDPOINTS )
	{
		sscanf( str, "%d %d %d %d %d", &cgs.alienBuildPoints,
		        &cgs.alienBuildPointsTotal,
		        &cgs.humanBuildPoints,
		        &cgs.humanBuildPointsTotal,
		        &cgs.humanBuildPointsPowered );
	}
	else if ( num == CS_STAGES )
	{
		stage_t oldAlienStage = cgs.alienStage;
		stage_t oldHumanStage = cgs.humanStage;

		sscanf( str, "%d %d %d %d %d %d",
		        &cgs.alienStage, &cgs.humanStage,
		        &cgs.alienKills, &cgs.humanKills,
		        &cgs.alienNextStageThreshold, &cgs.humanNextStageThreshold );

		if ( cgs.alienStage != oldAlienStage )
		{
			CG_AnnounceAlienStageTransistion( oldAlienStage, cgs.alienStage );
		}

		if ( cgs.humanStage != oldHumanStage )
		{
			CG_AnnounceHumanStageTransistion( oldHumanStage, cgs.humanStage );
		}
	}
	else if ( num == CS_SPAWNS )
	{
		sscanf( str, "%d %d", &cgs.numAlienSpawns, &cgs.numHumanSpawns );
	}
	else if ( num == CS_LEVEL_START_TIME )
	{
		cgs.levelStartTime = atoi( str );
	}
	else if ( num == CS_VOTE_TIME )
	{
		cgs.voteTime = atoi( str );
		cgs.voteModified = qtrue;

		if ( cgs.voteTime )
		{
			trap_Cvar_Set( "ui_voteActive", "1" );
		}
		else
		{
			trap_Cvar_Set( "ui_voteActive", "0" );
		}
	}
	else if ( num == CS_VOTE_YES )
	{
		cgs.voteYes = atoi( str );
		cgs.voteModified = qtrue;
	}
	else if ( num == CS_VOTE_NO )
	{
		cgs.voteNo = atoi( str );
		cgs.voteModified = qtrue;
	}
	else if ( num == CS_VOTE_STRING )
	{
		Q_strncpyz( cgs.voteString, str, sizeof( cgs.voteString ) );
	}
	else if ( num >= CS_TEAMVOTE_TIME && num <= CS_TEAMVOTE_TIME + 1 )
	{
		int cs_offset = num - CS_TEAMVOTE_TIME;

		cgs.teamVoteTime[ cs_offset ] = atoi( str );
		cgs.teamVoteModified[ cs_offset ] = qtrue;

		if ( cs_offset == 0 )
		{
			if ( cgs.teamVoteTime[ cs_offset ] )
			{
				trap_Cvar_Set( "ui_humanTeamVoteActive", "1" );
			}
			else
			{
				trap_Cvar_Set( "ui_humanTeamVoteActive", "0" );
			}
		}
		else if ( cs_offset == 1 )
		{
			if ( cgs.teamVoteTime[ cs_offset ] )
			{
				trap_Cvar_Set( "ui_alienTeamVoteActive", "1" );
			}
			else
			{
				trap_Cvar_Set( "ui_alienTeamVoteActive", "0" );
			}
		}
	}
	else if ( num >= CS_TEAMVOTE_YES && num <= CS_TEAMVOTE_YES + 1 )
	{
		cgs.teamVoteYes[ num - CS_TEAMVOTE_YES ] = atoi( str );
		cgs.teamVoteModified[ num - CS_TEAMVOTE_YES ] = qtrue;
	}
	else if ( num >= CS_TEAMVOTE_NO && num <= CS_TEAMVOTE_NO + 1 )
	{
		cgs.teamVoteNo[ num - CS_TEAMVOTE_NO ] = atoi( str );
		cgs.teamVoteModified[ num - CS_TEAMVOTE_NO ] = qtrue;
	}
	else if ( num >= CS_TEAMVOTE_STRING && num <= CS_TEAMVOTE_STRING + 1 )
	{
		Q_strncpyz( cgs.teamVoteString[ num - CS_TEAMVOTE_STRING ], str, sizeof( cgs.teamVoteString ) );
	}
	else if ( num == CS_INTERMISSION )
	{
		cg.intermissionStarted = atoi( str );
	}
	else if ( num >= CS_MODELS && num < CS_MODELS + MAX_MODELS )
	{
		cgs.gameModels[ num - CS_MODELS ] = trap_R_RegisterModel( str );
	}
	else if ( num >= CS_SHADERS && num < CS_SHADERS + MAX_GAME_SHADERS )
	{
		cgs.gameShaders[ num - CS_SHADERS ] = trap_R_RegisterShader( str );
	}
	else if ( num >= CS_PARTICLE_SYSTEMS && num < CS_PARTICLE_SYSTEMS + MAX_GAME_PARTICLE_SYSTEMS )
	{
		cgs.gameParticleSystems[ num - CS_PARTICLE_SYSTEMS ] = CG_RegisterParticleSystem( ( char * ) str );
	}
	else if ( num >= CS_SOUNDS && num < CS_SOUNDS + MAX_SOUNDS )
	{
		if ( str[ 0 ] != '*' )
		{
			// player specific sounds don't register here
			cgs.gameSounds[ num - CS_SOUNDS ] = trap_S_RegisterSound( str, qfalse );
		}
	}
	else if ( num >= CS_PLAYERS && num < CS_PLAYERS + MAX_CLIENTS )
	{
		CG_NewClientInfo( num - CS_PLAYERS );
		CG_BuildSpectatorString();
	}
	else if ( num == CS_FLAGSTATUS )
	{
	}
	else if ( num == CS_SHADERSTATE )
	{
		CG_ShaderStateChanged();
	}
}
Example #29
0
/*
==============
RE_BuildSkeleton
==============
*/
int RE_BuildSkeleton( refSkeleton_t *skel, qhandle_t hAnim, int startFrame, int endFrame, float frac, qboolean clearOrigin )
{
	skelAnimation_t *skelAnim;

	skelAnim = R_GetAnimationByHandle( hAnim );

	if ( skelAnim->type == AT_MD5 && skelAnim->md5 )
	{
		int            i;
		md5Animation_t *anim;
		md5Channel_t   *channel;
		md5Frame_t     *newFrame, *oldFrame;
		vec3_t         newOrigin, oldOrigin, lerpedOrigin;
		quat_t         newQuat, oldQuat, lerpedQuat;
		int            componentsApplied;

		anim = skelAnim->md5;

		// Validate the frames so there is no chance of a crash.
		// This will write directly into the entity structure, so
		// when the surfaces are rendered, they don't need to be
		// range checked again.

		/*
		   if((startFrame >= anim->numFrames) || (startFrame < 0) || (endFrame >= anim->numFrames) || (endFrame < 0))
		   {
		   ri.Printf(PRINT_DEVELOPER, "RE_BuildSkeleton: no such frame %d to %d for '%s'\n", startFrame, endFrame, anim->name);
		   //startFrame = 0;
		   //endFrame = 0;
		   }
		 */

		Q_clamp( startFrame, 0, anim->numFrames - 1 );
		Q_clamp( endFrame, 0, anim->numFrames - 1 );

		// compute frame pointers
		oldFrame = &anim->frames[ startFrame ];
		newFrame = &anim->frames[ endFrame ];

		// calculate a bounding box in the current coordinate system
		for ( i = 0; i < 3; i++ )
		{
			skel->bounds[ 0 ][ i ] =
			  oldFrame->bounds[ 0 ][ i ] < newFrame->bounds[ 0 ][ i ] ? oldFrame->bounds[ 0 ][ i ] : newFrame->bounds[ 0 ][ i ];
			skel->bounds[ 1 ][ i ] =
			  oldFrame->bounds[ 1 ][ i ] > newFrame->bounds[ 1 ][ i ] ? oldFrame->bounds[ 1 ][ i ] : newFrame->bounds[ 1 ][ i ];
		}

		for ( i = 0, channel = anim->channels; i < anim->numChannels; i++, channel++ )
		{
			// set baseframe values
			VectorCopy( channel->baseOrigin, newOrigin );
			VectorCopy( channel->baseOrigin, oldOrigin );

			QuatCopy( channel->baseQuat, newQuat );
			QuatCopy( channel->baseQuat, oldQuat );

			componentsApplied = 0;

			// update tranlation bits
			if ( channel->componentsBits & COMPONENT_BIT_TX )
			{
				oldOrigin[ 0 ] = oldFrame->components[ channel->componentsOffset + componentsApplied ];
				newOrigin[ 0 ] = newFrame->components[ channel->componentsOffset + componentsApplied ];
				componentsApplied++;
			}

			if ( channel->componentsBits & COMPONENT_BIT_TY )
			{
				oldOrigin[ 1 ] = oldFrame->components[ channel->componentsOffset + componentsApplied ];
				newOrigin[ 1 ] = newFrame->components[ channel->componentsOffset + componentsApplied ];
				componentsApplied++;
			}

			if ( channel->componentsBits & COMPONENT_BIT_TZ )
			{
				oldOrigin[ 2 ] = oldFrame->components[ channel->componentsOffset + componentsApplied ];
				newOrigin[ 2 ] = newFrame->components[ channel->componentsOffset + componentsApplied ];
				componentsApplied++;
			}

			// update quaternion rotation bits
			if ( channel->componentsBits & COMPONENT_BIT_QX )
			{
				( ( vec_t * ) oldQuat ) [ 0 ] = oldFrame->components[ channel->componentsOffset + componentsApplied ];
				( ( vec_t * ) newQuat ) [ 0 ] = newFrame->components[ channel->componentsOffset + componentsApplied ];
				componentsApplied++;
			}

			if ( channel->componentsBits & COMPONENT_BIT_QY )
			{
				( ( vec_t * ) oldQuat ) [ 1 ] = oldFrame->components[ channel->componentsOffset + componentsApplied ];
				( ( vec_t * ) newQuat ) [ 1 ] = newFrame->components[ channel->componentsOffset + componentsApplied ];
				componentsApplied++;
			}

			if ( channel->componentsBits & COMPONENT_BIT_QZ )
			{
				( ( vec_t * ) oldQuat ) [ 2 ] = oldFrame->components[ channel->componentsOffset + componentsApplied ];
				( ( vec_t * ) newQuat ) [ 2 ] = newFrame->components[ channel->componentsOffset + componentsApplied ];
			}

			QuatCalcW( oldQuat );
			QuatNormalize( oldQuat );

			QuatCalcW( newQuat );
			QuatNormalize( newQuat );

#if 1
			VectorLerp( oldOrigin, newOrigin, frac, lerpedOrigin );
			QuatSlerp( oldQuat, newQuat, frac, lerpedQuat );
#else
			VectorCopy( newOrigin, lerpedOrigin );
			QuatCopy( newQuat, lerpedQuat );
#endif

			// copy lerped information to the bone + extra data
			skel->bones[ i ].parentIndex = channel->parentIndex;

			if ( channel->parentIndex < 0 && clearOrigin )
			{
				VectorClear( skel->bones[ i ].origin );
				QuatClear( skel->bones[ i ].rotation );

				// move bounding box back
				VectorSubtract( skel->bounds[ 0 ], lerpedOrigin, skel->bounds[ 0 ] );
				VectorSubtract( skel->bounds[ 1 ], lerpedOrigin, skel->bounds[ 1 ] );
			}
			else
			{
				VectorCopy( lerpedOrigin, skel->bones[ i ].origin );
			}

			QuatCopy( lerpedQuat, skel->bones[ i ].rotation );

#if defined( REFBONE_NAMES )
			Q_strncpyz( skel->bones[ i ].name, channel->name, sizeof( skel->bones[ i ].name ) );
#endif
		}

		skel->numBones = anim->numChannels;
		skel->type = SK_RELATIVE;
		return qtrue;
	}

	//ri.Printf(PRINT_WARNING, "RE_BuildSkeleton: bad animation '%s' with handle %i\n", anim->name, hAnim);

	// FIXME: clear existing bones and bounds?
	return qfalse;
}
Example #30
0
/*
** GLW_LoadOpenGL
**
** GLimp_win.c internal function that attempts to load and use
** a specific OpenGL DLL.
*/
static qboolean GLW_LoadOpenGL( const char *drivername ) {
	char buffer[1024];
	qboolean cdsFullscreen;

	Q_strncpyz( buffer, drivername, sizeof( buffer ) );
	Q_strlwr( buffer );

	//
	// determine if we're on a standalone driver
	//
	if ( strstr( buffer, "opengl32" ) != 0 || r_maskMinidriver->integer ) {
		glConfig.driverType = GLDRV_ICD;
	} else
	{
		glConfig.driverType = GLDRV_STANDALONE;

		ri.Printf( PRINT_ALL, "...assuming '%s' is a standalone driver\n", drivername );

		if ( strstr( buffer, _3DFX_DRIVER_NAME ) ) {
			glConfig.driverType = GLDRV_VOODOO;
		}
	}

	// disable the 3Dfx splash screen
	_putenv( "FX_GLIDE_NO_SPLASH=0" );

	//
	// load the driver and bind our function pointers to it
	//
	if ( QGL_Init( buffer ) ) {
#if 0
// FIXME: newer 3Dfx drivers means this can go away
		if ( !Q_stricmp( buffer, _3DFX_DRIVER_NAME ) ) {
			cdsFullscreen = qfalse;
		} else
#endif
		{
			cdsFullscreen = r_fullscreen->integer;
		}

		// create the window and set up the context
		if ( !GLW_StartDriverAndSetMode( drivername, r_mode->integer, r_colorbits->integer, cdsFullscreen ) ) {
			// if we're on a 24/32-bit desktop and we're going fullscreen on an ICD,
			// try it again but with a 16-bit desktop
			if ( glConfig.driverType == GLDRV_ICD ) {
				if ( r_colorbits->integer != 16 ||
					 cdsFullscreen != qtrue ||
					 r_mode->integer != 3 ) {
					if ( !GLW_StartDriverAndSetMode( drivername, 3, 16, qtrue ) ) {
						goto fail;
					}
				}
			} else
			{
				goto fail;
			}
		}

		if ( glConfig.driverType == GLDRV_VOODOO ) {
			glConfig.isFullscreen = qtrue;
		}

		return qtrue;
	}
fail:

	QGL_Shutdown();

	return qfalse;
}