예제 #1
0
        private BitmapTextureInteropResource ExtractResourceDefinition(Bitmap.BitmapResource resource, ResourceSerializationContext context)
        {
            var definition = CacheContext.Deserializer.Deserialize <BitmapTextureInteropResource>(context);

            if (definition.Texture == null || definition.Texture.Definition == null)
            {
                throw new ArgumentException("Invalid bitmap definition");
            }
            return(definition);
        }
예제 #2
0
        private Bitmap ConvertBitmap(CacheFile.IndexItem blamTag, Bitmap bitmap, Dictionary <ResourceLocation, Stream> resourceStreams)
        {
            bitmap.Flags     = BitmapRuntimeFlags.UsingTagInteropAndTagResource;
            bitmap.UnknownB4 = 0;

            if (BlamCache.Version == CacheVersion.HaloReach)
            {
                bitmap.TightBoundsOld = bitmap.TightBoundsNew;

                foreach (var image in bitmap.Images)
                {
                    // For all formats above #38 (reach DXN, CTX1, DXT3a_mono, DXT3a_alpha, DXT5a_mono, DXT5a_alpha, DXN_mono_alpha), subtract 5 to match with H3/ODST/HO enum
                    if (image.Format >= (BitmapFormat)38)
                    {
                        image.Format = image.Format - 5;
                    }
                }
            }

            //
            // For each bitmaps, apply conversion process and create a new list of resources that will replace the one from H3.
            //

            var tagName      = blamTag.Name;
            var resourceList = new List <Bitmap.BitmapResource>();

            for (int i = 0; i < bitmap.Images.Count(); i++)
            {
                var resource = ConvertBitmap(bitmap, resourceStreams, i, tagName);
                if (resource == null)
                {
                    return(null);
                }
                Bitmap.BitmapResource bitmapResource = new Bitmap.BitmapResource
                {
                    Resource = resource
                };
                resourceList.Add(bitmapResource);
            }

            bitmap.Resources = resourceList;
            bitmap.InterleavedResourcesOld = null;

            //fixup for HO expecting 6 sequences in sensor_blips bitmap
            if (tagName == "ui\\chud\\bitmaps\\sensor_blips")
            {
                bitmap.Sequences.Add(bitmap.Sequences[3]);
                bitmap.Sequences.Add(bitmap.Sequences[3]);
            }

            return(bitmap);
        }
예제 #3
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);
        }
예제 #4
0
        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);
        }