Esempio n. 1
0
bool AStar::Save(IFileSystem *filesystem, const char *Filename)
{
	CUtlBuffer buf;

	AStarNode *Node;
	NodeList_t Links;

	int TotalNumLinks = 0;
	int NodeTotal = Nodes.Count();

	//////////////////////////////////////////////
	// Nodes
	buf.PutInt(NodeTotal);

	for(int i = 0; i < NodeTotal; i++)
	{
		Node = Nodes[i];

		buf.PutFloat(Node->GetPos().x);
		buf.PutFloat(Node->GetPos().y);
		buf.PutFloat(Node->GetPos().z);

		TotalNumLinks += Node->GetLinks().Count();
	}
	//////////////////////////////////////////////

	//////////////////////////////////////////////
	// Links
	buf.PutInt(TotalNumLinks);

	for(int i = 0; i < NodeTotal; i++)
	{
		Node = Nodes[i];
		Links = Node->GetLinks();
		for(int li = 0; li < Links.Count(); li++)
		{
			buf.PutInt(Node->GetID());
			buf.PutInt(Links[li]->GetID());
		}
	}
	//////////////////////////////////////////////

	//////////////////////////////////////////////
	// Write File

	FileHandle_t fh = filesystem->Open(Filename, "wb");
	if(!fh)
	{
		return false;
	}

	filesystem->Write(buf.Base(), buf.TellPut(), fh);
	filesystem->Close(fh);
	//////////////////////////////////////////////

	return true;
}
Esempio n. 2
0
//-----------------------------------------------------------------------------
// Binary buffer attribute
//-----------------------------------------------------------------------------
bool Serialize( CUtlBuffer &buf, const CUtlBinaryBlock &src )
{
	int nLength = src.Length();
	if ( !buf.IsText() )
	{
		buf.PutInt( nLength );
		if ( nLength != 0 )
		{
			buf.Put( src.Get(), nLength );
		}
		return buf.IsValid();
	}

	// Writes out uuencoded binaries
	for ( int i = 0; i < nLength; ++i )
	{
		if ( (i % 40) == 0 )
		{
			buf.PutChar( '\n' );
		}

		char b1 = src[i] & 0xF;
		char b2 = src[i] >> 4;

		char c1 = ( b1 <= 9 ) ? b1 + '0' : b1 - 10 + 'A';
		char c2 = ( b2 <= 9 ) ? b2 + '0' : b2 - 10 + 'A';

		buf.PutChar( c2 );
		buf.PutChar( c1 );
	}

	buf.PutChar( '\n' );
	return buf.IsValid();
}
Esempio n. 3
0
/**
 * Save a navigation area to the opened binary stream
 */
