/// <summary> /// Replaces a resource with raw, pre-compressed data. /// </summary> /// <param name="resource">The resource whose data should be replaced. On success, the reference will be adjusted to account for the new data.</param> /// <param name="data">The raw, pre-compressed data to use.</param> public void ReplaceRawResource(PageableResource resource, byte[] data) { if (resource == null) { throw new ArgumentNullException("resource"); } resource.DisableChecksum(); var cache = GetResourceCache(resource); using (var stream = cache.File.Open(FileMode.Open, FileAccess.ReadWrite)) cache.Cache.ImportRaw(stream, resource.Page.Index, data); }
/// <summary> /// Adds raw, pre-compressed resource data to a cache. /// </summary> /// <param name="resource">The resource reference to initialize.</param> /// <param name="data">The pre-compressed data to store.</param> public void AddRawResource(PageableResource resource, byte[] data) { if (resource == null) { throw new ArgumentNullException("resource"); } resource.DisableChecksum(); var cache = GetResourceCache(resource, out var location); using (var stream = OpenCacheReadWrite(location)) resource.Page.Index = cache.AddRaw(stream, data); }
private TagResourceReference CreateResource <T>(T resourceDefinition, ResourceLocation location, TagResourceTypeGen3 resourceType) { var resourceReference = new TagResourceReference(); var pageableResource = new PageableResource(); pageableResource.Page = new ResourcePage(); pageableResource.Resource = new ResourceData(); pageableResource.ChangeLocation(location); pageableResource.Resource.Unknown2 = 1; pageableResource.Resource.ResourceType = resourceType; resourceReference.HaloOnlinePageableResource = pageableResource; var definitionStream = new MemoryStream(); var dataStream = new MemoryStream(); using (var definitionWriter = new EndianWriter(definitionStream, EndianFormat.LittleEndian)) using (var dataWriter = new EndianWriter(dataStream, EndianFormat.LittleEndian)) { var context = new ResourceDefinitionSerializationContext(dataWriter, definitionWriter, CacheAddressType.Definition); var serializer = new ResourceSerializer(Cache.Version); serializer.Serialize(context, resourceDefinition); var data = dataStream.ToArray(); var definitionData = definitionStream.ToArray(); dataStream.Position = 0; pageableResource.DisableChecksum(); dataStream.Position = 0; AddResource(pageableResource, dataStream); // add resource definition and fixups pageableResource.Resource.DefinitionData = definitionData; pageableResource.Resource.FixupLocations = context.FixupLocations; pageableResource.Resource.DefinitionAddress = context.MainStructOffset; pageableResource.Resource.InteropLocations = context.InteropLocations; } return(resourceReference); }
/// <summary> /// Compresses and replaces the data for a resource. /// </summary> /// <param name="resource">The resource whose data should be replaced. On success, the reference will be adjusted to account for the new data.</param> /// <param name="dataStream">The stream to read the new data from.</param> /// <exception cref="System.ArgumentException">Thrown if the input stream is not open for reading.</exception> public void ReplaceResource(PageableResource resource, Stream dataStream) { if (resource == null) { throw new ArgumentNullException("resource"); } if (!dataStream.CanRead) { throw new ArgumentException("The input stream is not open for reading", "dataStream"); } var cache = GetResourceCache(resource); using (var stream = cache.File.Open(FileMode.Open, FileAccess.ReadWrite)) { var dataSize = (int)(dataStream.Length - dataStream.Position); var data = new byte[dataSize]; dataStream.Read(data, 0, dataSize); var compressedSize = cache.Cache.Compress(stream, resource.Page.Index, data); resource.Page.CompressedBlockSize = compressedSize; resource.Page.UncompressedBlockSize = (uint)dataSize; resource.DisableChecksum(); } }
/// <summary> /// Adds a new pageable_resource to the current cache. /// </summary> /// <param name="resource">The pageable_resource to add.</param> /// <param name="dataStream">The stream to read the resource data from.</param> /// <exception cref="System.ArgumentNullException">resource</exception> /// <exception cref="System.ArgumentException">The input stream is not open for reading;dataStream</exception> public void AddResource(PageableResource resource, Stream dataStream) { if (resource == null) { throw new ArgumentNullException("resource"); } if (!dataStream.CanRead) { throw new ArgumentException("The input stream is not open for reading", "dataStream"); } var cache = GetResourceCache(resource, out var location); using (var stream = OpenCacheReadWrite(location)) { var dataSize = (int)(dataStream.Length - dataStream.Position); var data = new byte[dataSize]; dataStream.Read(data, 0, dataSize); resource.Page.Index = cache.Add(stream, data, out uint compressedSize); resource.Page.CompressedBlockSize = compressedSize; resource.Page.UncompressedBlockSize = (uint)dataSize; resource.DisableChecksum(); } }
private PageableResource ConvertBitmap(Bitmap bitmap, Dictionary <ResourceLocation, Stream> resourceStreams, int imageIndex, string tagName) { var image = bitmap.Images[imageIndex]; BaseBitmap baseBitmap = BitmapConverter.ConvertGen3Bitmap(BlamCache, bitmap, imageIndex, BlamCache.Version); if (baseBitmap == null) { return(null); } // fix type enum if (baseBitmap.Type == BitmapType.Array) { baseBitmap.Type = BitmapType.Texture3D; } SetTagData(baseBitmap, image); var dataSize = baseBitmap.Data.Length; var resource = new PageableResource { Page = new RawPage(), Resource = new TagResourceGen3 { ResourceFixups = new List <TagResourceGen3.ResourceFixup>(), ResourceDefinitionFixups = new List <TagResourceGen3.ResourceDefinitionFixup>(), ResourceType = TagResourceTypeGen3.Bitmap, Unknown2 = 1 } }; using (var dataStream = new MemoryStream(baseBitmap.Data)) { var bitmapResource = new Bitmap.BitmapResource { Resource = resource, Unknown4 = 0 }; var resourceContext = new ResourceSerializationContext(CacheContext, resource); // Create new definition var resourceDefinition = new BitmapTextureInteropResource { Texture = new TagStructureReference <BitmapTextureInteropResource.BitmapDefinition> { Definition = new BitmapTextureInteropResource.BitmapDefinition { Data = new TagData(), UnknownData = new TagData(), } } }; SetResourceDefinitionData(baseBitmap, image, resourceDefinition.Texture.Definition); // // Serialize the new resource definition // var location = bitmap.Usage == 2 ? ResourceLocation.TexturesB : // bump maps ResourceLocation.Textures; // everything else resource.ChangeLocation(location); if (resource == null) { throw new ArgumentNullException("resource"); } if (!dataStream.CanRead) { throw new ArgumentException("The input stream is not open for reading", "dataStream"); } var cache = CacheContext.GetResourceCache(location); if (!resourceStreams.ContainsKey(location)) { resourceStreams[location] = FlagIsSet(PortingFlags.Memory) ? new MemoryStream() : (Stream)CacheContext.OpenResourceCacheReadWrite(location); if (FlagIsSet(PortingFlags.Memory)) { using (var resourceStream = CacheContext.OpenResourceCacheRead(location)) resourceStream.CopyTo(resourceStreams[location]); } } dataSize = (int)(dataStream.Length - dataStream.Position); var data = new byte[dataSize]; dataStream.Read(data, 0, dataSize); resource.Page.Index = cache.Add(resourceStreams[location], data, out uint compressedSize); resource.Page.CompressedBlockSize = compressedSize; resource.Page.UncompressedBlockSize = (uint)dataSize; resource.DisableChecksum(); CacheContext.Serializer.Serialize(resourceContext, resourceDefinition); } return(resource); }