예제 #1
0
        public StringTableHaloOnline(CacheVersion version, Stream stream)
        {
            Version = version;

            Resolver = null;

            if (CacheVersionDetection.Compare(Version, CacheVersion.HaloOnline700123) >= 0)
            {
                Resolver = new StringIdResolverMS30();
            }
            else if (CacheVersionDetection.Compare(Version, CacheVersion.HaloOnline498295) >= 0)
            {
                Resolver = new StringIdResolverMS28();
            }
            else
            {
                Resolver = new StringIdResolverMS23();
            }

            if (stream != null && stream.Length != 0)
            {
                Load(stream);
            }
            else
            {
                CreateFromStrings();
            }
        }
예제 #2
0
 /// <summary>
 /// Creates a vertex stream for a given engine version.
 /// </summary>
 /// <param name="version">The engine version.</param>
 /// <param name="stream">The base stream.</param>
 /// <returns>The created vertex stream.</returns>
 public static IVertexStream Create(CacheVersion version, Stream stream)
 {
     if (CacheVersionDetection.Compare(version, CacheVersion.Halo3ODST) <= 0)
     {
         return(new VertexStreamXbox(stream));
     }
     if (CacheVersionDetection.Compare(version, CacheVersion.HaloOnline235640) >= 0)
     {
         return(new VertexStreamMS25(stream));
     }
     return(new VertexStreamMS23(stream));
 }
예제 #3
0
        private ResourceLocation FixResourceLocation(ResourceLocation location, CacheVersion srcVersion, CacheVersion destVersion)
        {
            if (CacheVersionDetection.Compare(destVersion, CacheVersion.HaloOnline235640) >= 0)
            {
                return(location);
            }
            switch (location)
            {
            case ResourceLocation.RenderModels:
                return(ResourceLocation.Resources);

            case ResourceLocation.Lightmaps:
                return(ResourceLocation.Textures);
            }
            return(location);
        }
예제 #4
0
        private RenderGeometry ConvertGeometry(RenderGeometry geometry, GameCacheContextHaloOnline srcCacheContext, GameCacheContextHaloOnline destCacheContext)
        {
            if (geometry == null || geometry.Resource.HaloOnlinePageableResource == null || geometry.Resource.HaloOnlinePageableResource.Page.Index < 0 || !geometry.Resource.HaloOnlinePageableResource.GetLocation(out var location))
            {
                return(geometry);
            }

            // The format changed starting with version 1.235640, so if both versions are on the same side then they can be converted normally
            var srcCompare  = CacheVersionDetection.Compare(srcCacheContext.Version, CacheVersion.HaloOnline235640);
            var destCompare = CacheVersionDetection.Compare(destCacheContext.Version, CacheVersion.HaloOnline235640);

            if ((srcCompare < 0 && destCompare < 0) || (srcCompare >= 0 && destCompare >= 0))
            {
                geometry.Resource.HaloOnlinePageableResource = ConvertResource(geometry.Resource.HaloOnlinePageableResource, srcCacheContext, destCacheContext);
                return(geometry);
            }

            Console.WriteLine("- Rebuilding geometry resource {0} in {1}...", geometry.Resource.HaloOnlinePageableResource.Page.Index, location);
            using (MemoryStream inStream = new MemoryStream(), outStream = new MemoryStream())
            {
                // First extract the model data
                srcCacheContext.ExtractResource(geometry.Resource.HaloOnlinePageableResource, inStream);

                // Now open source and destination vertex streams
                inStream.Position = 0;
                var inVertexStream  = VertexStreamFactory.Create(srcCacheContext.Version, inStream);
                var outVertexStream = VertexStreamFactory.Create(destCacheContext.Version, outStream);

                // Deserialize the definition data
                var resourceContext = new ResourceSerializationContext(CacheContext, geometry.Resource.HaloOnlinePageableResource);
                var definition      = srcCacheContext.Deserializer.Deserialize <RenderGeometryApiResourceDefinition>(resourceContext);

                // Convert each vertex buffer
                foreach (var buffer in definition.VertexBuffers)
                {
                    ConvertVertexBuffer(srcCacheContext, destCacheContext, buffer.Definition, inStream, inVertexStream, outStream, outVertexStream);
                }

                // Copy each index buffer over
                foreach (var buffer in definition.IndexBuffers)
                {
                    if (buffer.Definition.Data.Size == 0)
                    {
                        continue;
                    }
                    inStream.Position = buffer.Definition.Data.Address.Offset;
                    buffer.Definition.Data.Address = new CacheAddress(CacheAddressType.Data, (int)outStream.Position);
                    var bufferData = new byte[buffer.Definition.Data.Size];
                    inStream.Read(bufferData, 0, bufferData.Length);
                    outStream.Write(bufferData, 0, bufferData.Length);
                    StreamUtil.Align(outStream, 4);
                }

                // Update the definition data
                destCacheContext.Serializer.Serialize(resourceContext, definition);

                // Now inject the new resource data
                var newLocation = FixResourceLocation(location, srcCacheContext.Version, destCacheContext.Version);

                outStream.Position = 0;
                geometry.Resource.HaloOnlinePageableResource.ChangeLocation(newLocation);
                destCacheContext.AddResource(geometry.Resource.HaloOnlinePageableResource, outStream);
            }

            return(geometry);
        }