private static DdsHeader CreateDdsHeader(BitmapTextureInteropResource definition) { var info = definition.Texture.Definition; var result = new DdsHeader { Width = (uint)info.Width, Height = (uint)info.Height, MipMapCount = (uint)info.MipmapCount }; BitmapDdsFormatDetection.SetUpHeaderForFormat(info.Format, result); switch (info.Type) { case BitmapType.CubeMap: result.SurfaceComplexityFlags = DdsSurfaceComplexityFlags.Complex; result.SurfaceInfoFlags = DdsSurfaceInfoFlags.CubeMap | DdsSurfaceInfoFlags.CubeMapNegativeX | DdsSurfaceInfoFlags.CubeMapNegativeY | DdsSurfaceInfoFlags.CubeMapNegativeZ | DdsSurfaceInfoFlags.CubeMapPositiveX | DdsSurfaceInfoFlags.CubeMapPositiveY | DdsSurfaceInfoFlags.CubeMapPositiveZ; break; case BitmapType.Texture3D: result.Depth = (uint)info.Depth; result.SurfaceInfoFlags = DdsSurfaceInfoFlags.Volume; break; } const string dew = "Doritos(TM) Dew(TM) it right!"; Encoding.ASCII.GetBytes(dew, 0, dew.Length, result.Reserved, 0); return(result); }
public XboxBitmap(BitmapTextureInteropResource definition, Bitmap.Image image) : base(definition, image) { UpdateFormat(image.Format); MultipleOfBlockDimension = Width % BlockDimension == 0 && Height % BlockDimension == 0; NotExact = Width != VirtualWidth || Height != VirtualHeight; InTile = Width <= MinimalBitmapSize / 2 && Height <= MinimalBitmapSize / 2; Offset = 0; }
public BaseBitmap(BitmapTextureInteropResource definition, Bitmap.Image image) { var def = definition.Texture.Definition; Height = def.Height; Width = def.Width; Depth = def.Depth; MipMapCount = def.MipmapCount - 1; Type = def.Type; Flags = image.Flags; UpdateFormat(image.Format); }
private void ExtractResourceData(BitmapTextureInteropResource definition, Bitmap.BitmapResource resource, Stream outStream) { var dataReference = definition.Texture.Definition.Data; if (dataReference.Address.Type != CacheAddressType.Resource) { throw new InvalidOperationException("Invalid resource data address"); } var resourceDataStream = new MemoryStream(); CacheContext.ExtractResource(resource.Resource, resourceDataStream); resourceDataStream.Position = dataReference.Address.Offset; StreamUtil.Copy(resourceDataStream, outStream, dataReference.Size); }
public static BitmapTextureInteropResource CreateBitmapResourceFromDDS(GameCache cache, DDSFile file) { BitmapTextureInteropResource result = BitmapUtils.CreateEmptyBitmapTextureInteropResource(); if (cache is GameCacheHaloOnlineBase) { // TODO: for cubemaps, fix mipmap order to d3d9 expected order result.Texture.Definition.PrimaryResourceData = new TagData(file.BitmapData); result.Texture.Definition.Bitmap = BitmapUtils.CreateBitmapTextureInteropDefinition(file.Header); } else if (cache.GetType() == typeof(GameCacheGen3)) { // need to do some serious conversion, might be better to require an uncompressed input throw new NotImplementedException(); } return(result); }
public static BaseBitmap ConvertGen3Bitmap(GameCache cache, Bitmap bitmap, int imageIndex, bool forDDS = false) { var image = bitmap.Images[imageIndex]; if (image.XboxFlags.HasFlag(BitmapFlagsXbox.UseInterleavedTextures)) { BitmapTextureInterleavedInteropResource resource = cache.ResourceCache.GetBitmapTextureInterleavedInteropResource(bitmap.InterleavedResources[image.InterleavedTextureIndex1]); if (resource == null) { return(null); } BitmapTextureInteropDefinition definition; BitmapTextureInteropDefinition otherDefinition; int pairIndex = 0; if (image.InterleavedTextureIndex2 > 0) { definition = resource.Texture.Definition.Bitmap2; otherDefinition = resource.Texture.Definition.Bitmap1; pairIndex = 1; } else { definition = resource.Texture.Definition.Bitmap1; otherDefinition = resource.Texture.Definition.Bitmap2; } return(ConvertGen3Bitmap(resource.Texture.Definition.PrimaryResourceData.Data, resource.Texture.Definition.SecondaryResourceData.Data, definition, bitmap, imageIndex, true, pairIndex, otherDefinition, forDDS)); } else { BitmapTextureInteropResource resource = cache.ResourceCache.GetBitmapTextureInteropResource(bitmap.Resources[imageIndex]); if (resource == null) { return(null); } return(ConvertGen3Bitmap(resource.Texture.Definition.PrimaryResourceData.Data, resource.Texture.Definition.SecondaryResourceData.Data, resource.Texture.Definition.Bitmap, bitmap, imageIndex, false, 0, null, forDDS)); } }
public abstract TagResourceReference CreateBitmapResource(BitmapTextureInteropResource bitmapResourceDefinition);
public void InjectDds(TagSerializer serializer, TagDeserializer deserializer, Bitmap bitmap, int imageIndex, Stream ddsStream, ResourceLocation location = ResourceLocation.Textures) { var resource = bitmap.Resources[imageIndex].Resource; var newResource = (resource == null); ResourceSerializationContext resourceContext; BitmapTextureInteropResource definition; if (newResource) { // Create a new resource reference resource = new PageableResource { Page = new RawPage(), Resource = new TagResourceGen3 { ResourceFixups = new List <TagResourceGen3.ResourceFixup>(), ResourceDefinitionFixups = new List <TagResourceGen3.ResourceDefinitionFixup>(), ResourceType = TagResourceTypeGen3.Bitmap, Unknown2 = 1 } }; bitmap.Resources[imageIndex].Resource = resource; resourceContext = new ResourceSerializationContext(CacheContext, resource); definition = new BitmapTextureInteropResource { Texture = new TagStructureReference <BitmapTextureInteropResource.BitmapDefinition> { Definition = new BitmapTextureInteropResource.BitmapDefinition { Data = new TagData(), UnknownData = new TagData(), } } }; } else { // Deserialize the old definition resourceContext = new ResourceSerializationContext(CacheContext, resource); definition = deserializer.Deserialize <BitmapTextureInteropResource>(resourceContext); } if (definition.Texture == null || definition.Texture.Definition == null) { throw new ArgumentException("Invalid bitmap definition"); } var texture = definition.Texture.Definition; var imageData = bitmap.Images[imageIndex]; // Read the DDS header and modify the definition to match var dds = DdsHeader.Read(ddsStream); var dataSize = (int)(ddsStream.Length - ddsStream.Position); texture.Data = new TagData(dataSize, new CacheResourceAddress(CacheResourceAddressType.Resource, 0)); texture.Width = (short)dds.Width; texture.Height = (short)dds.Height; texture.Depth = (sbyte)Math.Max(1, dds.Depth); texture.MipmapCount = (sbyte)Math.Max(1, dds.MipMapCount); texture.Type = BitmapDdsFormatDetection.DetectType(dds); texture.D3DFormat = (int)((dds.D3D10Format != DxgiFormat.Bc5UNorm) ? dds.FourCc : DdsFourCc.FromString("ATI2")); texture.Format = BitmapDdsFormatDetection.DetectFormat(dds); // Set flags based on the format switch (texture.Format) { case BitmapFormat.Dxt1: case BitmapFormat.Dxt3: case BitmapFormat.Dxt5: case BitmapFormat.Dxn: texture.Flags = BitmapFlags.Compressed; break; default: texture.Flags = BitmapFlags.None; break; } if ((texture.Width & (texture.Width - 1)) == 0 && (texture.Height & (texture.Height - 1)) == 0) { texture.Flags |= BitmapFlags.PowerOfTwoDimensions; } // If creating a new image, then add a new resource, otherwise replace the existing one if (newResource) { resource.ChangeLocation(location); CacheContext.AddResource(resource, ddsStream); } else { CacheContext.ReplaceResource(resource, ddsStream); } // Serialize the new resource definition serializer.Serialize(resourceContext, definition); // Modify the image data in the bitmap tag to match the definition imageData.Width = texture.Width; imageData.Height = texture.Height; imageData.Depth = texture.Depth; imageData.Type = texture.Type; imageData.Format = texture.Format; imageData.Flags = texture.Flags; imageData.MipmapCount = (sbyte)(texture.MipmapCount - 1); imageData.DataOffset = texture.Data.Address.Offset; imageData.DataSize = texture.Data.Size; imageData.Curve = (BitmapImageCurve)texture.Curve; }
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); }
public override TagResourceReference CreateBitmapResource(BitmapTextureInteropResource bitmapResourceDefinition) { return(null); }
public override TagResourceReference CreateBitmapResource(BitmapTextureInteropResource bitmapResourceDefinition) { return(CreateResource(bitmapResourceDefinition, ResourceLocation.Textures, TagResourceTypeGen3.Bitmap)); }