Ejemplo n.º 1
0
		SPtr<SndPlayer>	ovSndPlayer::load(const wcs& filepath,int buffers)
		{
			buffers = max(buffers, 2);

			SMem sm;
			if(!FileSystem::loadFromAll(filepath, sm))
				return NULL;

			ov_callbacks callbacks;
			callbacks.read_func = read_ov;
			callbacks.seek_func = seek_ov;
			callbacks.close_func = close_ov;
			callbacks.tell_func = tell_ov;

			OggVorbis_File* ov_file = new OggVorbis_File;

			MemReader reader(sm.get(), sm.size());

			if(ov_open_callbacks(&reader, ov_file, NULL, 0, callbacks) < 0)
			{
				delete ov_file;

				return NULL;
			}

			vorbis_info* info = ov_info(ov_file, -1);
			vorbis_comment* comment = ov_comment(ov_file, -1);

			ALenum format;

			if(info->channels == 1)
				format = AL_FORMAT_MONO16;
			else if(info->channels == 2)
				format = AL_FORMAT_STEREO16;
			else
			{
				ov_clear(ov_file);
				delete ov_file;

				return NULL;
			}

			unsigned int source_name = Oal::current()->genSource();

			ovSndPlayer* player = new ovSndPlayer(source_name);
			player->_filemem = sm;
			player->_file = MemReader(sm.get(), sm.size());
			ov_file->datasource = &player->_file;
			player->_ov_file = (void*)ov_file;
			player->_ov_info = (void*)info;
			player->_ov_comment = (void*)comment;
			player->_format = format;
			player->_array_buffer.resize(buffers);
			for(int i = 0; i < buffers; ++i)
				player->_array_buffer[i] = new SndBuf(L"", Oal::current()->genBuffer());
			player->_buffer.resize(info->rate);
			//player->_buffer.resize(info->rate * 2 * 2 / 2);

			return SPtr<SndPlayer>(player);
		}