void CNavArea::Save( CUtlBuffer &fileBuffer, unsigned int version ) const
{
	// save ID
	fileBuffer.PutUnsignedInt( m_id );

	// save attribute flags
	fileBuffer.PutInt( m_attributeFlags );

	// save extent of area
	fileBuffer.Put( &m_nwCorner, 3*sizeof(float) );
	fileBuffer.Put( &m_seCorner, 3*sizeof(float) );

	// save heights of implicit corners
	fileBuffer.PutFloat( m_neZ );
	fileBuffer.PutFloat( m_swZ );

	// save connections to adjacent areas
	// in the enum order NORTH, EAST, SOUTH, WEST
	for( int d=0; d<NUM_DIRECTIONS; d++ )
	{
		// save number of connections for this direction
		unsigned int count = m_connect[d].Count();
		fileBuffer.PutUnsignedInt( count );

		FOR_EACH_VEC( m_connect[d], it )
		{
			NavConnect connect = m_connect[d][ it ];
			fileBuffer.PutUnsignedInt( connect.area->m_id );
		}
	}
//-----------------------------------------------------------------------------
// Purpose: Saves a bit string to the given file
// Input  :
// Output :
//-----------------------------------------------------------------------------
void SaveBitString(const int *pInts, int nInts, CUtlBuffer& buf)
{
	buf.EnsureCapacity( buf.TellPut() + (sizeof( int )*nInts) );
	for (int i=0;i<nInts;i++) 
	{
		buf.PutInt( pInts[i] );
	}
}
Esempio n. 5
0
bool CBaseGameStats::SaveToFileNOW( bool bForceSyncWrite /* = false */ )
{
	if ( !StatsTrackingIsFullyEnabled() )
		return false;

	// this code path is only for old format stats.  Products that use new format take a different path.
	if ( !gamestats->UseOldFormat() )
		return false;

	CUtlBuffer buf;
	buf.PutShort( GAMESTATS_FILE_VERSION );
	buf.Put( s_szPseudoUniqueID, 16 );

	if( ShouldTrackStandardStats() )
		m_BasicStats.SaveToBuffer( buf ); 
	else
		buf.PutInt( GAMESTATS_STANDARD_NOT_SAVED );

	gamestats->AppendCustomDataToSaveBuffer( buf );

	char fullpath[ 512 ] = { 0 };
	if ( filesystem->FileExists( GetStatSaveFileName(), GAMESTATS_PATHID ) )
	{
		filesystem->RelativePathToFullPath( GetStatSaveFileName(), GAMESTATS_PATHID, fullpath, sizeof( fullpath ) );
	}
	else
	{
		// filename is local to game dir for Steam, so we need to prepend game dir for regular file save
		char gamePath[256];
		engine->GetGameDir( gamePath, 256 );
		Q_StripTrailingSlash( gamePath );
		Q_snprintf( fullpath, sizeof( fullpath ), "%s/%s", gamePath, GetStatSaveFileName() );
		Q_strlower( fullpath );
		Q_FixSlashes( fullpath );
	}

	// StatsLog( "SaveToFileNOW '%s'\n", fullpath );

	if( CBGSDriver.m_bShuttingDown || bForceSyncWrite ) //write synchronously
	{
		filesystem->WriteFile( fullpath, GAMESTATS_PATHID, buf );

		StatsLog( "Shut down wrote to '%s'\n", fullpath );
	}
	else
	{
		// Allocate memory for async system to use (and free afterward!!!)
		size_t nBufferSize = buf.TellPut();
		void *pMem = malloc(nBufferSize);
		CUtlBuffer statsBuffer( pMem, nBufferSize );
		statsBuffer.Put( buf.Base(), nBufferSize );

		// Write data async
		filesystem->AsyncWrite( fullpath, statsBuffer.Base(), statsBuffer.TellPut(), true, false );
	}

	return true;
}
void CNetworkStringTableContainer::WriteStringTables( CUtlBuffer& buf )
{
	int numTables = m_Tables.Size();

	buf.PutInt( numTables );
	for ( int i = 0; i < numTables; i++ )
	{
		CNetworkStringTable *table = m_Tables[ i ];
		buf.PutString( table->GetTableName() );
		table->WriteStringTable( buf );
	}
}
Esempio n. 7
0
bool Serialize( CUtlBuffer &buf, const int &src )
{
	if ( buf.IsText() )
	{
		buf.Printf( "%d", src );
	}
	else
	{
		buf.PutInt( src );
	}
	return buf.IsValid();
}
void CCompiledKeyValuesWriter::WriteFiles( CUtlBuffer &buf )
{
	int c = m_Files.Count();
	buf.PutInt( c );
	for ( int i = 0; i < c; ++i )
	{
		KVFile_t &file = m_Files[ i ];
		buf.PutShort( file.filename );
		buf.PutShort( file.firstElement );
		buf.PutShort( file.numElements );
	}
}
void CCompiledKeyValuesWriter::WriteData( CUtlBuffer& buf )
{
	int c = m_Data.Count();
	buf.PutInt( c );
	for ( int i = 0; i < c; ++i )
	{
		KVInfo_t &info = m_Data[ i ];
		buf.PutShort( info.key );
		buf.PutShort( info.value );
		buf.PutShort( info.GetParent() );
		buf.PutChar( info.IsSubTree() ? 1 : 0 );
	}
}
void BasicGameStats_t::SaveToBuffer( CUtlBuffer& buf )
{
	buf.PutInt( m_nSecondsToCompleteGame );

	m_Summary.SaveToBuffer( buf );

	int c = m_MapTotals.Count();
	buf.PutInt( c );
	for ( int i = m_MapTotals.First(); i != m_MapTotals.InvalidIndex(); i = m_MapTotals.Next( i ) )
	{
		char const *name = m_MapTotals.GetElementName( i );
		BasicGameStatsRecord_t &rec = m_MapTotals[ i ];

		buf.PutString( name );
		rec.SaveToBuffer( buf );
	}

	buf.PutChar( (char)m_nHL2ChaptureUnlocked );	
	buf.PutChar( m_bSteam ? 1 : 0 );
	buf.PutChar( m_bCyberCafe ? 1 : 0 );
	buf.PutShort( (short)m_nDXLevel );
}
void BasicGameStatsRecord_t::SaveToBuffer( CUtlBuffer &buf )
{
	buf.PutInt( m_nCount );
	buf.PutInt( m_nSeconds );
	buf.PutInt( m_nCommentary );
	buf.PutInt( m_nHDR );
	buf.PutInt( m_nCaptions );
	for ( int i = 0; i < 3; ++i )
	{
		buf.PutInt( m_nSkill[ i ] );
	}

	buf.PutChar( m_bSteam ? 1 : 0 );
	buf.PutChar( m_bCyberCafe ? 1 : 0 );
	buf.PutInt( m_nDeaths );
}
void CNetworkStringTable::WriteStringTable( CUtlBuffer& buf )
{
	int numstrings = GetNumStrings();
	buf.PutInt( numstrings );
	for ( int i = 0 ; i < numstrings; i++ )
	{
		buf.PutString( GetString( i ) );
		int userDataSize;
		const void *pUserData = GetStringUserData( i, &userDataSize );
		if ( userDataSize > 0 )
		{
			buf.PutChar( 1 );
			buf.PutShort( (short)userDataSize );
			buf.Put( pUserData, userDataSize );
		}
		else
		{
			buf.PutChar( 0 );
		}
		
	}
}
void CCompiledKeyValuesWriter::WriteStringTable( CUtlBuffer& buf )
{
	int i;
	CUtlVector< int >	offsets;

	CUtlBuffer stringBuffer;

	offsets.AddToTail( stringBuffer.TellPut() );

	stringBuffer.PutString( "" );
	// save all the rest
	int c = m_StringTable.GetNumStrings();
	for ( i = 1; i < c; i++)
	{
		offsets.AddToTail( stringBuffer.TellPut() );
		stringBuffer.PutString( m_StringTable.String( i ) );
	}

	buf.Put( offsets.Base(), offsets.Count() * sizeof( int ) );

	buf.PutInt( stringBuffer.TellPut() );
	buf.Put( stringBuffer.Base(), stringBuffer.TellPut() );
}
Esempio n. 14
0
// This is a compressed save of just the data needed to drive phonemes in the engine (no word / sentence text, etc )
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : buf - 
//-----------------------------------------------------------------------------
void CSentence::CacheSaveToBuffer( CUtlBuffer& buf, int version )
{
	Assert( !buf.IsText() );
	Assert( m_bIsCached );

	int i;
	unsigned short pcount = GetRuntimePhonemeCount();

	// header
	if ( version == CACHED_SENTENCE_VERSION_ALIGNED )
	{
		buf.PutChar( version );
		buf.PutChar( 0 );
		buf.PutChar( 0 );
		buf.PutChar( 0 );
		buf.PutInt( pcount );
	}
	else
	{
		buf.PutChar( version );
		buf.PutShort( pcount );
	}

	// phoneme
	if ( version == CACHED_SENTENCE_VERSION_ALIGNED )
	{
		for ( i = 0; i < pcount; ++i )
		{
			const CBasePhonemeTag *phoneme = GetRuntimePhoneme( i );
			Assert( phoneme );
			buf.PutInt( phoneme->GetPhonemeCode() );
			buf.PutFloat( phoneme->GetStartTime() );
			buf.PutFloat( phoneme->GetEndTime() );
		}
	}
	else
	{
		for ( i = 0; i < pcount; ++i )
		{
			const CBasePhonemeTag *phoneme = GetRuntimePhoneme( i );
			Assert( phoneme );
			buf.PutShort( phoneme->GetPhonemeCode() );
			buf.PutFloat( phoneme->GetStartTime() );
			buf.PutFloat( phoneme->GetEndTime() );
		}
	}

	// emphasis samples and voice duck
	int c = m_EmphasisSamples.Count();
	Assert( c <= 32767 );

	if ( version == CACHED_SENTENCE_VERSION_ALIGNED )
	{
		buf.PutInt( c );
		for ( i = 0; i < c; i++ )
		{
			CEmphasisSample *sample = &m_EmphasisSamples[i];
			Assert( sample );
			buf.PutFloat( sample->time );
			buf.PutFloat( sample->value );
		}
		buf.PutInt( GetVoiceDuck() ? 1 : 0 );
	}
	else
	{
		buf.PutShort( c );
		for ( i = 0; i < c; i++ )
		{
			CEmphasisSample *sample = &m_EmphasisSamples[i];
			Assert( sample );
			buf.PutFloat( sample->time );
			short scaledValue = clamp( (short)( sample->value * 32767 ), (short)0, (short)32767 );
			buf.PutShort( scaledValue );
		}
		buf.PutChar( GetVoiceDuck() ? 1 : 0 );
	}
}
//-----------------------------------------------------------------------------
// Purpose: Finds the value of a particular server variable
//-----------------------------------------------------------------------------
bool CServerRemoteAccess::LookupValue(const char *variable, CUtlBuffer &value)
{
	Assert(value.IsText());

	// first see if it's a cvar
	const char *strval = LookupStringValue(variable);
	if (strval)
	{
		value.PutString(strval);
		value.PutChar(0);
	}
	else if (!stricmp(variable, "stats"))
	{
		char stats[512];
		GetStatsString(stats, sizeof(stats));
		value.PutString(stats);
		value.PutChar(0);
	}
	else if (!stricmp(variable, "banlist"))
	{
		// returns a list of banned users and ip's
		GetUserBanList(value);
	}
	else if (!stricmp(variable, "playerlist"))
	{
		GetPlayerList(value);		
	}
	else if (!stricmp(variable, "maplist"))
	{
		GetMapList(value);
	}
	else if (!stricmp(variable, "uptime"))
	{
		int timeSeconds = (int)(Plat_FloatTime());
		value.PutInt(timeSeconds);
		value.PutChar(0);
	}
	else if (!stricmp(variable, "ipaddress"))
	{
		char addr[25];
		Q_snprintf( addr, sizeof(addr), "%s:%i", net_local_adr.ToString(true), sv.GetUDPPort());
		value.PutString( addr );
		value.PutChar(0);
	}
	else if (!stricmp(variable, "mapcycle"))
	{
		ConVarRef mapcycle( "mapcyclefile" );
		if ( mapcycle.IsValid() )
		{
			// send the mapcycle list file
			FileHandle_t f = g_pFileSystem->Open(mapcycle.GetString(), "rb" );

			if ( f == FILESYSTEM_INVALID_HANDLE )
				return true;
			
			int len = g_pFileSystem->Size(f);
			char *mapcycleData = (char *)_alloca( len+1 );
			if ( len && g_pFileSystem->Read( mapcycleData, len, f ) )
			{
				mapcycleData[len] = 0; // Make sure it's null terminated.
				value.PutString((const char *)mapcycleData);
				value.PutChar(0);
			}
			else
			{
				value.PutString( "" );
				value.PutChar(0);
			}

			g_pFileSystem->Close( f );


		}
	}
	else
	{
		// value not found, null terminate
		value.PutChar(0);
		return false;
	}
	
	return true;
}
Esempio n. 16
0
bool KeyValues::WriteAsBinary(CUtlBuffer &buffer)
{
	if (buffer.IsText())
		return false;

	if (!buffer.IsValid())
		return false;

	for (KeyValues *dat = this; dat != NULL; dat = dat->m_pPeer)
	{
		buffer.PutUnsignedChar(dat->m_iDataType);
		buffer.PutString(dat->GetName());

		switch (dat->m_iDataType)
		{
			case TYPE_NONE:
			{
				dat->m_pSub->WriteAsBinary(buffer);
				break;
			}

			case TYPE_STRING:
			{
				if (dat->m_sValue && *(dat->m_sValue))
				{
					buffer.PutString(dat->m_sValue);
				}
				else
				{
					buffer.PutString("");
				}

				break;
			}

			case TYPE_WSTRING:
			{
				Assert(!"TYPE_WSTRING");
				break;
			}

			case TYPE_INT:
			{
				buffer.PutInt(dat->m_iValue);
				break;
			}

			case TYPE_UINT64:
			{
				buffer.PutDouble(*((double *)dat->m_sValue));
				break;
			}

			case TYPE_FLOAT:
			{
				buffer.PutFloat(dat->m_flValue);
				break;
			}

			case TYPE_COLOR:
			{
				buffer.PutUnsignedChar(dat->m_Color[0]);
				buffer.PutUnsignedChar(dat->m_Color[1]);
				buffer.PutUnsignedChar(dat->m_Color[2]);
				buffer.PutUnsignedChar(dat->m_Color[3]);
				break;
			}

			case TYPE_PTR:
			{
				buffer.PutUnsignedInt((int)dat->m_pValue);
			}

			default:
			{
				break;
			}
		}
	}

	buffer.PutUnsignedChar(TYPE_NUMTYPES); 
	return buffer.IsValid();
}
Esempio n. 17
0
bool CServerRemoteAccess::LookupValue(const char *variable, CUtlBuffer &value)
{
	const char* strval = LookupStringValue(variable);
	if (strval)
	{
		value.PutString(strval);
		value.PutChar(0);
		return true;
	}

	if (!Q_stricmp(variable, "stats"))
	{
		char stats[512];
		GetStatsString(stats, sizeof(stats));
		value.PutString(stats);
		value.PutChar(0);
		return true;
	}

	if (!Q_stricmp(variable, "banlist"))
	{
		GetUserBanList(value);
		return true;
	}

	if (!Q_stricmp(variable, "playerlist"))
	{
		GetPlayerList(value);
		return true;
	}

	if (!Q_stricmp(variable, "maplist"))
	{
		GetMapList(value);
		return true;
	}

	if (!Q_stricmp(variable, "uptime"))
	{
		value.PutInt(int(Sys_FloatTime() - Host_GetStartTime()));
		value.PutChar(0);
		return true;
	}

	if (!Q_stricmp(variable, "ipaddress"))
	{
		value.PutString(NET_AdrToString(net_local_adr));
		value.PutChar(0);
		return true;
	}

	if (!Q_stricmp(variable, "mapcycle"))
	{
		int len;
		void* mapcyclelist = COM_LoadFileForMe(mapcyclefile.string, &len);
		if (mapcyclelist && len)
		{
			value.PutString((char*)mapcyclelist);
			value.PutChar(0);
			COM_FreeFile(mapcyclelist);
		}
		return true;
	}

	value.PutChar(0);
	return false;
}
Esempio n. 18
0
void VMPI_DistributeLightData()
{
	if ( !g_bUseMPI )
		return;

	if ( g_bMPIMaster )
	{
		const char *pVirtualFilename = "--plightdata--";
		
		CUtlBuffer lightFaceData;

		// write out the light data
		lightFaceData.EnsureCapacity( pdlightdata->Count() + (numfaces * (MAXLIGHTMAPS+sizeof(int))) );
		Q_memcpy( lightFaceData.PeekPut(), pdlightdata->Base(), pdlightdata->Count() );
		lightFaceData.SeekPut( CUtlBuffer::SEEK_HEAD, pdlightdata->Count() );

		// write out the relevant face info into the stream
		for ( int i = 0; i < numfaces; i++ )
		{
			for ( int j = 0; j < MAXLIGHTMAPS; j++ )
			{
				lightFaceData.PutChar(g_pFaces[i].styles[j]);
			}
			lightFaceData.PutInt(g_pFaces[i].lightofs);
		}
		VMPI_FileSystem_CreateVirtualFile( pVirtualFilename, lightFaceData.Base(), lightFaceData.TellMaxPut() );

		char cPacketID[2] = { VMPI_VRAD_PACKET_ID, VMPI_SUBPACKETID_PLIGHTDATA_RESULTS };
		VMPI_Send2Chunks( cPacketID, sizeof( cPacketID ), pVirtualFilename, strlen( pVirtualFilename ) + 1, VMPI_PERSISTENT );
	}
	else
	{
		VMPI_SetCurrentStage( "VMPI_DistributeLightData" );

		// Wait until we've received the filename from the master.
		while ( g_LightResultsFilename.Count() == 0 )
		{
			VMPI_DispatchNextMessage();
		}

		// Open 
		FileHandle_t fp = g_pFileSystem->Open( g_LightResultsFilename.Base(), "rb", VMPI_VIRTUAL_FILES_PATH_ID );
		if ( !fp )
			Error( "Can't open '%s' to read lighting info.", g_LightResultsFilename.Base() );

		int size = g_pFileSystem->Size( fp );
		int faceSize = (numfaces*(MAXLIGHTMAPS+sizeof(int)));

		if ( size > faceSize )
		{
			int lightSize = size - faceSize;
			CUtlBuffer faceData;
			pdlightdata->EnsureCount( lightSize );
			faceData.EnsureCapacity( faceSize );

			g_pFileSystem->Read( pdlightdata->Base(), lightSize, fp );
			g_pFileSystem->Read( faceData.Base(), faceSize, fp );
			g_pFileSystem->Close( fp );

			faceData.SeekPut( CUtlBuffer::SEEK_HEAD, faceSize );

			// write out the face data
			for ( int i = 0; i < numfaces; i++ )
			{
				for ( int j = 0; j < MAXLIGHTMAPS; j++ )
				{
					g_pFaces[i].styles[j] = faceData.GetChar();
				}
				g_pFaces[i].lightofs = faceData.GetInt();
			}
		}
	}
}
Esempio n. 19
0
void WritePHXFile( const char *pName, const phyfile_t &file )
{
	if ( file.header.size != sizeof(file.header) || file.collide.solidCount <= 0 )
		return;

	CUtlBuffer out;

	char outName[1024];
	Q_snprintf( outName, sizeof(outName), "%s", pName );
	Q_SetExtension( outName, ".phx", sizeof(outName) );

	simplifyparams_t params;
	params.Defaults();
	params.tolerance = (file.collide.solidCount > 1) ? 4.0f : 2.0f;
	// single solids constraint to AABB for placement help
	params.addAABBToSimplifiedHull = (file.collide.solidCount == 1) ? true : false;
	params.mergeConvexElements = true;
	params.mergeConvexTolerance = 0.025f;
	Q_FixSlashes(outName);
	Q_strlower(outName);
	char *pSearch = Q_strstr( outName,"models\\" );
	if ( pSearch )
	{
		char keyname[1024];
		pSearch += strlen("models\\");
		Q_StripExtension( pSearch, keyname, sizeof(keyname) );
		OverrideDefaultsForModel( keyname, params );
	}
	out.Put( &file.header, sizeof(file.header) );
	int outSize = 0;
	bool bStoreSolidNames = file.collide.solidCount > 1 ? true : false;
	bStoreSolidNames = bStoreSolidNames || HasMultipleBones(outName);

	vcollide_t *pNewCollide = ConvertVCollideToPHX( &file.collide, params, &outSize, false, bStoreSolidNames);
	g_TotalOut += file.fileSize;
	for ( int i = 0; i < pNewCollide->solidCount; i++ )
	{
		int collideSize = physcollision->CollideSize( pNewCollide->solids[i] );
		out.PutInt( collideSize );
		char *pMem = new char[collideSize];
		physcollision->CollideWrite( pMem, pNewCollide->solids[i] );
		out.Put( pMem, collideSize );
		delete[] pMem;
	}

	if (!g_bQuiet)
	{
		Msg("%s Compressed %d (%d text) to %d (%d text)\n", outName, file.fileSize, file.collide.descSize, out.TellPut(), pNewCollide->descSize );
	}
	out.Put( pNewCollide->pKeyValues, pNewCollide->descSize );
	g_TotalCompress += out.TellPut();

#if 0
	//Msg("OLD:\n-----------------------------------\n%s\n", file.collide.pKeyValues );
	CPackedPhysicsDescription *pPacked = physcollision->CreatePackedDesc( pNewCollide->pKeyValues, pNewCollide->descSize );
	Msg("NEW:\n-----------------------------------\n" );
	for ( int i = 0; i < pPacked->m_solidCount; i++ )
	{
		solid_t solid;
		pPacked->GetSolid( &solid, i );
		Msg("index %d\n", solid.index );
		Msg("name %s\n", solid.name );
		Msg("mass %.2f\n", solid.params.mass );
		Msg("surfaceprop %s\n", solid.surfaceprop);
		Msg("damping %.2f\n", solid.params.damping );
		Msg("rotdamping %.2f\n", solid.params.rotdamping );
		Msg("drag %.2f\n", solid.params.dragCoefficient );
		Msg("inertia %.2f\n", solid.params.inertia );
		Msg("volume %.2f\n", solid.params.volume );
	}
#endif
	DestroyPHX( pNewCollide );
	if ( !g_pFullFileSystem->WriteFile( outName, NULL, out ) )
		Warning("Can't write file: %s\n", outName );
}
Esempio n. 20
0
//-----------------------------------------------------------------------------
// A Scene image file contains all the compiled .XCD
//-----------------------------------------------------------------------------
bool CSceneImage::CreateSceneImageFile( CUtlBuffer &targetBuffer, char const *pchModPath, bool bLittleEndian, bool bQuiet, ISceneCompileStatus *pStatus )
{
	CUtlVector<fileList_t>	vcdFileList;
	CUtlSymbolTable			vcdSymbolTable( 0, 32, true );

	Msg( "\n" );

	// get all the VCD files according to the seacrh paths
	char searchPaths[512];
	g_pFullFileSystem->GetSearchPath( "GAME", false, searchPaths, sizeof( searchPaths ) );
	char *pPath = strtok( searchPaths, ";" );
	while ( pPath )
	{
		int currentCount = vcdFileList.Count();

		char szPath[MAX_PATH];
		V_ComposeFileName( pPath, "scenes/*.vcd", szPath, sizeof( szPath ) );

		scriptlib->FindFiles( szPath, true, vcdFileList );

		Msg( "Scenes: Searching '%s' - Found %d scenes.\n", szPath, vcdFileList.Count() - currentCount );

		pPath = strtok( NULL, ";" );
	}

	if ( !vcdFileList.Count() )
	{
		Msg( "Scenes: No Scene Files found!\n" );
		return false;
	}

	// iterate and convert all the VCD files
	bool bGameIsTF = V_stristr( pchModPath, "\\tf" ) != NULL;
	for ( int i=0; i<vcdFileList.Count(); i++ )
	{
		const char *pFilename = vcdFileList[i].fileName.String();
		const char *pSceneName = V_stristr( pFilename, "scenes\\" );
		if ( !pSceneName )
		{
			continue;
		}

		if ( !bLittleEndian && bGameIsTF && V_stristr( pSceneName, "high\\" ) )
		{
			continue;
		}

		// process files in order they would be found in search paths
		// i.e. skipping later processed files that match an earlier conversion
		UtlSymId_t symbol = vcdSymbolTable.Find( pSceneName );
		if ( symbol == UTL_INVAL_SYMBOL )
		{
			vcdSymbolTable.AddString( pSceneName );

			pStatus->UpdateStatus( pFilename, bQuiet, i, vcdFileList.Count() );

			if ( !CreateTargetFile_VCD( pFilename, "", false, bLittleEndian ) )
			{
				Error( "CreateSceneImageFile: Failed on '%s' conversion!\n", pFilename );
			}


		}
	}

	if ( !g_SceneFiles.Count() )
	{
		// nothing to do
		return true;
	}

	Msg( "Scenes: Finalizing %d unique scenes.\n", g_SceneFiles.Count() );


	// get the string pool
	CUtlVector< unsigned int > stringOffsets;
	CUtlBuffer stringPool;
	g_ChoreoStringPool.GetTableAndPool( stringOffsets, stringPool );

	if ( !bQuiet )
	{
		Msg( "Scenes: String Table: %d bytes\n", stringOffsets.Count() * sizeof( int ) );
		Msg( "Scenes: String Pool: %d bytes\n", stringPool.TellMaxPut() );
	}

	// first header, then lookup table, then string pool blob
	int stringPoolStart = sizeof( SceneImageHeader_t ) + stringOffsets.Count() * sizeof( int );
	// then directory
	int sceneEntryStart = stringPoolStart + stringPool.TellMaxPut();
	// then variable sized summaries
	int sceneSummaryStart = sceneEntryStart + g_SceneFiles.Count() * sizeof( SceneImageEntry_t );
	// then variable sized compiled binary scene data
	int sceneDataStart = 0;

	// construct header
	SceneImageHeader_t imageHeader = { 0 };
	imageHeader.nId = SCENE_IMAGE_ID;
	imageHeader.nVersion = SCENE_IMAGE_VERSION;
	imageHeader.nNumScenes = g_SceneFiles.Count();
	imageHeader.nNumStrings = stringOffsets.Count();
	imageHeader.nSceneEntryOffset = sceneEntryStart;
	if ( !bLittleEndian )
	{
		imageHeader.nId = BigLong( imageHeader.nId );
		imageHeader.nVersion = BigLong( imageHeader.nVersion );
		imageHeader.nNumScenes = BigLong( imageHeader.nNumScenes );
		imageHeader.nNumStrings = BigLong( imageHeader.nNumStrings );
		imageHeader.nSceneEntryOffset = BigLong( imageHeader.nSceneEntryOffset );
	}
	targetBuffer.Put( &imageHeader, sizeof( imageHeader ) );

	// header is immediately followed by string table and pool
	for ( int i = 0; i < stringOffsets.Count(); i++ )
	{
		unsigned int offset = stringPoolStart + stringOffsets[i];
		if ( !bLittleEndian )
		{
			offset = BigLong( offset );
		}
		targetBuffer.PutInt( offset );
	}
	Assert( stringPoolStart == targetBuffer.TellMaxPut() );
	targetBuffer.Put( stringPool.Base(), stringPool.TellMaxPut() );

	// construct directory
	CUtlSortVector< SceneImageEntry_t, CSceneImageEntryLessFunc > imageDirectory;
	imageDirectory.EnsureCapacity( g_SceneFiles.Count() );

	// build directory
	// directory is linear sorted by filename checksum for later binary search
	for ( int i = 0; i < g_SceneFiles.Count(); i++ )
	{
		SceneImageEntry_t imageEntry = { 0 };

		// name needs to be normalized for determinstic later CRC name calc
		// calc crc based on scenes\anydir\anyscene.vcd
		char szCleanName[MAX_PATH];
		V_strncpy( szCleanName, g_SceneFiles[i].fileName.String(), sizeof( szCleanName ) );
		V_strlower( szCleanName );
		V_FixSlashes( szCleanName );
		char *pName = V_stristr( szCleanName, "scenes\\" );
		if ( !pName )
		{
			// must have scenes\ in filename
			Error( "CreateSceneImageFile: Unexpected lack of scenes prefix on %s\n", g_SceneFiles[i].fileName.String() );
		}

		CRC32_t crcFilename = CRC32_ProcessSingleBuffer( pName, strlen( pName ) );
		imageEntry.crcFilename = crcFilename;

		// temp store an index to its file, fixup later, necessary to access post sort
		imageEntry.nDataOffset = i;
		if ( imageDirectory.Find( imageEntry ) != imageDirectory.InvalidIndex() )
		{
			// filename checksums must be unique or runtime binary search would be bogus
			Error( "CreateSceneImageFile: Unexpected filename checksum collision!\n" );
		}		

		imageDirectory.Insert( imageEntry );
	}

	// determine sort order and start of data after dynamic summaries
	CUtlVector< int > writeOrder;
	writeOrder.EnsureCapacity( g_SceneFiles.Count() );
	sceneDataStart = sceneSummaryStart;
	for ( int i = 0; i < imageDirectory.Count(); i++ )
	{
		// reclaim offset, indicates write order of scene file
		int iScene = imageDirectory[i].nDataOffset;
		writeOrder.AddToTail( iScene );

		// march past each variable sized summary to determine start of scene data
		int numSounds = g_SceneFiles[iScene].soundList.Count();
		sceneDataStart += sizeof( SceneImageSummary_t ) + ( numSounds - 1 ) * sizeof( int );
	}

	// finalize and write directory
	Assert( sceneEntryStart == targetBuffer.TellMaxPut() );
	int nSummaryOffset = sceneSummaryStart;
	int nDataOffset = sceneDataStart;
	for ( int i = 0; i < imageDirectory.Count(); i++ )
	{
		int iScene = writeOrder[i];

		imageDirectory[i].nDataOffset = nDataOffset;
		imageDirectory[i].nDataLength = g_SceneFiles[iScene].compiledBuffer.TellMaxPut();
		imageDirectory[i].nSceneSummaryOffset = nSummaryOffset;
		if ( !bLittleEndian )
		{
			imageDirectory[i].crcFilename = BigLong( imageDirectory[i].crcFilename );
			imageDirectory[i].nDataOffset = BigLong( imageDirectory[i].nDataOffset );
			imageDirectory[i].nDataLength = BigLong( imageDirectory[i].nDataLength );
			imageDirectory[i].nSceneSummaryOffset = BigLong( imageDirectory[i].nSceneSummaryOffset );
		}
		targetBuffer.Put( &imageDirectory[i], sizeof( SceneImageEntry_t ) );

		int numSounds = g_SceneFiles[iScene].soundList.Count();
		nSummaryOffset += sizeof( SceneImageSummary_t ) + (numSounds - 1) * sizeof( int );

		nDataOffset += g_SceneFiles[iScene].compiledBuffer.TellMaxPut();
	}

	// finalize and write summaries
	Assert( sceneSummaryStart == targetBuffer.TellMaxPut() );
	for ( int i = 0; i < imageDirectory.Count(); i++ )
	{
		int iScene = writeOrder[i];
		int msecs = g_SceneFiles[iScene].msecs;
		int soundCount = g_SceneFiles[iScene].soundList.Count();
		if ( !bLittleEndian )
		{
			msecs = BigLong( msecs );
			soundCount = BigLong( soundCount );
		}
		targetBuffer.PutInt( msecs );
		targetBuffer.PutInt( soundCount );
		for ( int j = 0; j < g_SceneFiles[iScene].soundList.Count(); j++ )
		{
			int soundId = g_SceneFiles[iScene].soundList[j];
			if ( !bLittleEndian )
			{
				soundId = BigLong( soundId );
			}
			targetBuffer.PutInt( soundId );
		}
	}

	// finalize and write data
	Assert( sceneDataStart == targetBuffer.TellMaxPut() );
	for ( int i = 0; i < imageDirectory.Count(); i++ )
	{	
		int iScene = writeOrder[i];
		targetBuffer.Put( g_SceneFiles[iScene].compiledBuffer.Base(), g_SceneFiles[iScene].compiledBuffer.TellMaxPut() );
	}

	if ( !bQuiet )
	{
		Msg( "Scenes: Final size: %.2f MB\n", targetBuffer.TellMaxPut() / (1024.0f * 1024.0f ) );
	}

	// cleanup
	g_SceneFiles.Purge();

	return true;
}