Beispiel #1
0
        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);
        }
Beispiel #2
0
 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;
 }
Beispiel #3
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);
    }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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));
            }
        }
Beispiel #7
0
 public abstract TagResourceReference CreateBitmapResource(BitmapTextureInteropResource bitmapResourceDefinition);
Beispiel #8
0
        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);
        }
Beispiel #10
0
 public override TagResourceReference CreateBitmapResource(BitmapTextureInteropResource bitmapResourceDefinition)
 {
     return(null);
 }
 public override TagResourceReference CreateBitmapResource(BitmapTextureInteropResource bitmapResourceDefinition)
 {
     return(CreateResource(bitmapResourceDefinition, ResourceLocation.Textures, TagResourceTypeGen3.Bitmap));
 }