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); }
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 ); }
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; }