Example #1
0
/*
================
SV_EntityScript

get entity script for current map
================
*/
char *SV_EntityScript( void )
{
	string	entfilename;
	char	*ents;
	size_t	ft1, ft2;

	if( !sv.worldmodel )
		return NULL;

	// check for entfile too
	Q_strncpy( entfilename, sv.worldmodel->name, sizeof( entfilename ));
	FS_StripExtension( entfilename );
	FS_DefaultExtension( entfilename, ".ent" );

	// make sure what entity patch is never than bsp
	ft1 = FS_FileTime( sv.worldmodel->name, false );
	ft2 = FS_FileTime( entfilename, true );

	if( ft2 != -1 )
	{
		if( ft1 > ft2 )
		{
			MsgDev( D_INFO, "^1Entity patch is older than BSP. Ignored.\n", entfilename );			
		}
		else if(( ents = FS_LoadFile( entfilename, NULL, true )) != NULL )
		{
			MsgDev( D_INFO, "^2Read entity patch:^7 %s\n", entfilename );
			return ents;
		}
	}

	// use internal entities
	return sv.worldmodel->entities;
}
Example #2
0
qboolean HPAK_ResourceForIndex( const char *filename, int index, resource_t *pRes )
{
	file_t		*f;
	hpak_header_t	hdr;
	hpak_container_t	hpakcontainer;
	string		pakname;

	if( !filename || !filename[0] )
		return false;

	Q_strncpy( pakname, filename, sizeof( pakname ));
	FS_StripExtension( pakname );
	FS_DefaultExtension( pakname, ".hpk" );

	f = FS_Open( pakname, "rb", false );
	FS_Read( f, &hdr, sizeof( hdr ));

	if( hdr.ident != IDCUSTOMHEADER )
	{
		MsgDev( D_ERROR, "HPAK_ResourceForIndex: %s it's not a HPK file.\n", pakname );
		FS_Close( f );
		return false;
	}

	if( hdr.version != IDCUSTOM_VERSION )
	{
		MsgDev( D_ERROR, "HPAK_ResourceForIndex: %s has invalid version (%i should be %i).\n", pakname, hdr.version, IDCUSTOM_VERSION );
		FS_Close( f );
		return false;
	}

	FS_Seek( f, hdr.seek, SEEK_SET );
	FS_Read( f, &hpakcontainer.count, sizeof( hpakcontainer.count ));

	if( hpakcontainer.count < 1 || hpakcontainer.count > MAX_FILES_IN_WAD )
	{
		MsgDev( D_ERROR, "HPAK_ResourceForIndex: %s has too many lumps %u.\n", pakname, hpakcontainer.count );
		FS_Close( f );
		return false;
	}

	if( index < 1 || index > hpakcontainer.count )
	{
		MsgDev( D_ERROR, "HPAK_ResourceForIndex: %s, lump with index %i doesn't exist.\n", pakname, index );
		FS_Close( f );
		return false;
	}

	hpakcontainer.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpakcontainer.count );

	// we could just seek the right data...
	FS_Read( f, hpakcontainer.dirs, sizeof( hpak_dir_t ) * hpakcontainer.count );
	*pRes = hpakcontainer.dirs[index-1].DirectoryResource;
	Mem_Free( hpakcontainer.dirs );
	FS_Close( f );

	return true;
}
Example #3
0
/*
=====================================
Cmd_GetSoundList

Prints or complete sound filename
=====================================
*/
qboolean Cmd_GetSoundList( const char *s, char *completedname, int length )
{
	search_t		*t;
	string		matchbuf;
	int		i, numsounds;
	const char	*snddir = "sound/"; // constant

	t = FS_Search( va( "%s%s*.*", snddir, s ), true, false );
	if( !t ) return false;

	Q_strncpy( matchbuf, t->filenames[0] + Q_strlen( snddir ), MAX_STRING ); 
	FS_StripExtension( matchbuf ); 
	if( completedname && length ) Q_strncpy( completedname, matchbuf, length );
	if( t->numfilenames == 1 ) return true;

	for(i = 0, numsounds = 0; i < t->numfilenames; i++)
	{
		const char *ext = FS_FileExtension( t->filenames[i] ); 

		if( !Q_stricmp( ext, "wav" ) || !Q_stricmp( ext, "mp3" ));
		else continue;

		Q_strncpy( matchbuf, t->filenames[i] + Q_strlen(snddir), MAX_STRING ); 
		FS_StripExtension( matchbuf );
		Msg( "%16s\n", matchbuf );
		numsounds++;
	}

	Msg( "\n^3 %i sounds found.\n", numsounds );
	Mem_Free( t );

	// cut shortestMatch to the amount common with s
	if( completedname && length )
	{
		for( i = 0; matchbuf[i]; i++ )
		{
			if( Q_tolower( completedname[i] ) != Q_tolower( matchbuf[i] ))
				completedname[i] = 0;
		}
	}

	return true;
}
Example #4
0
void HPAK_CheckIntegrity( const char *filename )
{
	string	pakname;

	if( !filename || !filename[0] ) return;
	Q_strncpy( pakname, filename, sizeof( pakname ));
	FS_StripExtension( pakname );
	FS_DefaultExtension( pakname, ".hpk" );

	HPAK_ValidatePak( pakname );
}
Example #5
0
/*
====================
CL_UpdateTexture

Update texture top and bottom colors
====================
*/
void CL_UpdateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor )
{
	gltexture_t	*glt;
	rgbdata_t		*pic;
	texture_t		*tx = NULL;
	char		texname[128], name[128], mdlname[128];
	int		i, index;
	size_t size;
	byte		paletteBackup[768];
	byte		*raw, *pal;

	// save of the real texture index
	glt = R_GetTexture( ptexture->index );

	// build name of original texture
	Q_strncpy( mdlname, RI.currentmodel->name, sizeof( mdlname ));
	FS_FileBase( ptexture->name, name );
	FS_StripExtension( mdlname );

	Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name );
	index = GL_FindTexture( texname );
	if( !index ) return; // couldn't find texture

	// search for pixels
	for( i = 0; i < RI.currentmodel->numtextures; i++ )
	{
		tx = RI.currentmodel->textures[i];
		if( tx->gl_texturenum == index )
			break; // found
	}

	ASSERT( tx != NULL );

	// backup original palette
	pal = (byte *)(tx + 1) + (tx->width * tx->height);
	Q_memcpy( paletteBackup, pal, 768 );

	raw = CL_CreateRawTextureFromPixels( tx, &size, topcolor, bottomcolor );
	pic = FS_LoadImage( glt->name, raw, size );
	if( !pic )
	{
		MsgDev( D_ERROR, "Couldn't update texture %s\n", glt->name );
		return;
	}

	index = GL_LoadTextureInternal( glt->name, pic, 0, true );
	FS_FreeImage( pic );

	// restore original palette
	Q_memcpy( pal, paletteBackup, 768 );

	ASSERT( index == ptexture->index );
}
Example #6
0
void HPAK_CheckSize( const char *filename )
{
	string	pakname;
	int	maxsize;

	maxsize = hpk_maxsize->integer;
	if( maxsize <= 0 ) return;

	if( !filename || !filename[0] ) return;
	Q_strncpy( pakname, filename, sizeof( pakname ));
	FS_StripExtension( pakname );
	FS_DefaultExtension( pakname, ".hpk" );

	if( FS_FileSize( pakname, false ) > ( maxsize * 1000000 ))
		MsgDev( D_ERROR, "HPAK_CheckSize: %s is too large.\n", filename );
}
Example #7
0
/*
================
FS_OpenStream

open and reading basic info from sound stream
================
*/
stream_t *FS_OpenStream( const char *filename )
{
          const char	*ext = FS_FileExtension( filename );
	string		path, loadname;
	qboolean		anyformat = true;
	const streamfmt_t	*format;
	stream_t		*stream;

	Sound_Reset(); // clear old streaminfo
	Q_strncpy( loadname, filename, sizeof( loadname ));

	if( Q_stricmp( ext, "" ))
	{
		// we needs to compare file extension with list of supported formats
		// and be sure what is real extension, not a filename with dot
		for( format = sound.streamformat; format && format->formatstring; format++ )
		{
			if( !Q_stricmp( format->ext, ext ))
			{
				FS_StripExtension( loadname );
				anyformat = false;
				break;
			}
		}
	}

	// now try all the formats in the selected list
	for( format = sound.streamformat; format && format->formatstring; format++)
	{
		if( anyformat || !Q_stricmp( ext, format->ext ))
		{
			Q_sprintf( path, format->formatstring, loadname, "", format->ext );
			if(( stream = format->openfunc( path )) != NULL )
			{
				stream->format = format;
				return stream; // done
			}
		}
	}

	if( !sound.streamformat || sound.streamformat->ext == NULL )
		MsgDev( D_NOTE, "FS_OpenStream: soundlib offline\n" );
	else MsgDev( D_NOTE, "FS_OpenStream: couldn't open \"%s\"\n", loadname );

	return NULL;
}
Example #8
0
void R_NewMap( void )
{
	texture_t	*tx;
	int	i;

	R_ClearDecals(); // clear all level decals

	// upload detailtextures
	if( r_detailtextures->integer )
	{
		string	mapname, filepath;

		Q_strncpy( mapname, cl.worldmodel->name, sizeof( mapname ));
		FS_StripExtension( mapname );
		Q_sprintf( filepath, "%s_detail.txt", mapname );

		R_ParseDetailTextures( filepath );
	}

	// clear out efrags in case the level hasn't been reloaded
	for( i = 0; i < cl.worldmodel->numleafs; i++ )
		cl.worldmodel->leafs[i+1].efrags = NULL;

	tr.skytexturenum = -1;
	r_viewleaf = r_oldviewleaf = NULL;

	// clearing texture chains
	for( i = 0; i < cl.worldmodel->numtextures; i++ )
	{
		if( !cl.worldmodel->textures[i] )
			continue;

		tx = cl.worldmodel->textures[i];

		if( !Q_strncmp( tx->name, "sky", 3 ) && tx->width == 256 && tx->height == 128)
			tr.skytexturenum = i;

 		tx->texturechain = NULL;
	}

	R_SetupSky( cl.refdef.movevars->skyName );

	GL_BuildLightmaps ();
	R_GenerateVBO();
}
Example #9
0
/*
====================
SV_Record_f

record <demoname>
====================
*/
void SV_MVD_Record_f (void)
{
	int		c;
	char	name[MAX_OSPATH+MAX_MVD_NAME];
	char	newname[MAX_MVD_NAME];
	dir_t	dir;

	c = Cmd_Argc();
	if (c != 2)
	{
		Com_Printf ("mvdrecord <demoname>\n");
		return;
	}

	if (sv.state != ss_game){
		Com_Printf ("Not active yet.\n");
		return;
	}

	dir = Sys_listdir(va("%s/%s", fs_gamedir, sv_demoDir.string), ".*", false);
	if (sv_demoMaxDirSize.value && dir.size > sv_demoMaxDirSize.value*1024)
	{
		Com_Printf("insufficient directory space, increase sv_demoMaxDirSize\n");
		return;
	}

	Q_strncpyz(newname, va("%s%s", sv_demoPrefix.string, SV_CleanName(Cmd_Argv(1))), sizeof(newname) - strlen(sv_demoSuffix.string) - 5);
	Q_strncatz(newname, sv_demoSuffix.string, MAX_MVD_NAME);

	_snprintf (name, MAX_OSPATH+MAX_MVD_NAME, "%s/%s/%s", fs_gamedir, sv_demoDir.string, newname);

	FS_StripExtension(name, name, sizeof(name));
	FS_DefaultExtension(name, ".mvd", sizeof(name));
//	FS_CreatePath(name);

	//
	// open the demo file and start recording
	//
	SV_MVD_Record (SV_InitRecordFile(name));
}
Example #10
0
/*
=================
WriteSurfaceExtraFile

writes out a surface info file (<map>.srf)
=================
*/
void WriteSurfaceExtraFile( const char *path )
{
	char		srfPath[MAX_SYSPATH];
	file_t		*sf;
	surfaceExtra_t	*se;
	int		i;

	if( path == NULL || path[0] == '\0' )
		return;
	
	MsgDev( D_NOTE, "--- WriteSurfaceExtraFile ---\n" );
	
	com.snprintf( srfPath, sizeof( srfPath ), "maps/%s", path );
	FS_StripExtension( srfPath );
	FS_DefaultExtension( srfPath, ".srf" );
	Msg( "Writing %s\n", srfPath );
	sf = FS_Open( srfPath, "w" );
	if( !sf ) Sys_Error( "Error opening %s for writing", srfPath );
	
	for( i = -1; i < numSurfaceExtras; i++ )
	{
		se = GetSurfaceExtra( i );
		
		if( i < 0 ) FS_Printf( sf, "default" );
		else FS_Printf( sf, "%d", i );
		
		if( se->mds == NULL ) FS_Printf( sf, "\n" );
		else
		{
			FS_Printf( sf, " // %s V: %d I: %d %s\n", surfaceTypes[se->mds->type], se->mds->numVerts, se->mds->numIndexes,
			(se->mds->planar ? "planar" : ""));
		}
		
		FS_Printf( sf, "{\n" );
		
		if( se->si != NULL ) FS_Printf( sf, "\tshader %s\n", se->si->shader );
			
		if( se->parentSurfaceNum != seDefault.parentSurfaceNum )
			FS_Printf( sf, "\tparent %d\n", se->parentSurfaceNum );
			
		if( se->entityNum != seDefault.entityNum )
			FS_Printf( sf, "\tentity %d\n", se->entityNum );
			
		if( se->castShadows != seDefault.castShadows || se == &seDefault )
			FS_Printf( sf, "\tcastShadows %d\n", se->castShadows );
			
		if( se->recvShadows != seDefault.recvShadows || se == &seDefault )
			FS_Printf( sf, "\treceiveShadows %d\n", se->recvShadows );
			
		if( se->sampleSize != seDefault.sampleSize || se == &seDefault )
			FS_Printf( sf, "\tsampleSize %d\n", se->sampleSize );
			
		if( se->longestCurve != seDefault.longestCurve || se == &seDefault )
			FS_Printf( sf, "\tlongestCurve %f\n", se->longestCurve );
			
		if( VectorCompare( se->lightmapAxis, seDefault.lightmapAxis ) == false )
			FS_Printf( sf, "\tlightmapAxis ( %f %f %f )\n", se->lightmapAxis[0], se->lightmapAxis[1], se->lightmapAxis[2] );
		FS_Printf( sf, "}\n\n" );
	}
	FS_Close( sf );
}
Example #11
0
qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
{
	byte	buf[MAX_SYSPATH];
	char	*buffer;
	string	result;
	int	i, size;
	search_t	*t;
	file_t	*f;

	if( FS_FileSize( "maps.lst", onlyingamedir ) > 0 && !fRefresh )
	{
		MsgDev( D_NOTE, "maps.lst is exist: %s\n", onlyingamedir ? "basedir" : "gamedir" );
		return true; // exist 
	}

	t = FS_Search( "maps/*.bsp", false, onlyingamedir );

	if( !t )
	{
		if( onlyingamedir )
		{
			// mod doesn't contain any maps (probably this is a bot)
			return Cmd_CheckMapsList_R( fRefresh, false );
		}

		return false;
	}

	buffer = Mem_Alloc( host.mempool, t->numfilenames * 2 * sizeof( result ));

	for( i = 0; i < t->numfilenames; i++ )
	{
		char		*ents = NULL, *pfile;
		int		ver = -1, lumpofs = 0, lumplen = 0;
		string		mapname, message, entfilename;
		const char	*ext = FS_FileExtension( t->filenames[i] ); 

		if( Q_stricmp( ext, "bsp" )) continue;
		f = FS_Open( t->filenames[i], "rb", onlyingamedir );
		FS_FileBase( t->filenames[i], mapname );

		if( f )
		{
			int	num_spawnpoints = 0;
			dheader_t	*header;

			Q_memset( buf, 0, MAX_SYSPATH );
			FS_Read( f, buf, MAX_SYSPATH );
			ver = *(uint *)buf;
                              
			switch( ver )
			{
			case Q1BSP_VERSION:
			case HLBSP_VERSION:
			case XTBSP_VERSION:
				header = (dheader_t *)buf;
				if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 )
				{
					lumpofs = header->lumps[LUMP_PLANES].fileofs;
					lumplen = header->lumps[LUMP_PLANES].filelen;
				}
				else
				{
					lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
					lumplen = header->lumps[LUMP_ENTITIES].filelen;
				}
				break;
			}

			Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
			FS_StripExtension( entfilename );
			FS_DefaultExtension( entfilename, ".ent" );
			ents = FS_LoadFile( entfilename, NULL, true );

			if( !ents && lumplen >= 10 )
			{
				FS_Seek( f, lumpofs, SEEK_SET );
				ents = (char *)Mem_Alloc( host.mempool, lumplen + 1 );
				FS_Read( f, ents, lumplen );
			}

			if( ents )
			{
				// if there are entities to parse, a missing message key just
				// means there is no title, so clear the message string now
				char	token[2048];
				qboolean	worldspawn = true;

				Q_strncpy( message, "No Title", MAX_STRING );
				pfile = ents;

				while(( pfile = COM_ParseFile( pfile, token )) != NULL )
				{
					if( token[0] == '}' && worldspawn )
						worldspawn = false;
					else if( !Q_strcmp( token, "message" ) && worldspawn )
					{
						// get the message contents
						pfile = COM_ParseFile( pfile, message );
					}
					else if( !Q_strcmp( token, "classname" ))
					{
						pfile = COM_ParseFile( pfile, token );
						if( !Q_strcmp( token, GI->mp_entity ))
							num_spawnpoints++;
					}
					if( num_spawnpoints ) break; // valid map
				}
				Mem_Free( ents );
			}

			if( f ) FS_Close( f );

			if( num_spawnpoints )
			{
				// format: mapname "maptitle"\n
				Q_sprintf( result, "%s \"%s\"\n", mapname, message );
				Q_strcat( buffer, result ); // add new string
			}
		}
	}

	if( t ) Mem_Free( t ); // free search result
	size = Q_strlen( buffer );

	if( !size )
	{
          	if( buffer ) Mem_Free( buffer );

		if( onlyingamedir )
			return Cmd_CheckMapsList_R( fRefresh, false );
		return false;
	}

	// write generated maps.lst
	if( FS_WriteFile( "maps.lst", buffer, Q_strlen( buffer )))
	{
          	if( buffer ) Mem_Free( buffer );
		return true;
	}
	return false;
}
Example #12
0
/*
=====================================
Cmd_GetMapList

Prints or complete map filename
=====================================
*/
qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
{
	search_t		*t;
	file_t		*f;
	string		message;
	string		matchbuf;
	byte		buf[MAX_SYSPATH]; // 1 kb
	int		i, nummaps;

	t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps->integer );
	if( !t ) return false;

	FS_FileBase( t->filenames[0], matchbuf ); 
	Q_strncpy( completedname, matchbuf, length );
	if( t->numfilenames == 1 ) return true;

	for( i = 0, nummaps = 0; i < t->numfilenames; i++ )
	{
		char		entfilename[CS_SIZE];
		int		ver = -1, mapver = -1, lumpofs = 0, lumplen = 0;
		const char	*ext = FS_FileExtension( t->filenames[i] ); 
		char		*ents = NULL, *pfile;
		qboolean		paranoia = false;
		qboolean		gearbox = false;
			
		if( Q_stricmp( ext, "bsp" )) continue;
		Q_strncpy( message, "^1error^7", sizeof( message ));
		f = FS_Open( t->filenames[i], "rb", con_gamemaps->integer );
	
		if( f )
		{
			dheader_t	*header;
			dextrahdr_t	*hdrext;

			Q_memset( buf, 0, sizeof( buf ));
			FS_Read( f, buf, sizeof( buf ));
			header = (dheader_t *)buf;
			ver = header->version;
                              
			switch( ver )
			{
			case Q1BSP_VERSION:
			case HLBSP_VERSION:
			case XTBSP_VERSION:
				if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 && !(header->lumps[LUMP_ENTITIES].filelen % sizeof(dplane_t)))
				{
					lumpofs = header->lumps[LUMP_PLANES].fileofs;
					lumplen = header->lumps[LUMP_PLANES].filelen;
					gearbox = true;
				}
				else
				{
					lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
					lumplen = header->lumps[LUMP_ENTITIES].filelen;
					gearbox = false;
				}
				break;
			}

			if( ver == XTBSP_VERSION )
				hdrext = (dextrahdr_t *)((byte *)buf + sizeof( dheader31_t ));
			else hdrext = (dextrahdr_t *)((byte *)buf + sizeof( dheader_t ));

			if( hdrext->id == IDEXTRAHEADER && hdrext->version == EXTRA_VERSION )
				paranoia = true;

			Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
			FS_StripExtension( entfilename );
			FS_DefaultExtension( entfilename, ".ent" );
			ents = FS_LoadFile( entfilename, NULL, true );

			if( !ents && lumplen >= 10 )
			{
				FS_Seek( f, lumpofs, SEEK_SET );
				ents = (char *)Mem_Alloc( host.mempool, lumplen + 1 );
				FS_Read( f, ents, lumplen );
			}

			if( ents )
			{
				// if there are entities to parse, a missing message key just
				// means there is no title, so clear the message string now
				char	token[2048];

				message[0] = 0;
				pfile = ents;

				while(( pfile = COM_ParseFile( pfile, token )) != NULL )
				{
					if( !Q_strcmp( token, "{" )) continue;
					else if(!Q_strcmp( token, "}" )) break;
					else if(!Q_strcmp( token, "message" ))
					{
						// get the message contents
						pfile = COM_ParseFile( pfile, message );
					}
					else if(!Q_strcmp( token, "mapversion" ))
					{
						// get the message contents
						pfile = COM_ParseFile( pfile, token );
						mapver = Q_atoi( token );
					}
				}
				Mem_Free( ents );
			}
		}

		if( f ) FS_Close(f);
		FS_FileBase( t->filenames[i], matchbuf );

		switch( ver )
		{
		case Q1BSP_VERSION:
			if( mapver == 220 ) Q_strncpy( buf, "Half-Life Alpha", sizeof( buf ));
			else Q_strncpy( buf, "Quake", sizeof( buf ));
			break;
		case HLBSP_VERSION:
			if( gearbox ) Q_strncpy( buf, "Blue-Shift", sizeof( buf ));
			else if( paranoia ) Q_strncpy( buf, "Paranoia 2", sizeof( buf ));
			else Q_strncpy( buf, "Half-Life", sizeof( buf ));
			break;
		case XTBSP_VERSION:
			if( paranoia ) Q_strncpy( buf, "Paranoia 2", sizeof( buf ));
			else Q_strncpy( buf, "Xash3D", sizeof( buf ));
			break;
		default:
			Q_strncpy( buf, "??", sizeof( buf ));
			break;
		}

		Msg( "%16s (%s) ^3%s^7\n", matchbuf, buf, message );
		nummaps++;
	}

	Msg( "\n^3 %i maps found.\n", nummaps );
	Mem_Free( t );

	// cut shortestMatch to the amount common with s
	for( i = 0; matchbuf[i]; i++ )
	{
		if( Q_tolower( completedname[i] ) != Q_tolower( matchbuf[i] ))
			completedname[i] = 0;
	}
	return true;
}
Example #13
0
void HPAK_CreatePak( const char *filename, resource_t *DirEnt, byte *data, file_t *f )
{
	int		filelocation;
	string		pakname;
	char		md5[16];
	char		*temp;
	MD5Context_t	MD5_Hash;
	file_t		*fout;

	if( !filename || !filename[0] )
	{
		MsgDev( D_ERROR, "HPAK_CreatePak: NULL name\n" );
		return;
	}

	if(( f != NULL && data != NULL ) || ( f == NULL && data == NULL ))
	{
		MsgDev( D_ERROR, "HPAK_CreatePak: too many sources, please leave one.\n" );
		return;
	}

	Q_strncpy( pakname, filename, sizeof( pakname ));
	FS_StripExtension( pakname );
	FS_DefaultExtension( pakname, ".hpk" );

	MsgDev( D_INFO, "creating HPAK %s.\n", pakname );
	fout = FS_Open( pakname, "wb", false );
	if( !fout )
	{
		MsgDev( D_ERROR, "HPAK_CreatePak: can't write %s.\n", pakname );
		return;
	}

	// let's hash it.
	Q_memset( &MD5_Hash, 0, sizeof( MD5Context_t ));
	MD5Init( &MD5_Hash );

	if( data == NULL )
	{
		// there are better ways
		filelocation = FS_Tell( f );
		temp = Z_Malloc( DirEnt->nDownloadSize );
		FS_Read( f, temp, DirEnt->nDownloadSize );
		FS_Seek( f, filelocation, SEEK_SET );

		MD5Update( &MD5_Hash, temp, DirEnt->nDownloadSize );
		Mem_Free( temp );
	}
	else
	{
		MD5Update( &MD5_Hash, data, DirEnt->nDownloadSize );
	}

	MD5Final( md5, &MD5_Hash );

	if( Q_memcmp( md5, DirEnt->rgucMD5_hash, 16 ))
	{
		MsgDev( D_ERROR, "HPAK_CreatePak: bad checksum for %s. Ignored\n", pakname );
		return;
	}

	hash_pack_header.ident = IDCUSTOMHEADER;
	hash_pack_header.version = IDCUSTOM_VERSION;
	hash_pack_header.seek = 0;

	FS_Write( fout, &hash_pack_header, sizeof( hash_pack_header ));

	hash_pack_dir.count = 1;
	hash_pack_dir.dirs = Z_Malloc( sizeof( hpak_dir_t ));
	hash_pack_dir.dirs[0].DirectoryResource = *DirEnt;
	hash_pack_dir.dirs[0].seek = FS_Tell( fout );
	hash_pack_dir.dirs[0].size = DirEnt->nDownloadSize;

	if( data == NULL )
	{
		HPAK_FileCopy( fout, f, hash_pack_dir.dirs[0].size );
	}
	else
	{
		FS_Write( fout, data, hash_pack_dir.dirs[0].size );
	}

	filelocation = FS_Tell( fout );
	FS_Write( fout, &hash_pack_dir.count, sizeof( hash_pack_dir.count ));
	FS_Write( fout, &hash_pack_dir.dirs[0], sizeof( hpak_dir_t ));

	Mem_Free( hash_pack_dir.dirs );
	Q_memset( &hash_pack_dir, 0, sizeof( hpak_container_t ));

	hash_pack_header.seek = filelocation;
	FS_Seek( fout, 0, SEEK_SET );
	FS_Write( fout, &hash_pack_header, sizeof( hpak_header_t ));
	FS_Close( fout );
}
bool FS_ParseLiblistGam(const char *filename, const char *gamedir, gameinfo_t *GameInfo)
{
	char *pfile;
	string token;
	
	if(!GameInfo)
		return false;	
	
	char *afile = mpFileSystem->LoadFile(filename, NULL, false);
	
	if(!afile)
		return false;

	// setup default values
	GameInfo->max_edicts = 900;	// default value if not specified
	GameInfo->max_tents = 500;
	GameInfo->max_beams = 128;
	GameInfo->soundclip_dist = 1536;
	GameInfo->max_particles = 4096;
	GameInfo->version = 1.0f;
	GameInfo->falldir[0] = '\0';
	
	GameInfo->title = "New Game";
	GameInfo->gamedir = gamedir;
	GameInfo->basedir = SI.ModuleName;
	GameInfo->sp_entity = "info_player_start";
	GameInfo->mp_entity = "info_player_deathmatch";
	GameInfo->game_dll = "dlls/hl.dll";
	GameInfo->startmap = "newmap";
	GameInfo->dll_path = "cl_dlls";
	GameInfo->iconpath = "game.ico";

	VectorSet(GameInfo->client_mins[0],   0,   0,  0 );
	VectorSet(GameInfo->client_maxs[0],   0,   0,  0 );
	VectorSet(GameInfo->client_mins[1], -16, -16, -36);
	VectorSet(GameInfo->client_maxs[1],  16,  16,  36);
	VectorSet(GameInfo->client_mins[2], -32, -32, -32);
	VectorSet(GameInfo->client_maxs[2],  32,  32,  32);
	VectorSet(GameInfo->client_mins[3], -16, -16, -18);
	VectorSet(GameInfo->client_maxs[3],  16,  16,  18);

	pfile = afile;

	while((pfile = COM_ParseFile(pfile, token)) != NULL)
	{
		if(token == "game")
			pfile = COM_ParseFile(pfile, GameInfo->msTitle);
		if(token == "gamedir")
			pfile = COM_ParseFile(pfile, GameInfo->msGameDir);
		if(token == "fallback_dir")
			pfile = COM_ParseFile(pfile, GameInfo->msFallDir);
		else if(token == "startmap")
		{
			pfile = COM_ParseFile(pfile, GameInfo->msStartMap);
			FS_StripExtension(GameInfo->msStartMap); // HQ2:Amen has extension .bsp
		}
		else if(token == "trainmap" || token == "trainingmap")
		{
			pfile = COM_ParseFile(pfile, GameInfo->msTrainMap);
			FS_StripExtension(GameInfo->msTrainMap); // HQ2:Amen has extension .bsp
		}
		else if(token == "url_info")
			pfile = COM_ParseFile(pfile, GameInfo->msGameURL);
		else if(token == "url_dl")
			pfile = COM_ParseFile(pfile, GameInfo->msUpdateURL);
		else if(token == "gamedll")
		{
			pfile = COM_ParseFile(pfile, GameInfo->msGameDLL);
			COM_FixSlashes(GameInfo->msGameDLL);
		}
		else if(token == "icon")
		{
			pfile = COM_ParseFile(pfile, GameInfo->msIconPath);
			COM_FixSlashes(GameInfo->msIconPath);
			FS_DefaultExtension(GameInfo->msIconPath, ".ico");
		}
		else if(token == "type")
		{
			pfile = COM_ParseFile(pfile, token);

			if(token == "singleplayer_only")
			{
				GameInfo->gamemode = 1;
				strncpy(GameInfo->type, "Single", sizeof(GameInfo->type));
			}
			else if(token == "multiplayer_only")
			{
				GameInfo->gamemode = 2;
				strncpy(GameInfo->type, "Multiplayer", sizeof(GameInfo->type));
			}
			else
			{
				// pass type without changes
				GameInfo->gamemode = 0;
				strncpy(GameInfo->type, token, sizeof(GameInfo->type));
			};
		}
		else if(token == "version")
		{
			pfile = COM_ParseFile(pfile, token);
			GameInfo->version = Q_atof(token);
		}
		else if(token == "size")
		{
			pfile = COM_ParseFile(pfile, token);
			GameInfo->size = Q_atoi(token);
		}
		else if(token == "mpentity")
			pfile = COM_ParseFile(pfile, GameInfo->mp_entity);
		else if(token == "secure")
		{
			pfile = COM_ParseFile(pfile, token);
			GameInfo->secure = Q_atoi(token);
		}
		else if(token == "nomodels")
		{
			pfile = COM_ParseFile(pfile, token);
			GameInfo->nomodels = Q_atoi(token);
		};
	};

	if(!mpFileSystem->IsSysFolderExists(va("%s\\%s", host.rootdir, GameInfo->gamedir)))
		GameInfo->msGameDir = gamedir;

	if(!mpFileSystem->IsSysFolderExists(va("%s\\%s", host.rootdir, GameInfo->falldir)))
		GameInfo->msFallDir = "";

	if(afile != NULL)
		Mem_Free(afile);

	return true;
};
Example #15
0
/*
================
Image_Save

writes image as any known format
================
*/
qboolean FS_SaveImage( const char *filename, rgbdata_t *pix )
{
          const char	*ext = FS_FileExtension( filename );
	qboolean		anyformat = !Q_stricmp( ext, "" ) ? true : false;
	string		path, savename;
	const savepixformat_t *format;

	if( !pix || !pix->buffer || anyformat )
	{
		// clear any force flags
		image.force_flags = 0;
		return false;
	}

	Q_strncpy( savename, filename, sizeof( savename ));
	FS_StripExtension( savename ); // remove extension if needed

	if( pix->flags & (IMAGE_CUBEMAP|IMAGE_SKYBOX))
	{
		size_t		realSize = pix->size; // keep real pic size
		byte		*picBuffer; // to avoid corrupt memory on free data
		const suffix_t	*box;
		int		i;

		if( pix->flags & IMAGE_SKYBOX )
			box = skybox_qv1;
		else if( pix->flags & IMAGE_CUBEMAP )
			box = cubemap_v2;
		else
		{
			// clear any force flags
			image.force_flags = 0;
			return false;	// do not happens
		}

		pix->size /= 6; // now set as side size 
		picBuffer = pix->buffer;

		// save all sides seperately
		for( format = image.saveformats; format && format->formatstring; format++ )
		{
			if( !Q_stricmp( ext, format->ext ))
			{
				for( i = 0; i < 6; i++ )
				{
					Q_sprintf( path, format->formatstring, savename, box[i].suf, format->ext );
					if( !format->savefunc( path, pix )) break; // there were errors
					pix->buffer += pix->size; // move pointer
				}

				// restore pointers
				pix->size = realSize;
				pix->buffer = picBuffer;

				// clear any force flags
				image.force_flags = 0;

				return ( i == 6 );
			}
		}
	}
	else
	{
		for( format = image.saveformats; format && format->formatstring; format++ )
		{
			if( !Q_stricmp( ext, format->ext ))
			{
				Q_sprintf( path, format->formatstring, savename, "", format->ext );
				if( format->savefunc( path, pix ))
				{
					// clear any force flags
					image.force_flags = 0;
					return true; // saved
				}
			}
		}
	}

	// clear any force flags
	image.force_flags = 0;

	return false;
}
Example #16
0
qboolean HPAK_ResourceForHash( const char *filename, char *inHash, resource_t *pRes )
{
	file_t		*f;
	hpak_t		*hpak;
	hpak_container_t	hpakcontainer;
	hpak_header_t	hdr;
	string		pakname;
	int		ret;

	if( !filename || !filename[0] )
		return false;
	
	for( hpak = hpak_queue; hpak != NULL; hpak = hpak->next )
	{
		if( !Q_stricmp( hpak->name, filename ) && !Q_memcmp( hpak->HpakResource.rgucMD5_hash, inHash, 0x10 ))
		{
			if( pRes != NULL ) *pRes = hpak->HpakResource;
			return true;
		}
	}

	Q_strncpy( pakname, filename, sizeof( pakname ));
	FS_StripExtension( pakname );
	FS_DefaultExtension( pakname, ".hpk" );

	f = FS_Open( pakname, "rb", false );
	if( !f ) return false;

	FS_Read( f, &hdr, sizeof( hdr ));

	if( hdr.ident != IDCUSTOMHEADER )
	{
		MsgDev( D_ERROR, "HPAK_ResourceForHash: %s it's not a HPK file.\n", pakname );
		FS_Close( f );
		return false;
	}

	if( hdr.version != IDCUSTOM_VERSION )
	{
		MsgDev( D_ERROR, "HPAK_ResourceForHash: %s has invalid version (%i should be %i).\n", pakname, hdr.version, IDCUSTOM_VERSION );
		FS_Close( f );
		return false;
	}

	FS_Seek( f, hdr.seek, SEEK_SET );
	FS_Read( f, &hpakcontainer.count, sizeof( hpakcontainer.count ));

	if( hpakcontainer.count < 1 || hpakcontainer.count > MAX_FILES_IN_WAD )
	{
		MsgDev( D_ERROR, "HPAK_ResourceForHash: %s has too many lumps %u.\n", pakname, hpakcontainer.count );
		FS_Close( f );
		return false;
	}

	hpakcontainer.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpakcontainer.count );
	FS_Read( f, hpakcontainer.dirs, sizeof( hpak_dir_t ) * hpakcontainer.count );
	ret = HPAK_FindResource( &hpakcontainer, inHash, pRes );

	Mem_Free( hpakcontainer.dirs );
	FS_Close( f );
	return(ret);
}
Example #17
0
static qboolean HPAK_Validate( const char *filename, qboolean quiet )
{
	file_t		*f;
	hpak_dir_t	*dataDir;
	hpak_header_t	hdr;
	byte		*dataPak;
	int		i, num_lumps;
	MD5Context_t	MD5_Hash;
	string		pakname;
	resource_t	*pRes;
	char		md5[16];

	if( quiet ) HPAK_FlushHostQueue();

	// not an error - just flush queue
	if( !filename || !*filename )
		return true;

	Q_strncpy( pakname, filename, sizeof( pakname ));
	FS_StripExtension( pakname );
	FS_DefaultExtension( pakname, ".hpk" );

	f = FS_Open( pakname, "rb", false );
	if( !f )
	{
		MsgDev( D_INFO, "Couldn't find %s.\n", pakname );
		return true;
	}

	if( !quiet ) MsgDev( D_INFO, "Validating %s\n", pakname );

	FS_Read( f, &hdr, sizeof( hdr ));
	if( hdr.ident != IDCUSTOMHEADER || hdr.version != IDCUSTOM_VERSION )
	{
		MsgDev( D_ERROR, "HPAK_ValidatePak: %s does not have a valid HPAK header.\n", pakname );
		FS_Close( f );
		return false;
	}

	FS_Seek( f, hdr.seek, SEEK_SET );
	FS_Read( f, &num_lumps, sizeof( num_lumps ));

	if( num_lumps < 1 || num_lumps > MAX_FILES_IN_WAD )
	{
		MsgDev( D_ERROR, "HPAK_ValidatePak: %s has too many lumps %u.\n", pakname, num_lumps );
		FS_Close( f );
		return false;
	}

	if( !quiet ) MsgDev( D_INFO, "# of Entries:  %i\n", num_lumps );

	dataDir = Z_Malloc( sizeof( hpak_dir_t ) * num_lumps );
	FS_Read( f, dataDir, sizeof( hpak_dir_t ) * num_lumps );

	if( !quiet ) MsgDev( D_INFO, "# Type Size FileName : MD5 Hash\n" );

	for( i = 0; i < num_lumps; i++ )
	{
		if( dataDir[i].size < 1 || dataDir[i].size > 131071 )
		{
			// odd max size
			MsgDev( D_ERROR, "HPAK_ValidatePak: lump %i has invalid size %s\n", i, Q_pretifymem( dataDir[i].size, 2 ));
			Mem_Free( dataDir );
			FS_Close(f);
			return false;
		}

		dataPak = Z_Malloc( dataDir[i].size );
		FS_Seek( f, dataDir[i].seek, SEEK_SET );
		FS_Read( f, dataPak, dataDir[i].size );

		Q_memset( &MD5_Hash, 0, sizeof( MD5Context_t ));
		MD5Init( &MD5_Hash );
		MD5Update( &MD5_Hash, dataPak, dataDir[i].size );
		MD5Final( md5, &MD5_Hash );

		pRes = &dataDir[i].DirectoryResource;

		MsgDev( D_INFO, "%i:      %s %s %s:   ", i, HPAK_TypeFromIndex( pRes->type ),
		Q_pretifymem( pRes->nDownloadSize, 2 ), pRes->szFileName );  

		if( Q_memcmp( md5, pRes->rgucMD5_hash, 0x10 ))
		{
			if( quiet )
			{
				MsgDev( D_ERROR, "HPAK_ValidatePak: %s has invalid checksum.\n", pakname );
				Mem_Free( dataPak );
				Mem_Free( dataDir );
				FS_Close( f );
				return false;
			}
			else MsgDev( D_INFO, "failed\n" );
		}
		else
		{
			if( !quiet ) MsgDev( D_INFO, "OK\n" );
		}

		// at this point, it's passed our checks.
		Mem_Free( dataPak );
	}

	Mem_Free( dataDir );
	FS_Close( f );
	return true;
}
Example #18
0
void HPAK_AddLump( qboolean add_to_queue, const char *name, resource_t *DirEnt, byte *data, file_t *f )
{
	int		i, position, length;
	string		pakname1, pakname2;
	char		md5[16];
	MD5Context_t	MD5_Hash;
	hpak_container_t	hpak1, hpak2;
	file_t		*f1, *f2;
	hpak_dir_t	*dirs;
	byte		*temp;

	if( !name || !name[0] )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: NULL name\n" );
		return;
	}

	if( !DirEnt )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: invalid lump\n" );
		return;
	}

	if( data == NULL && f == NULL )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: missing lump data\n" );
		return;
	}

	if( DirEnt->nDownloadSize < 1024 || DirEnt->nDownloadSize > 131072 )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: invalid size %s\n", Q_pretifymem( DirEnt->nDownloadSize, 2 ));
		return;
	}

	// hash it
	Q_memset( &MD5_Hash, 0, sizeof( MD5Context_t ));
	MD5Init( &MD5_Hash );

	if( data == NULL )
	{
		// there are better ways
		position = FS_Tell( f );
		temp = Z_Malloc( DirEnt->nDownloadSize );
		FS_Read( f, temp, DirEnt->nDownloadSize );
		FS_Seek( f, position, SEEK_SET );

		MD5Update( &MD5_Hash, temp, DirEnt->nDownloadSize );
		Mem_Free( temp );
	}
	else
	{
		MD5Update( &MD5_Hash, data, DirEnt->nDownloadSize );
	}

	MD5Final( md5, &MD5_Hash );

	if( Q_memcmp( md5, DirEnt->rgucMD5_hash, 0x10 ))
	{
		MsgDev( D_ERROR, "HPAK_AddLump: bad checksum for %s. Ignored\n", DirEnt->szFileName );
		return;
	}

	if( add_to_queue )
	{
		HPAK_AddToQueue( name, DirEnt, data, f );
		return;
	}

	Q_strncpy( pakname1, name, sizeof( pakname1 ));
	FS_StripExtension( pakname1 );
	FS_DefaultExtension( pakname1, ".hpk" );

	f1 = FS_Open( pakname1, "rb", false );

	if( !f1 )
	{
		// create new pack
		HPAK_CreatePak( name, DirEnt, data, f );
		return;
	}

	Q_strncpy( pakname2, pakname1, sizeof( pakname2 ));
	FS_StripExtension( pakname2 );
	FS_DefaultExtension( pakname2, ".hp2" );

	f2 = FS_Open( pakname2, "w+b", false );

	if( !f2 )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: couldn't open %s.\n", pakname2 );
		FS_Close( f1 );
		return;
	}

	// load headers
	FS_Read( f1, &hash_pack_header, sizeof( hpak_header_t ));

	if( hash_pack_header.version != IDCUSTOM_VERSION )
	{
		// we don't check the HPAK bit for some reason.
		MsgDev( D_ERROR, "HPAK_AddLump: %s does not have a valid header.\n", pakname2 );
		FS_Close( f1 );
		FS_Close( f2 );
	}

	length = FS_FileLength( f1 );
	HPAK_FileCopy( f2, f1, length );

	FS_Seek( f1, hash_pack_header.seek, SEEK_SET );
	FS_Read( f1, &hpak1.count, sizeof( hpak1.count ));

	if( hpak1.count < 1 || hpak1.count > MAX_FILES_IN_WAD )
	{
		MsgDev( D_ERROR, "HPAK_AddLump: %s contain too many lumps.\n", pakname1 );
		FS_Close( f1 );
		FS_Close( f2 );
		return;
	}

	// load the data
	hpak1.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpak1.count );
	FS_Read( f1, hpak1.dirs, sizeof( hpak_dir_t ) * hpak1.count );
	FS_Close( f1 );

	if( HPAK_FindResource( &hpak1, DirEnt->rgucMD5_hash, NULL ))
	{
		Mem_Free( hpak1.dirs );
		FS_Close( f2 );
	}

	// make a new container
	hpak2.count = hpak1.count;
	hpak2.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpak2.count );
	Q_memcpy( hpak2.dirs, hpak1.dirs, hpak1.count );

	for( i = 0, dirs = NULL; i < hpak1.count; i++ )
	{
		if( Q_memcmp( hpak1.dirs[i].DirectoryResource.rgucMD5_hash, DirEnt->rgucMD5_hash, 16 ) < 0 )
		{
			dirs = &hpak1.dirs[i];
			while( i < hpak1.count )
			{
				hpak2.dirs[i+1] = hpak1.dirs[i];
				i++;
			}
			break;
		}
	}

	if( dirs == NULL ) dirs = &hpak2.dirs[hpak2.count-1];

	Q_memset( dirs, 0, sizeof( hpak_dir_t ));
	FS_Seek( f2, hash_pack_header.seek, SEEK_SET );
	dirs->DirectoryResource = *DirEnt;
	dirs->seek = FS_Tell( f2 );
	dirs->size = DirEnt->nDownloadSize;

	if( !data ) HPAK_FileCopy( f2, f, dirs->size );
	else FS_Write( f2, data, dirs->size );

	hash_pack_header.seek = FS_Tell( f2 );
	FS_Write( f2, &hpak2.count, sizeof( hpak2.count ));

	for( i = 0; i < hpak2.count; i++ )
	{
		FS_Write( f2, &hpak2.dirs[i], sizeof( hpak_dir_t ));
	}

	// finalize
	Mem_Free( hpak1.dirs );
	Mem_Free( hpak2.dirs );

	FS_Seek( f2, 0, SEEK_SET );
	FS_Write( f2, &hash_pack_header, sizeof( hpak_header_t ));
	FS_Close( f2 );

	FS_Delete( pakname1 );
	FS_Rename( pakname2, pakname1 );
}
Example #19
0
/*
=================
LoadSurfaceExtraFile

reads a surface info file (<map>.srf)
=================
*/
void LoadSurfaceExtraFile( const char *path )
{
	char		srfPath[MAX_SYSPATH];
	surfaceExtra_t	*se;
	int		surfaceNum;
	script_t		*script;
	token_t		token;
	
	if( path == NULL || path[0] == '\0' )
		return;
	
	com.strcpy( srfPath, path );
	FS_StripExtension( srfPath );
	FS_DefaultExtension( srfPath, ".srf" );
	Msg( "Loading %s\n", srfPath );

	script = (void *)Com_OpenScript( srfPath, NULL, 0 );
	if( !script ) Sys_Break( "unable to load %s\n", srfPath ); // q3map is always crashed if this missed
	
	while( 1 )
	{
		if( !Com_ReadToken( script, SC_ALLOW_NEWLINES|SC_PARSE_GENERIC, &token ))
			break;
		
		if( !com.stricmp( token.string, "default" )) se = &seDefault;
		else
		{
			surfaceNum = com.atoi( token.string );
			if( surfaceNum < 0 || surfaceNum > MAX_MAP_DRAW_SURFS )
				Sys_Error( "ReadSurfaceExtraFile(): %s, line %d: bogus surface num %d", srfPath, token.line, surfaceNum );
			while( surfaceNum >= numSurfaceExtras )
				se = AllocSurfaceExtra();
			se = &surfaceExtras[surfaceNum];
		}
		
		// handle { } section
		if( !Com_ReadToken( script, SC_ALLOW_NEWLINES|SC_PARSE_GENERIC, &token ) || com.strcmp( token.string, "{" ))
			Sys_Error( "ReadSurfaceExtraFile(): %s, line %d: { not found\n", srfPath, token.line );
		while( 1 )
		{
			if( !Com_ReadToken( script, SC_ALLOW_NEWLINES|SC_PARSE_GENERIC, &token ))
				break;
			if( !com.strcmp( token.string, "}" ))
				break;
			
			if( !com.stricmp( token.string, "shader" ))
			{
				Com_ReadToken( script, SC_ALLOW_PATHNAMES|SC_PARSE_GENERIC, &token );
				se->si = ShaderInfoForShader( token.string );
			}
			else if( !com.stricmp( token.string, "parent" ))
			{
				Com_ReadLong( script, false, &se->parentSurfaceNum );
			}
			else if( !com.stricmp( token.string, "entity" ))
			{
				Com_ReadLong( script, false, &se->entityNum );
			}
			else if( !com.stricmp( token.string, "castShadows" ))
			{
				Com_ReadLong( script, false, &se->castShadows );
			}
			else if( !com.stricmp( token.string, "receiveShadows" ))
			{
				Com_ReadLong( script, false, &se->recvShadows );
			}
			else if( !com.stricmp( token.string, "sampleSize" ))
			{
				Com_ReadLong( script, false, &se->sampleSize );
			}
			else if( !com.stricmp( token.string, "longestCurve" ))
			{
				Com_ReadFloat( script, false, &se->longestCurve );
			}
			else if( !com.stricmp( token.string, "lightmapAxis" ))
				Com_Parse1DMatrix( script, 3, se->lightmapAxis );
			
			// ignore all other tokens on the line
			Com_SkipRestOfLine( script );
		}
	}
	Com_CloseScript( script );
}
Example #20
0
qboolean HPAK_GetDataPointer( const char *filename, resource_t *pResource, byte **buffer, int *size )
{
	file_t		*f;
	int		i, num_lumps;
	hpak_dir_t	*direntries;
	byte		*tmpbuf;
	string		pakname;
	hpak_t		*queue;
	hpak_header_t	hdr;

	if( !filename || !filename[0] )
		return false;

	if( buffer ) *buffer = NULL;
	if( size ) *size = 0;

	for( queue = hpak_queue; queue != NULL; queue = queue->next )
	{
		if( !Q_stricmp(queue->name, filename ) && !Q_memcmp( queue->HpakResource.rgucMD5_hash, pResource->rgucMD5_hash, 16 ))
		{
			if( buffer )
			{
				tmpbuf = Z_Malloc( queue->size );
				Q_memcpy( tmpbuf, queue->data, queue->size );
				*buffer = tmpbuf;
			}

			if( size ) *size = queue->size;

			return true;
		}
	}

	Q_strncpy( pakname, filename, sizeof( pakname ));
	FS_StripExtension( pakname );
	FS_DefaultExtension( pakname, ".hpk" );

	f = FS_Open( pakname, "rb", false );
	if( !f ) return false;

	FS_Read( f, &hdr, sizeof( hdr ));

	if( hdr.ident != IDCUSTOMHEADER )
	{
		MsgDev( D_ERROR, "HPAK_GetDataPointer: %s it's not a HPK file.\n", pakname );
		FS_Close( f );
		return false;
	}

	if( hdr.version != IDCUSTOM_VERSION )
	{
		MsgDev( D_ERROR, "HPAK_GetDataPointer: %s has invalid version (%i should be %i).\n", pakname, hdr.version, IDCUSTOM_VERSION );
		FS_Close( f );
		return false;
	}

	FS_Seek( f, hdr.seek, SEEK_SET );
	FS_Read( f, &num_lumps, sizeof( num_lumps ));

	if( num_lumps < 1 || num_lumps > MAX_FILES_IN_WAD )
	{
		MsgDev( D_ERROR, "HPAK_GetDataPointer: %s has too many lumps %u.\n", filename, num_lumps );
		FS_Close( f );
		return false;
	}

	direntries = Z_Malloc( sizeof( hpak_dir_t ) * num_lumps );
	FS_Read( f, direntries, sizeof( hpak_dir_t ) * num_lumps );

	for( i = 0; i < num_lumps; i++ )
	{
		if( !Q_memcmp( direntries[i].DirectoryResource.rgucMD5_hash, pResource->rgucMD5_hash, 16 ))
		{
			FS_Seek( f, direntries[i].seek, SEEK_SET );

			if( buffer && direntries[i].size > 0 )
			{
				tmpbuf = Z_Malloc( direntries[i].size );
				FS_Read( f, tmpbuf, direntries[i].size );
				*buffer = tmpbuf;
			}

			Mem_Free( direntries );
			FS_Close( f );
			return true;
		}
	}

	Mem_Free( direntries );
	FS_Close( f );
	return false;
}
Example #21
0
/*
=================
VID_CubemapShot
=================
*/
qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qboolean skyshot )
{
	rgbdata_t		*r_shot, *r_side;
	byte		*temp = NULL;
	byte		*buffer = NULL;
	string		basename;
	int		i = 1, flags, result;

	if( !RI.drawWorld || !cl.worldmodel )
		return false;

	// make sure the specified size is valid
	while( i < size ) i<<=1;

	if( i != size ) return false;
	if( size > glState.width || size > glState.height )
		return false;

	// setup refdef
	RI.params |= RP_ENVVIEW;	// do not render non-bmodel entities

	// alloc space
	temp = Mem_Alloc( r_temppool, size * size * 3 );
	buffer = Mem_Alloc( r_temppool, size * size * 3 * 6 );
	r_shot = Mem_Alloc( r_temppool, sizeof( rgbdata_t ));
	r_side = Mem_Alloc( r_temppool, sizeof( rgbdata_t ));

	// use client vieworg
	if( !vieworg ) vieworg = cl.refdef.vieworg;

	for( i = 0; i < 6; i++ )
	{
		// go into 3d mode
		R_Set2DMode( false );

		if( skyshot )
		{
			R_DrawCubemapView( vieworg, r_skyBoxInfo[i].angles, size );
			flags = r_skyBoxInfo[i].flags;
		}
		else
		{
			R_DrawCubemapView( vieworg, r_envMapInfo[i].angles, size );
			flags = r_envMapInfo[i].flags;
		}

		pglReadPixels( 0, 0, size, size, GL_RGB, GL_UNSIGNED_BYTE, temp );
		r_side->flags = IMAGE_HAS_COLOR;
		r_side->width = r_side->height = size;
		r_side->type = PF_RGB_24;
		r_side->size = r_side->width * r_side->height * 3;
		r_side->buffer = temp;

		if( flags ) Image_Process( &r_side, 0, 0, 0.0f, flags, NULL );
		Q_memcpy( buffer + (size * size * 3 * i), r_side->buffer, size * size * 3 );
	}

	RI.params &= ~RP_ENVVIEW;

	r_shot->flags = IMAGE_HAS_COLOR;
	r_shot->flags |= (skyshot) ? IMAGE_SKYBOX : IMAGE_CUBEMAP;
	r_shot->width = size;
	r_shot->height = size;
	r_shot->type = PF_RGB_24;
	r_shot->size = r_shot->width * r_shot->height * 3 * 6;
	r_shot->palette = NULL;
	r_shot->buffer = buffer;

	// make sure what we have right extension
	Q_strncpy( basename, base, MAX_STRING );
	FS_StripExtension( basename );
	FS_DefaultExtension( basename, ".tga" );

	// write image as 6 sides
	result = FS_SaveImage( basename, r_shot );
	FS_FreeImage( r_shot );
	FS_FreeImage( r_side );

	return result;
}
Example #22
0
void HPAK_RemoveLump( const char *name, resource_t *resource )
{
	string		read_path;
	string		save_path;
	file_t		*f1, *f2;
	hpak_container_t	hpak_read;
	hpak_container_t	hpak_save;
	int		i, j;

	if( !name || !name[0] || !resource )
		return;

	HPAK_FlushHostQueue();

	Q_strncpy( read_path, name, sizeof( read_path ));
	FS_StripExtension( read_path );
	FS_DefaultExtension( read_path, ".hpk" );

	f1 = FS_Open( read_path, "rb", false );
	if( !f1 )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s couldn't open.\n", read_path );
		return;
	}

	Q_strncpy( save_path, read_path, sizeof( save_path ));
	FS_StripExtension( save_path );
	FS_DefaultExtension( save_path, ".hp2" );
	f2 = FS_Open( save_path, "w+b", false );
	if( !f2 )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s couldn't open.\n", save_path );
		FS_Close( f1 );
		return;
	}

	FS_Seek( f1, 0, SEEK_SET );
	FS_Seek( f2, 0, SEEK_SET );

	// header copy
	FS_Read( f1, &hash_pack_header, sizeof( hpak_header_t ));
	FS_Write( f2, &hash_pack_header, sizeof( hpak_header_t ));

	if( hash_pack_header.ident != IDCUSTOMHEADER || hash_pack_header.version != IDCUSTOM_VERSION )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s has invalid header.\n", read_path );
		FS_Close( f1 );
		FS_Close( f2 );
		FS_Delete( save_path ); // delete temp file
		return;
	}

	FS_Seek( f1, hash_pack_header.seek, SEEK_SET );
	FS_Read( f1, &hpak_read.count, sizeof( hpak_read.count ));

	if( hpak_read.count < 1 || hpak_read.count > MAX_FILES_IN_WAD )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s has invalid number of lumps.\n", read_path );
		FS_Close( f1 );
		FS_Close( f2 );
		FS_Delete( save_path ); // delete temp file
		return;
	}

	if( hpak_read.count == 1 )
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: %s only has one element, so it's not deleted.\n", read_path );
		FS_Close( f1 );
		FS_Close( f2 );
		FS_Delete( read_path );
		FS_Delete( save_path );
		return;
	}

	hpak_save.count = hpak_read.count - 1;
	hpak_read.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpak_read.count );
	hpak_save.dirs = Z_Malloc( sizeof( hpak_dir_t ) * hpak_save.count );

	FS_Read( f1, hpak_read.dirs, sizeof( hpak_dir_t ) * hpak_read.count );

	if( !HPAK_FindResource( &hpak_read, resource->rgucMD5_hash, NULL ))
	{
		MsgDev( D_ERROR, "HPAK_RemoveLump: Couldn't find the lump %s in hpak %s.n", resource->szFileName, read_path );
		Mem_Free( hpak_read.dirs );
		Mem_Free( hpak_save.dirs );
		FS_Close( f1 );
		FS_Close( f2 );
		FS_Delete( save_path );
		return;
	}

	MsgDev( D_INFO, "Removing lump %s from %s.\n", resource->szFileName, read_path );

	// If there's a collision, we've just corrupted this hpak.
	for( i = 0, j = 0; i < hpak_read.count; i++ )
	{
		if( !Q_memcmp( hpak_read.dirs[i].DirectoryResource.rgucMD5_hash, resource->rgucMD5_hash, 16 ))
			continue;

		hpak_save.dirs[j] = hpak_read.dirs[i];
		hpak_save.dirs[j].seek = FS_Tell( f2 );
		FS_Seek( f1, hpak_read.dirs[j].seek, SEEK_SET );
		HPAK_FileCopy( f2, f1, hpak_save.dirs[j].size );
		j++;
	}

	hash_pack_header.seek = FS_Tell( f2 );
	FS_Write( f2, &hpak_save.count, ( hpak_save.count ));

	for( i = 0; i < hpak_save.count; i++ )
	{
		FS_Write( f2, &hpak_save.dirs[i], sizeof( hpak_dir_t ));
	}

	FS_Seek( f2, 0, SEEK_SET );
	FS_Write( f2, &hash_pack_header, sizeof( hpak_header_t ));

	Mem_Free( hpak_read.dirs );
	Mem_Free( hpak_save.dirs );
	FS_Close( f1 );
	FS_Close( f2 );

	FS_Delete( read_path );
	FS_Rename( save_path, read_path );
}
Example #23
0
/*
================
FS_LoadImage

loading and unpack to rgba any known image
================
*/
rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size )
{
          const char	*ext = FS_FileExtension( filename );
	string		path, loadname, sidename;
	qboolean		anyformat = true;
	int		i, filesize = 0;
	const loadpixformat_t *format;
	const cubepack_t	*cmap;
	byte		*f;

	Image_Reset(); // clear old image
	Q_strncpy( loadname, filename, sizeof( loadname ));

	if( Q_stricmp( ext, "" ))
	{
		// we needs to compare file extension with list of supported formats
		// and be sure what is real extension, not a filename with dot
		for( format = image.loadformats; format && format->formatstring; format++ )
		{
			if( !Q_stricmp( format->ext, ext ))
			{
				FS_StripExtension( loadname );
				anyformat = false;
				break;
			}
		}
	}

	// HACKHACK: skip any checks, load file from buffer
	if( filename[0] == '#' && buffer && size ) goto load_internal;

	// now try all the formats in the selected list
	for( format = image.loadformats; format && format->formatstring; format++)
	{
		if( anyformat || !Q_stricmp( ext, format->ext ))
		{
			Q_sprintf( path, format->formatstring, loadname, "", format->ext );
			image.hint = format->hint;
			f = FS_LoadFile( path, &filesize, false );
			if( f && filesize > 0 )
			{
				if( format->loadfunc( path, f, filesize ))
				{
					Mem_Free( f ); // release buffer
					return ImagePack(); // loaded
				}
				else Mem_Free(f); // release buffer 
			}
		}
	}

	// check all cubemap sides with package suffix
	for( cmap = load_cubemap; cmap && cmap->type; cmap++ )
	{
		for( i = 0; i < 6; i++ )
		{
			// for support mixed cubemaps e.g. sky_ft.bmp, sky_rt.tga
			// NOTE: all loaders must keep sides in one format for all
			for( format = image.loadformats; format && format->formatstring; format++ )
			{
				if( anyformat || !Q_stricmp( ext, format->ext ))
				{
					Q_sprintf( path, format->formatstring, loadname, cmap->type[i].suf, format->ext );
					image.hint = cmap->type[i].hint; // side hint

					f = FS_LoadFile( path, &filesize, false );
					if( f && filesize > 0 )
					{
						// this name will be used only for tell user about problems 
						if( format->loadfunc( path, f, filesize ))
						{         
							Q_snprintf( sidename, sizeof( sidename ), "%s%s.%s", loadname, cmap->type[i].suf, format->ext );
							if( FS_AddSideToPack( sidename, cmap->type[i].flags )) // process flags to flip some sides
							{
								Mem_Free( f );
								break; // loaded
							}
						}
						Mem_Free( f );
					}
				}
			}

			if( image.num_sides != i + 1 ) // check side
			{
				// first side not found, probably it's not cubemap
				// it contain info about image_type and dimensions, don't generate black cubemaps 
				if( !image.cubemap ) break;
				MsgDev( D_ERROR, "FS_LoadImage: couldn't load (%s%s), create black image\n", loadname, cmap->type[i].suf );

				// Mem_Alloc already filled memblock with 0x00, no need to do it again
				image.cubemap = Mem_Realloc( host.imagepool, image.cubemap, image.ptr + image.size );
				image.ptr += image.size; // move to next
				image.num_sides++; // merge counter
			}
		}

		// make sure what all sides is loaded
		if( image.num_sides != 6 )
		{
			// unexpected errors ?
			if( image.cubemap )
				Mem_Free( image.cubemap );
			Image_Reset();
		}
		else break;
	}

	if( image.cubemap )
		return ImagePack(); // all done

load_internal:
	for( format = image.loadformats; format && format->formatstring; format++ )
	{
		if( anyformat || !Q_stricmp( ext, format->ext ))
		{
			image.hint = format->hint;
			if( buffer && size > 0  )
			{
				if( format->loadfunc( loadname, buffer, size ))
					return ImagePack(); // loaded
			}
		}
	}

	if( !image.loadformats || image.loadformats->ext == NULL )
		MsgDev( D_NOTE, "FS_LoadImage: imagelib offline\n" );
	else if( filename[0] != '#' )
		MsgDev( D_WARN, "FS_LoadImage: couldn't load \"%s\"\n", loadname );

	// clear any force flags
	image.force_flags = 0;

	return NULL;
}
Example #24
0
/*
================
FS_LoadSound

loading and unpack to wav any known sound
================
*/
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
{
          const char	*ext = FS_FileExtension( filename );
	string		path, loadname;
	qboolean		anyformat = true;
	int		filesize = 0;
	const loadwavfmt_t	*format;
	byte		*f;

	Sound_Reset(); // clear old sounddata
	Q_strncpy( loadname, filename, sizeof( loadname ));

	if( Q_stricmp( ext, "" ))
	{
		// we needs to compare file extension with list of supported formats
		// and be sure what is real extension, not a filename with dot
		for( format = sound.loadformats; format && format->formatstring; format++ )
		{
			if( !Q_stricmp( format->ext, ext ))
			{
				FS_StripExtension( loadname );
				anyformat = false;
				break;
			}
		}
	}

	// HACKHACK: skip any checks, load file from buffer
	if( filename[0] == '#' && buffer && size ) goto load_internal;

	// now try all the formats in the selected list
	for( format = sound.loadformats; format && format->formatstring; format++)
	{
		if( anyformat || !Q_stricmp( ext, format->ext ))
		{
			Q_sprintf( path, format->formatstring, loadname, "", format->ext );
			f = FS_LoadFile( path, &filesize, false );
			if( f && filesize > 0 )
			{
				if( format->loadfunc( path, f, filesize ))
				{
					Mem_Free(f); // release buffer
					return SoundPack(); // loaded
				}
				else Mem_Free(f); // release buffer
			}
		}
	}

load_internal:
	for( format = sound.loadformats; format && format->formatstring; format++ )
	{
		if( anyformat || !Q_stricmp( ext, format->ext ))
		{
			if( buffer && size > 0  )
			{
				if( format->loadfunc( loadname, buffer, size ))
					return SoundPack(); // loaded
			}
		}
	}

	if( !sound.loadformats || sound.loadformats->ext == NULL )
		MsgDev( D_NOTE, "FS_LoadSound: soundlib offline\n" );
	else if( filename[0] != '#' )
		MsgDev( D_WARN, "FS_LoadSound: couldn't load \"%s\"\n", loadname );

	return NULL;
}