Ejemplo n.º 2
0
bool UGame::LoadFromRecord(const FGameRecord& InRecord)
{
	Init();

	if ( ObjectTree->LoadFromRecord( InRecord.ObjectTreeRecord ) == false )
	{
		return false;
	}

	FMemoryReader MemReader( InRecord.ByteData );
	FSaveGameArchive Ar( MemReader );
	this->Serialize( Ar );

	OnLoadedFromRecord();
	BPF_OnLoadedFromRecord();

	return true;
}
void FBuildPatchChunkCache::AddDataToCache( const FGuid& ChunkGuid, const TArray< uint8 >& ChunkDataFile )
{
	// Must never double acquire
	check( ChunkCache.Contains( ChunkGuid ) == false );

	// Create the ChunkFile data structure
	FChunkFile* NewChunkFile = new FChunkFile( GetRemainingReferenceCount( ChunkGuid ), false );

	// Lock data
	FChunkHeader* ChunkHeader;
	uint8* ChunkData;
	NewChunkFile->GetDataLock( &ChunkData, &ChunkHeader );

	// Copy the data
	FMemoryReader MemReader( ChunkDataFile );
	MemReader << *ChunkHeader;
	MemReader.Serialize( ChunkData, FBuildPatchData::ChunkDataSize );

	// Release data
	NewChunkFile->ReleaseDataLock();

	// Add it to our cache.
	ChunkCache.Add( ChunkGuid, NewChunkFile );
}
Ejemplo n.º 4
0
void RecompileShadersForRemote( 
	const FString& PlatformName,
	EShaderPlatform ShaderPlatformToCompile,
	const FString& OutputDirectory, 
	const TArray<FString>& MaterialsToLoad, 
	const TArray<uint8>& SerializedShaderResources, 
	TArray<uint8>* MeshMaterialMaps, 
	TArray<FString>* ModifiedFiles,
	bool bCompileChangedShaders )
{
	// figure out what shader platforms to recompile
	ITargetPlatformManagerModule* TPM = GetTargetPlatformManager();
	ITargetPlatform* TargetPlatform = TPM->FindTargetPlatform(PlatformName);
	if (TargetPlatform == NULL)
	{
		UE_LOG(LogShaders, Display, TEXT("Failed to find target platform module for %s"), *PlatformName);
		return;
	}

	TArray<FName> DesiredShaderFormats;
	TargetPlatform->GetAllTargetedShaderFormats(DesiredShaderFormats);

	UE_LOG(LogShaders, Display, TEXT("Loading %d materials..."), MaterialsToLoad.Num());
	// make sure all materials the client has loaded will be processed
	TArray<UMaterialInterface*> MaterialsToCompile;

	for (int32 Index = 0; Index < MaterialsToLoad.Num(); Index++)
	{
		UE_LOG(LogShaders, Display, TEXT("   --> %s"), *MaterialsToLoad[Index]);
		MaterialsToCompile.Add(LoadObject<UMaterialInterface>(NULL, *MaterialsToLoad[Index]));
	}

	UE_LOG(LogShaders, Display, TEXT("  Done!"))

	// figure out which shaders are out of date
	TArray<FShaderType*> OutdatedShaderTypes;
	TArray<const FVertexFactoryType*> OutdatedFactoryTypes;

	// Pick up new changes to shader files
	FlushShaderFileCache();

	if( bCompileChangedShaders )
	{
		FShaderType::GetOutdatedTypes( OutdatedShaderTypes, OutdatedFactoryTypes );
		UE_LOG( LogShaders, Display, TEXT( "We found %d out of date shader types, and %d out of date VF types!" ), OutdatedShaderTypes.Num(), OutdatedFactoryTypes.Num() );
	}

	{
		for (int32 FormatIndex = 0; FormatIndex < DesiredShaderFormats.Num(); FormatIndex++)
		{
			// get the shader platform enum
			const EShaderPlatform ShaderPlatform = ShaderFormatToLegacyShaderPlatform(DesiredShaderFormats[FormatIndex]);

			// Only compile for the desired platform if requested
			if (ShaderPlatform == ShaderPlatformToCompile || ShaderPlatformToCompile == SP_NumPlatforms)
			{
				if( bCompileChangedShaders )
				{
					// Kick off global shader recompiles
					BeginRecompileGlobalShaders( OutdatedShaderTypes, ShaderPlatform );

					// Block on global shaders
					FinishRecompileGlobalShaders();
				}

				// we only want to actually compile mesh shaders if a client directly requested it, and there's actually some work to do
				if (MeshMaterialMaps != NULL && (OutdatedShaderTypes.Num() || OutdatedFactoryTypes.Num() || bCompileChangedShaders == false))
				{
					TMap<FString, TArray<TRefCountPtr<FMaterialShaderMap> > > CompiledShaderMaps;
					UMaterial::CompileMaterialsForRemoteRecompile(MaterialsToCompile, ShaderPlatform, CompiledShaderMaps);

					// write the shader compilation info to memory, converting fnames to strings
					FMemoryWriter MemWriter(*MeshMaterialMaps, true);
					FNameAsStringProxyArchive Ar(MemWriter);

					// pull the serialized resource ids into an array of resources
					TArray<FShaderResourceId> ClientResourceIds;
					FMemoryReader MemReader(SerializedShaderResources, true);
					MemReader << ClientResourceIds;

					// save out the shader map to the byte array
					FMaterialShaderMap::SaveForRemoteRecompile(Ar, CompiledShaderMaps, ClientResourceIds);
				}

				// save it out so the client can get it (and it's up to date next time)
				FString GlobalShaderFilename = SaveGlobalShaderFile(ShaderPlatform, OutputDirectory);

				// add this to the list of files to tell the other end about
				if (ModifiedFiles)
				{
					// need to put it in non-sandbox terms
					FString SandboxPath(GlobalShaderFilename);
					check(SandboxPath.StartsWith(OutputDirectory));
					SandboxPath.ReplaceInline(*OutputDirectory, TEXT("../../../"));
					FPaths::NormalizeFilename(SandboxPath);
					ModifiedFiles->Add(SandboxPath);
				}
			}
		}
	}
}
bool FBuildPatchChunkCache::RecycleChunkFromBuild( const FGuid& ChunkGuid )
{
	// Must never double acquire
	check( ChunkCache.Contains( ChunkGuid ) == false );

	// Debug leaving any files open
	bool bSuccess = true;

	// Get the app manifest that this chunk can be sourced from
	FBuildPatchAppManifestPtr ChunkSourceAppManifest = InstallationInfo.GetManifestContainingChunk(ChunkGuid);
	if (!ChunkSourceAppManifest.IsValid())
	{
		return false;
	}

	// Get the install directory for this manifest
	const FString ChunkSourceInstallDir = InstallationInfo.GetManifestInstallDir(ChunkSourceAppManifest);
	if(ChunkSourceInstallDir.Len() <= 0)
	{
		return false;
	}

	// We need to generate an inventory of all chunk parts in this build that refer to the chunk that we require
	TMap< FGuid, TArray< FFileChunkPart > > ChunkPartInventory;
	TArray< FGuid > Array;
	Array.Add( ChunkGuid );
	ChunkSourceAppManifest->EnumerateChunkPartInventory(Array, ChunkPartInventory);

	// Attempt construction of the chunk from the parts
	FArchive* BuildFileIn = NULL;
	FString  BuildFileOpened;
	int64 BuildFileInSize = 0;

	// We must have a hash for this chunk or else we cant verify it
	uint8 HashType = 0;
	uint64 ChunkHash = 0;
	FSHAHashData ChunkShaHash;
	if (InstallManifet->GetChunkShaHash(ChunkGuid, ChunkShaHash))
	{
		HashType = FChunkHeader::HASH_SHA1;
	}
	else if (ChunkSourceAppManifest->GetChunkHash(ChunkGuid, ChunkHash))
	{
		HashType = FChunkHeader::HASH_ROLLING;
	}
	TArray< FFileChunkPart >* FileChunkPartsPtr = ChunkPartInventory.Find( ChunkGuid );
	bSuccess = (FileChunkPartsPtr != NULL && HashType != 0);
	if( bSuccess )
	{
		const TArray< FFileChunkPart >& FileChunkParts = *FileChunkPartsPtr;
		TArray< uint8 > TempArray;
		TempArray.AddUninitialized( FBuildPatchData::ChunkDataSize );
		uint8* TempChunkConstruction = TempArray.GetData();
		FMemory::Memzero( TempChunkConstruction, FBuildPatchData::ChunkDataSize );
		bSuccess = FileChunkParts.Num() > 0;
		for( auto FileChunkPartIt = FileChunkParts.CreateConstIterator(); FileChunkPartIt && bSuccess && !FBuildPatchInstallError::HasFatalError(); ++FileChunkPartIt )
		{
			const FFileChunkPart& FileChunkPart = *FileChunkPartIt;
			FString FullFilename = ChunkSourceInstallDir / FileChunkPart.Filename;
			// Close current build file ?
			if( BuildFileIn != NULL && BuildFileOpened != FullFilename )
			{
				BuildFileIn->Close();
				delete BuildFileIn;
				BuildFileIn = NULL;
				BuildFileOpened = TEXT( "" );
				BuildFileInSize = 0;
			}
			// Open build file ?
			if( BuildFileIn == NULL )
			{
				BuildFileIn = IFileManager::Get().CreateFileReader( *FullFilename );
				bSuccess = BuildFileIn != NULL;
				if( !bSuccess )
				{
					BuildFileOpened = TEXT( "" );
					FBuildPatchAnalytics::RecordChunkCacheError( ChunkGuid, FileChunkPart.Filename, FPlatformMisc::GetLastError(), TEXT( "ChunkRecycle" ), TEXT( "Source File Missing" ) );
					GWarn->Logf( TEXT( "BuildPatchChunkConstruction: Warning: Failed to load source file for chunk. %s" ), *FullFilename );
				}
				else
				{
					BuildFileOpened = FullFilename;
					BuildFileInSize = BuildFileIn->TotalSize();
				}
			}
			// Grab the section of the chunk
			if( BuildFileIn != NULL )
			{
				// Make sure we don't attempt to read off the end of the file
				const int64 LastRequiredByte = FileChunkPart.FileOffset + FileChunkPart.ChunkPart.Size;
				if( BuildFileInSize >= LastRequiredByte )
				{
					BuildFileIn->Seek( FileChunkPart.FileOffset );
					BuildFileIn->Serialize( TempChunkConstruction + FileChunkPart.ChunkPart.Offset, FileChunkPart.ChunkPart.Size );
				}
				else
				{
					bSuccess = false;
					FBuildPatchAnalytics::RecordChunkCacheError( ChunkGuid, FileChunkPart.Filename, INDEX_NONE, TEXT( "ChunkRecycle" ), TEXT( "Source File Too Small" ) );
					GWarn->Logf( TEXT( "BuildPatchChunkConstruction: Warning: Source file too small for chunk position. %s" ), *FullFilename );
				}
			}
		}

		// Check no other fatal errors were registered in the meantime
		bSuccess = bSuccess && !FBuildPatchInstallError::HasFatalError();

		// Check chunk hash
		if( bSuccess )
		{
			FSHAHashData ShaHashCheck;
			switch (HashType)
			{
			case FChunkHeader::HASH_ROLLING:
				bSuccess = FRollingHash< FBuildPatchData::ChunkDataSize >::GetHashForDataSet(TempChunkConstruction) == ChunkHash;
				break;
			case FChunkHeader::HASH_SHA1:
				FSHA1::HashBuffer(TempChunkConstruction, FBuildPatchData::ChunkDataSize, ShaHashCheck.Hash);
				bSuccess = ShaHashCheck == ChunkShaHash;
				break;
			default:
				bSuccess = false;
			}
			if( !bSuccess )
			{
				FBuildPatchAnalytics::RecordChunkCacheError( ChunkGuid, TEXT( "" ), INDEX_NONE, TEXT( "ChunkRecycle" ), TEXT( "Chunk Hash Fail" ) );
				GWarn->Logf( TEXT( "BuildPatchChunkConstruction: Warning: Hash check failed for recycled chunk %s" ), *ChunkGuid.ToString() );
			}
		}

		// Save the chunk to cache if all went well
		if( bSuccess )
		{
			// It was added asynchronously!!
			check( ChunkCache.Contains( ChunkGuid ) == false );

			// Create the ChunkFile data structure
			FChunkFile* NewChunkFile = new FChunkFile( GetRemainingReferenceCount( ChunkGuid ), true );

			// Lock data
			FChunkHeader* ChunkHeader;
			uint8* ChunkData;
			NewChunkFile->GetDataLock( &ChunkData, &ChunkHeader );

			// Copy the data
			FMemoryReader MemReader( TempArray );
			MemReader.Serialize( ChunkData, FBuildPatchData::ChunkDataSize );

			// Setup the header
			ChunkHeader->Guid = ChunkGuid;
			ChunkHeader->StoredAs = FChunkHeader::STORED_RAW;
			ChunkHeader->DataSize = FBuildPatchData::ChunkDataSize; // This would change if compressing/encrypting
			ChunkHeader->HashType = HashType;
			ChunkHeader->RollingHash = ChunkHash;
			ChunkHeader->SHAHash = ChunkShaHash;

			// Release data
			NewChunkFile->ReleaseDataLock();

			// Count chunk
			NumChunksRecycled.Increment();

			// Add it to our cache.
			ChunkCache.Add( ChunkGuid, NewChunkFile );
		}

		// Close any open file
		if( BuildFileIn != NULL )
		{
			BuildFileIn->Close();
			delete BuildFileIn;
			BuildFileIn = NULL;
		}
	}
	
	return bSuccess;
}