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(); } }
/// <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)); }
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); }
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); }