public void LoadBSPTag(CacheBase Cache, CacheBase.IndexItem Tag) { cache = Cache; tag = Tag; sbsp = DefinitionsManager.sbsp(cache, tag); sbsp.BSPName = Path.GetFileNameWithoutExtension(tag.Filename + "." + tag.ClassCode); lblName.Text = sbsp.BSPName; if (cache.Version <= DefinitionSet.Halo2Vista) sbsp.LoadRaw(); isWorking = true; tvRegions.Nodes.Clear(); TreeNode ClusterNode = new TreeNode("Clusters") { Checked = true }; foreach (var clust in sbsp.Clusters) { if (sbsp.ModelSections[clust.SectionIndex].Submeshes.Count > 0) ClusterNode.Nodes.Add(new TreeNode(sbsp.Clusters.IndexOf(clust).ToString("D3")) { Tag = clust, Checked = true }); } if (ClusterNode.Nodes.Count > 0) tvRegions.Nodes.Add(ClusterNode); TreeNode IGnode = new TreeNode("Instances") { Checked = true }; foreach (var IG in sbsp.GeomInstances) { if (sbsp.ModelSections[IG.SectionIndex].Submeshes.Count > 0) IGnode.Nodes.Add(new TreeNode(IG.Name) { Tag = IG, Checked = true }); } if (IGnode.Nodes.Count > 0) tvRegions.Nodes.Add(IGnode); isWorking = false; }
public void LoadBitmapTag(CacheBase Cache, CacheBase.IndexItem Tag) { exportAllImagesToolStripMenuItem.Visible = true; cache = Cache; tag = Tag; bitm = DefinitionsManager.bitm(cache, tag); lstBitmaps.Items.Clear(); var list = GetBitmapsByTag(cache, tag, PixelFormat.Format32bppArgb); for (int i = 0; i < list.Count; i++) { var submap = bitm.Bitmaps[i]; lstBitmaps.Items.Add(new ListViewItem(new string[] { i.ToString(), submap.Width.ToString(), submap.Height.ToString(), submap.Type.ToString(), submap.Format.ToString() }) { Tag = (list[i] == null) ? GetErrorImage() : list[i] }); } lstBitmaps.FocusedItem = lstBitmaps.Items[0]; lstBitmaps_SelectedIndexChanged(null, null); }
public void LoadSoundTag(CacheBase Cache, CacheBase.IndexItem Tag) { if (Cache.Version != DefinitionSet.Halo4Retail) { throw new Exception("This is for H4 ONLY"); } cache = (CacheH4R)Cache; tag = Tag; snd = (SoundH4R)DefinitionsManager.snd_(cache, tag); LoadCacheSoundPacks(cache); lstPerms.Items.Clear(); _perms.Clear(); _soundbanks.Clear(); ObjectLoadWorker(); if (lstPerms.Items.Count > 0) { Enabled = true; lstPerms.SelectedIndex = 0; label1.Text = _perms[0].Format.ToString(); } else { label1.Text = ""; Enabled = false; } }
public static void SaveBink(string Filename, CacheBase Cache, CacheBase.IndexItem Tag) { var bik = DefinitionsManager.bink(Cache, Tag); var raw = Cache.GetRawFromID(bik.RawID); if (!Filename.EndsWith(".bik")) { Filename += ".bik"; } if (!Directory.GetParent(Filename).Exists) { Directory.GetParent(Filename).Create(); } var fs = new FileStream(Filename, FileMode.Create, FileAccess.Write); var bw = new BinaryWriter(fs); for (int i = 0; i < (raw.Length); i += 4) { Array.Reverse(raw, i, 4); } bw.Write(raw); bw.Close(); bw.Dispose(); }
private void RecursiveExtract(object SaveFolder) { List<CacheBase.IndexItem> tagsDone = new List<CacheBase.IndexItem>(); foreach (var shader in sbsp.Shaders) { var rmshTag = cache.IndexItems.GetItemByID(shader.tagID); if (rmshTag == null) continue; var rmsh = DefinitionsManager.rmsh(cache, rmshTag); foreach (Definitions.shader.ShaderProperties prop in rmsh.Properties) { foreach (Definitions.shader.ShaderProperties.ShaderMap map in prop.ShaderMaps) { var bitmTag = cache.IndexItems.GetItemByID(map.BitmapTagID); if (bitmTag == null) continue; //dont need to waste time extracting the same ones over and over if (tagsDone.Contains(bitmTag)) continue; try { BitmapExtractor.SaveAllImages((string)SaveFolder + "\\" + bitmTag.Filename, cache, bitmTag, DefaultBitmFormat, true); TagExtracted(this, bitmTag); } catch (Exception ex) { ErrorExtracting(this, bitmTag, ex); } tagsDone.Add(bitmTag); } } } FinishedRecursiveExtract(this, tag); }
/// <summary> /// Save all permutations of a sound tag as separate sound files. /// </summary> /// <param name="Folder">The base filename. Permutation names will be appended accordingly.</param> /// <param name="Cache">The CacheFile containing the tag.</param> /// <param name="Tag">The sound tag.</param> /// <param name="Format">The format in which to save the data.</param> public static void SaveAllAsSeparate(string Folder, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format, bool Overwrite) { var snd_ = DefinitionsManager.snd_(Cache, Tag); var ugh_ = Cache.ugh_; var indices = new List <int>(); for (int i = 0; i < ugh_.PlayBacks[snd_.PlaybackIndex].PermutationCount; i++) { indices.Add(i); } SaveSelected(Folder, Cache, Tag, Format, indices, Overwrite); }
public void LoadUnicTag(CacheBase Cache, CacheBase.IndexItem Tag, Language Language) { cache = Cache; tag = Tag; label1.Enabled = cmbLang.Enabled = true; cmbLang.SelectedIndex = -1; var reader = Cache.Reader; unic = DefinitionsManager.unic(Cache, tag); cmbLang.SelectedIndex = (int)Language; }
/// <summary> /// Saves all pieces of the model from a scenario_structure_bsp tag to disk. /// </summary> /// <param name="Filename">The full path and filename to save to.</param> /// <param name="Cache">The CacheFile containing the scenario_structure_bsp tag.</param> /// <param name="Tag">The scenario_structure_bsp tag.</param> /// <param name="Format">The format to save the model in.</param> public static void SaveAllBSPParts(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, ModelFormat Format) { var sbsp = DefinitionsManager.sbsp(Cache, Tag); sbsp.LoadRaw(); var clusters = new List<int>(); var geoms = new List<int>(); for (int i = 0; i < sbsp.Clusters.Count; i++) clusters.Add(i); for (int i = 0; i < sbsp.GeomInstances.Count; i++) geoms.Add(i); SaveBSPParts(Filename, Cache, sbsp, Format, clusters, geoms); }
public static List <string> GetUnicStrings(CacheBase Cache, CacheBase.IndexItem Tag, Language Language) { List <string> strings = new List <string>(); var reader = Cache.Reader; var unic = DefinitionsManager.unic(Cache, Tag); int index = unic.Indices[(int)Language]; int length = unic.Lengths[(int)Language]; for (int i = index; i < (index + length); i++) { strings.Add(Cache.LocaleTables[(int)Language][i]); } return(strings); }
/// <summary> /// Saves all pieces of the model from a render_model tag to disk. /// </summary> /// <param name="Filename">The full path and filename to save to.</param> /// <param name="Cache">The CacheFile containing the render_model tag.</param> /// <param name="Tag">The render_model tag.</param> /// <param name="Format">The format to save the model in.</param> /// <param name="SplitMeshes">Whether to split the pieces into individual submeshes. Only applies when saving in EMF format.</param> public static void SaveAllModelParts(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, ModelFormat Format, bool SplitMeshes) { var mode = DefinitionsManager.mode(Cache, Tag); mode.LoadRaw(); List <int> Parts = new List <int>(); for (int i = 0; i < mode.ModelSections.Count; i++) { if (mode.ModelSections[i].Submeshes.Count > 0) { Parts.Add(i); } } SaveModelParts(Filename, Cache, mode, Format, Parts, SplitMeshes); }
public override bool Execute(List <string> args) { if (args.Count != 1) { return(false); } CacheBase.IndexItem item = null; Console.WriteLine("Verifying blam shader tag..."); var shaderName = args[0]; foreach (var tag in BlamCache.IndexItems) { if ((tag.ParentClass == "rm") && tag.Filename == shaderName) { item = tag; break; } } if (item == null) { Console.WriteLine("Blam shader tag does not exist: " + shaderName); return(false); } var renderMethod = DefinitionsManager.rmsh(BlamCache, item); var templateItem = BlamCache.IndexItems.Find(i => i.ID == renderMethod.Properties[0].TemplateTagID); var template = DefinitionsManager.rmt2(BlamCache, templateItem); for (var i = 0; i < template.UsageBlocks.Count; i++) { var bitmItem = BlamCache.IndexItems.Find(j => j.ID == renderMethod.Properties[0].ShaderMaps[i].BitmapTagID); Console.WriteLine(bitmItem); } return(true); }
public void LoadModelTag(CacheBase Cache, CacheBase.IndexItem Tag) { cache = Cache; tag = Tag; mode = DefinitionsManager.mode(cache, tag); if (mode.InstancedGeometryIndex != -1) { mode.LoadRaw(); } lblName.Text = mode.Name; tvRegions.Nodes.Clear(); foreach (var region in mode.Regions) { TreeNode node = new TreeNode(region.Name) { Checked = true, Tag = region }; foreach (var perm in region.Permutations) { if (perm.PieceIndex != -1) { if (mode.ModelSections[perm.PieceIndex].Submeshes.Count > 0) { node.Nodes.Add(new TreeNode(perm.Name) { Checked = true, Tag = perm }); } } } if (node.Nodes.Count > 0) { tvRegions.Nodes.Add(node); } } }
public static void SaveUnicStrings(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, Language Language) { List <string> sList = new List <string>(); var reader = Cache.Reader; var unic = DefinitionsManager.unic(Cache, Tag); int index = unic.Indices[(int)Language]; int length = unic.Lengths[(int)Language]; for (int i = index; i < (index + length); i++) { sList.Add(Cache.LocaleTables[(int)Language][i]); } if (!Directory.GetParent(Filename).Exists) { Directory.GetParent(Filename).Create(); } if (!Filename.EndsWith(".txt")) { Filename += ".txt"; } var fs = new FileStream(Filename, FileMode.Create); int start = unic.Indices[(int)Language]; for (int i = 0; i < sList.Count; i++) { string line = (i + start).ToString("D6") + "\t" + sList[i].Replace("\r\n", " ") + "\r\n"; byte[] buffer = Encoding.UTF8.GetBytes(line); fs.Write(buffer, 0, buffer.Length); } fs.Close(); fs.Dispose(); }
public void LoadSoundTag(CacheBase Cache, CacheBase.IndexItem Tag) { cache = Cache; tag = Tag; snd = DefinitionsManager.snd_(cache, tag); if (cache.ugh_ == null) { lstPerms.Items.Clear(); Enabled = false; return; } else { Enabled = true; } ugh = cache.ugh_; playback = ugh.PlayBacks[snd.PlaybackIndex]; Perms = new List <ugh_.SoundPermutation>(); for (int i = 0; i < playback.PermutationCount; i++) { Perms.Add(ugh.SoundPermutations[playback.FirstPermutation + i]); } lstPerms.Items.Clear(); foreach (var perm in Perms) { lstPerms.Items.Add(ugh.SoundNames[perm.NameIndex]); } lstPerms.SelectedIndex = 0; }
public override bool Execute(List <string> args) { var initialStringIDCount = Info.StringIDs.Strings.Count; bool isNew = false; if (args.Count == 3) { if (args[0] != "new") { return(false); } isNew = true; args.Remove("new"); } if (args.Count != 2) { return(false); } // // Verify the Blam render_model tag // var renderModelName = args[0]; CacheBase.IndexItem item = null; Console.WriteLine("Verifying Blam tag..."); foreach (var tag in BlamCache.IndexItems) { if ((tag.ClassCode == "mode" || tag.ClassCode == "sbsp") && tag.Filename == renderModelName) { item = tag; break; } } if (item == null) { Console.WriteLine("Blam tag does not exist: " + args[0]); return(false); } // // Verify the ED render_model tag // Console.WriteLine("Verifying ED tag index..."); int edRenderModelIndex; if (!int.TryParse(args[1], NumberStyles.HexNumber, null, out edRenderModelIndex) || (edRenderModelIndex >= Info.Cache.Tags.Count)) { Console.WriteLine("Invalid tag index: " + args[1]); return(false); } var edTag = Info.Cache.Tags[edRenderModelIndex]; if (edTag.Group.Name != Info.StringIDs.GetStringID("render_model")) { Console.WriteLine("Specified tag index is not a render_model: " + args[1]); return(false); } // // Deserialize the selected render_model // Console.WriteLine("Loading ED render_model tag..."); TagDefinitions.RenderModel renderModel; using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.ReadWrite)) { try { var context = new Serialization.TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, Info.Cache.Tags[(int)edRenderModelIndex]); renderModel = Info.Deserializer.Deserialize <TagDefinitions.RenderModel>(context); } catch { Console.WriteLine("Failed to deserialize selected render_model tag: " + edRenderModelIndex); return(true); } } // // Load the Blam render_model tag raw // var isBSP = item.ClassCode == "sbsp"; scenario_structure_bsp sbsp = null; render_model mode = null; if (isBSP) { sbsp = DefinitionsManager.sbsp(BlamCache, item); sbsp.LoadRaw(); } else { mode = DefinitionsManager.mode(BlamCache, item); mode.LoadRaw(); } // // Duplicate the render_model tag we're injecting over // TagInstance newTag; if (isNew) { Console.WriteLine("Duplicating selected render_model tag..."); if (!new DuplicateTagCommand(Info).Execute(new List <string> { edRenderModelIndex.ToString("X8") })) { Console.WriteLine("Failed to duplicate render_model tag: " + edRenderModelIndex); return(false); } newTag = Info.Cache.Tags[Info.Cache.Tags.Count - 1]; } else { newTag = edTag; } // // Start porting the model // RenderModelBuilder builder = new RenderModelBuilder(DefinitionSet.HaloOnline106708); var blamNodes = isBSP ? new List <render_model.Node> { new render_model.Node { Name = "default", ParentIndex = -1, FirstChildIndex = -1, NextSiblingIndex = -1, Position = new Vector(), Rotation = new Vector(0, 0, 0, -1), TransformScale = 1, TransformMatrix = new Matrix4x3( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0), DistanceFromParent = 0 } } : mode.Nodes; foreach (var node in blamNodes) { var nodeNameId = Info.StringIDs.GetStringID(node.Name); builder.AddNode( new TagDefinitions.RenderModel.Node { Name = nodeNameId.Index == 0 && node.Name != "" ? nodeNameId = Info.StringIDs.Add(node.Name) : nodeNameId, ParentNode = (short)node.ParentIndex, FirstChildNode = (short)node.FirstChildIndex, NextSiblingNode = (short)node.NextSiblingIndex, ImportNode = 0, DefaultTranslation = new Common.Vector3(node.Position.X, node.Position.Y, node.Position.Z), DefaultRotation = new Common.Vector4(node.Rotation.X, node.Rotation.Y, node.Rotation.Z, node.Rotation.W), DefaultScale = node.TransformScale, InverseForward = new Common.Vector3(node.TransformMatrix.m11, node.TransformMatrix.m12, node.TransformMatrix.m13), InverseLeft = new Common.Vector3(node.TransformMatrix.m21, node.TransformMatrix.m22, node.TransformMatrix.m23), InverseUp = new Common.Vector3(node.TransformMatrix.m31, node.TransformMatrix.m32, node.TransformMatrix.m33), InversePosition = new Common.Vector3(node.TransformMatrix.m41, node.TransformMatrix.m42, node.TransformMatrix.m43), DistanceFromParent = node.DistanceFromParent }); } // // Create empty materials for now... // var blamShaders = isBSP ? sbsp.Shaders : mode.Shaders; foreach (var shader in blamShaders) { builder.AddMaterial( new RenderMaterial { RenderMethod = Info.Cache.Tags[0x101F] }); } // // Build the model regions // if (isBSP) { builder.BeginRegion(Info.StringIDs.GetStringID("default")); builder.BeginPermutation(Info.StringIDs.GetStringID("default")); foreach (var section in sbsp.ModelSections) { if (section.Submeshes.Count == 0) { continue; } var rigidVertices = new List <RigidVertex>(); VertexValue v; if (section.Vertices != null) { foreach (var vertex in section.Vertices) { vertex.TryGetValue("position", 0, out v); var position = new Common.Vector4(v.Data.X, v.Data.Y, v.Data.Z, 1); vertex.TryGetValue("normal", 0, out v); var normal = new Common.Vector3(v.Data.I, v.Data.J, v.Data.K); vertex.TryGetValue("texcoords", 0, out v); var texcoord = new Common.Vector2(v.Data.X, v.Data.Y); vertex.TryGetValue("tangent", 0, out v); var tangent = new Common.Vector4(v.Data.X, v.Data.Y, v.Data.Z, 1); vertex.TryGetValue("binormal", 0, out v); var binormal = new Common.Vector3(v.Data.X, v.Data.Y, v.Data.Z); rigidVertices.Add( new RigidVertex { Position = position, Normal = normal, Texcoord = texcoord, Tangent = tangent, Binormal = binormal }); } } // Build the section's subparts builder.BeginMesh(); var indices = new List <ushort>(); foreach (var submesh in section.Submeshes) { builder.BeginPart((short)submesh.ShaderIndex, (ushort)submesh.FaceIndex, (ushort)submesh.FaceCount, (ushort)submesh.VertexCount); for (var j = 0; j < submesh.SubsetCount; j++) { var subpart = section.Subsets[submesh.SubsetIndex + j]; builder.DefineSubPart((ushort)subpart.FaceIndex, (ushort)subpart.FaceCount, (ushort)subpart.VertexCount); } builder.EndPart(); } builder.BindRigidVertexBuffer(rigidVertices, 0); builder.BindIndexBuffer(section.Indices.Select(index => (ushort)index), PrimitiveType.TriangleList); builder.EndMesh(); } builder.EndPermutation(); builder.EndRegion(); foreach (var instance in sbsp.GeomInstances) { var mesh = builder.Meshes[instance.SectionIndex]; if (mesh.VertexFormat == VertexBufferFormat.Rigid) { foreach (var i in mesh.RigidVertices) { i.Position = new Common.Vector4( i.Position.X + instance.TransformMatrix.m41, i.Position.Y + instance.TransformMatrix.m42, i.Position.Z + instance.TransformMatrix.m43, i.Position.W); } } else if (mesh.VertexFormat == VertexBufferFormat.World) { foreach (var i in mesh.WorldVertices) { i.Position = new Common.Vector4( i.Position.X + instance.TransformMatrix.m41, i.Position.Y + instance.TransformMatrix.m42, i.Position.Z + instance.TransformMatrix.m43, i.Position.W); } } else if (mesh.VertexFormat == VertexBufferFormat.Skinned) { foreach (var i in mesh.SkinnedVertices) { i.Position = new Common.Vector4( i.Position.X + instance.TransformMatrix.m41, i.Position.Y + instance.TransformMatrix.m42, i.Position.Z + instance.TransformMatrix.m43, i.Position.W); } } } } else { foreach (var region in mode.Regions) { var regionNameId = Info.StringIDs.GetStringID(region.Name); builder.BeginRegion(regionNameId.Index == 0 && region.Name != "" ? regionNameId = Info.StringIDs.Add(region.Name) : regionNameId); foreach (var permutation in region.Permutations) { if (permutation.PieceCount <= 0 || permutation.PieceIndex == -1) { continue; } var permutationNameId = Info.StringIDs.GetStringID(permutation.Name); builder.BeginPermutation(permutationNameId.Index == 0 && permutation.Name != "" ? permutationNameId = Info.StringIDs.Add(permutation.Name) : permutationNameId); for (var i = permutation.PieceIndex; i < permutation.PieceIndex + permutation.PieceCount; i++) { var section = mode.ModelSections[i]; if (section.Submeshes.Count == 0 || section.Vertices == null) { continue; } // // Collect the section's vertices // var skinnedVertices = new List <SkinnedVertex>(); var rigidVertices = new List <RigidVertex>(); VertexValue v; bool isSkinned = section.Vertices[0].TryGetValue("blendindices", 0, out v) && section.NodeIndex == 255; bool isBoned = section.Vertices[0].FormatName.Contains("rigid_boned"); foreach (var vertex in section.Vertices) { vertex.TryGetValue("position", 0, out v); var position = new Common.Vector4(v.Data.X, v.Data.Y, v.Data.Z, 1); vertex.TryGetValue("normal", 0, out v); var normal = new Common.Vector3(v.Data.I, v.Data.J, v.Data.K); vertex.TryGetValue("texcoords", 0, out v); var texcoord = new Common.Vector2(v.Data.X, v.Data.Y); vertex.TryGetValue("tangent", 0, out v); var tangent = new Common.Vector4(v.Data.X, v.Data.Y, v.Data.Z, 1); vertex.TryGetValue("binormal", 0, out v); var binormal = new Common.Vector3(v.Data.X, v.Data.Y, v.Data.Z); rigidVertices.Add( new RigidVertex { Position = position, Normal = normal, Texcoord = texcoord, Tangent = tangent, Binormal = binormal }); if (isBoned) { var blendIndices = new List <byte>(); vertex.TryGetValue("blendindices", 0, out v); blendIndices.Add((byte)v.Data.A); blendIndices.Add((byte)v.Data.B); blendIndices.Add((byte)v.Data.C); blendIndices.Add((byte)v.Data.D); skinnedVertices.Add(new SkinnedVertex { Position = position, Normal = normal, Texcoord = texcoord, Tangent = tangent, Binormal = binormal, BlendIndices = blendIndices.ToArray(), BlendWeights = new[] { 1.0f, 0.0f, 0.0f, 0.0f } }); } else if (isSkinned) { var blendIndices = new List <byte>(); var blendWeights = new List <float>(); vertex.TryGetValue("blendindices", 0, out v); blendIndices.Add((byte)v.Data.A); blendIndices.Add((byte)v.Data.B); blendIndices.Add((byte)v.Data.C); blendIndices.Add((byte)v.Data.D); vertex.TryGetValue("blendweight", 0, out v); blendWeights.Add(v.Data.A); blendWeights.Add(v.Data.B); blendWeights.Add(v.Data.C); blendWeights.Add(v.Data.D); skinnedVertices.Add(new SkinnedVertex { Position = position, Normal = normal, Texcoord = texcoord, Tangent = tangent, Binormal = binormal, BlendIndices = blendIndices.ToArray(), BlendWeights = blendWeights.ToArray() }); } } bool isRigid = false; if (skinnedVertices.Count == 0) { isRigid = rigidVertices.Count != 0; } // // Build the section's submeshes // builder.BeginMesh(); var indices = new List <ushort>(); foreach (var submesh in section.Submeshes) { builder.BeginPart((short)submesh.ShaderIndex, (ushort)submesh.FaceIndex, (ushort)submesh.FaceCount, (ushort)submesh.VertexCount); for (var j = 0; j < submesh.SubsetCount; j++) { var subpart = section.Subsets[submesh.SubsetIndex + j]; builder.DefineSubPart((ushort)subpart.FaceIndex, (ushort)subpart.FaceCount, (ushort)subpart.VertexCount); } builder.EndPart(); } if (isRigid) { builder.BindRigidVertexBuffer(rigidVertices, (sbyte)section.NodeIndex); } else if (isSkinned || isBoned) { builder.BindSkinnedVertexBuffer(skinnedVertices); } builder.BindIndexBuffer(section.Indices.Select(index => (ushort)index), PrimitiveType.TriangleStrip); builder.EndMesh(); } builder.EndPermutation(); } builder.EndRegion(); } } // // Finalize the new render_model tag // var resourceStream = new MemoryStream(); var newRenderModel = builder.Build(Info.Serializer, resourceStream); var renderModelNameStringID = Info.StringIDs.GetStringID(isBSP ? "default" : mode.Name); newRenderModel.Name = renderModelNameStringID.Index == -1 ? renderModelNameStringID = Info.StringIDs.Add(isBSP ? "default" : mode.Name) : renderModelNameStringID; // // Add the markers to the new render_model // newRenderModel.MarkerGroups = new List <TagDefinitions.RenderModel.MarkerGroup>(); var blamMarkerGroups = isBSP ? new List <render_model.MarkerGroup>() : mode.MarkerGroups; foreach (var markerGroup in blamMarkerGroups) { var markerGroupNameId = Info.StringIDs.GetStringID(markerGroup.Name); if (markerGroupNameId.Index == -1) { markerGroupNameId = Info.StringIDs.Add(markerGroup.Name); } newRenderModel.MarkerGroups.Add( new TagDefinitions.RenderModel.MarkerGroup { Name = markerGroupNameId, Markers = markerGroup.Markers.Select(marker => new TagDefinitions.RenderModel.MarkerGroup.Marker { RegionIndex = (sbyte)marker.RegionIndex, PermutationIndex = (sbyte)marker.PermutationIndex, NodeIndex = (sbyte)marker.NodeIndex, Unknown3 = 0, Translation = new Common.Vector3(marker.Position.X, marker.Position.Y, marker.Position.Z), Rotation = new Common.Vector4(marker.Rotation.X, marker.Rotation.Y, marker.Rotation.Z, marker.Rotation.W), Scale = marker.Scale }).ToList() }); } // // Disable rigid nodes on skinned meshes // foreach (var mesh in newRenderModel.Geometry.Meshes) { if (mesh.Type == VertexType.Skinned) { mesh.RigidNodeIndex = -1; } } // // Add a new resource for the model data // Console.WriteLine("Writing resource data..."); var resources = new ResourceDataManager(); resources.LoadCachesFromDirectory(Info.CacheFile.DirectoryName); resourceStream.Position = 0; resources.Add(newRenderModel.Geometry.Resource, ResourceLocation.Resources, resourceStream); using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.ReadWrite)) { Console.WriteLine("Writing tag data..."); newRenderModel.Geometry.Resource.Owner = newTag; var context = new Serialization.TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, newTag); Info.Serializer.Serialize(context, newRenderModel); } resourceStream.Close(); // // Save new string_ids // if (Info.StringIDs.Strings.Count != initialStringIDCount) { Console.WriteLine("Saving string_ids..."); using (var stringIdStream = Info.StringIDsFile.Open(FileMode.Open, FileAccess.ReadWrite)) Info.StringIDs.Save(stringIdStream); } // // Done! // Console.WriteLine("Ported render_model \"" + renderModelName + "\" successfully!"); return(true); }
/// <summary> /// Saves all images from a bitmap tag to disk. /// </summary> /// <param name="Filename">The full path and filename of the first bitmap to save. All subsequent images will be named accordingly.</param> /// <param name="Cache">The CacheFile containing the bitmap tag.</param> /// <param name="Tag">The bitmap tag.</param> /// <param name="Format">The format to save the images in.</param> /// <param name="Alpha">Whether to include the alpha channel in the images. Only applies when saving in TIF format.</param> public static void SaveAllImages(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, BitmapFormat Format, bool Alpha) { var bitm = DefinitionsManager.bitm(Cache, Tag); SaveAllImages(Filename, Cache, bitm, Format, Alpha); }
private void loadBspTag(CacheBase Cache, CacheBase.IndexItem Tag, bool Specular, bool Force) { if (!this.Enabled) { this.Enabled = true; } tvRegions.Nodes.Clear(); if (renderer1.Running) { renderer1.Stop("Loading..."); } Refresh(); cache = Cache; tag = Tag; sbsp = DefinitionsManager.sbsp(cache, tag); sbsp.BSPName = Path.GetFileNameWithoutExtension(tag.Filename + "." + tag.ClassCode); sbsp.LoadRaw(); isWorking = true; #region Build Tree TreeNode ClusterNode = new TreeNode("Clusters") { Checked = true }; foreach (var clust in sbsp.Clusters) { if (clust.SectionIndex >= sbsp.ModelSections.Count) { continue; } if (sbsp.ModelSections[clust.SectionIndex].Submeshes.Count > 0) { ClusterNode.Nodes.Add(new TreeNode(sbsp.Clusters.IndexOf(clust).ToString("D3")) { Tag = clust, Checked = true }); } } if (ClusterNode.Nodes.Count > 0) { tvRegions.Nodes.Add(ClusterNode); } TreeNode IGnode = new TreeNode("Instances") { Checked = true }; foreach (var IG in sbsp.GeomInstances) { if (IG.SectionIndex >= sbsp.ModelSections.Count) { continue; } if (sbsp.ModelSections[IG.SectionIndex].Submeshes.Count > 0) { IGnode.Nodes.Add(new TreeNode(IG.Name) { Tag = IG, Checked = true }); } } if (IGnode.Nodes.Count > 0) { tvRegions.Nodes.Add(IGnode); } tvRegions.Sort(); //much easier for looking through IGs #endregion isWorking = false; #region Load Stuff LoadShaders(false); LoadSections(); foreach (var clust in sbsp.Clusters) { AddCluster(clust, Force); } foreach (var ig in sbsp.GeomInstances) { AddGeomInstance(ig, Force); } #endregion #region BoundingBox Stuff PerspectiveCamera camera = (PerspectiveCamera)renderer1.Viewport.Camera; var XBounds = new RealBounds(float.MaxValue, float.MinValue); var YBounds = new RealBounds(float.MaxValue, float.MinValue); var ZBounds = new RealBounds(float.MaxValue, float.MinValue); #region Get Bounds foreach (var c in sbsp.Clusters) { if (c.SectionIndex >= sbsp.ModelSections.Count) { continue; } if (sbsp.ModelSections[c.SectionIndex].Submeshes.Count == 0) { continue; } if (c.XBounds.Min < XBounds.Min) { XBounds.Min = c.XBounds.Min; } if (c.YBounds.Min < YBounds.Min) { YBounds.Min = c.YBounds.Min; } if (c.ZBounds.Min < ZBounds.Min) { ZBounds.Min = c.ZBounds.Min; } if (c.XBounds.Max > XBounds.Max) { XBounds.Max = c.XBounds.Max; } if (c.YBounds.Max > YBounds.Max) { YBounds.Max = c.YBounds.Max; } if (c.ZBounds.Max > ZBounds.Max) { ZBounds.Max = c.ZBounds.Max; } } //foreach (var bb in sbsp.BoundingBoxes) //{ // if (bb.XBounds.Min < XBounds.Min) XBounds.Min = bb.XBounds.Min; // if (bb.YBounds.Min < YBounds.Min) YBounds.Min = bb.YBounds.Min; // if (bb.ZBounds.Min < ZBounds.Min) ZBounds.Min = bb.ZBounds.Min; // if (bb.XBounds.Max > XBounds.Max) XBounds.Max = bb.XBounds.Max; // if (bb.YBounds.Max > YBounds.Max) YBounds.Max = bb.YBounds.Max; // if (bb.ZBounds.Max > ZBounds.Max) ZBounds.Max = bb.ZBounds.Max; //} #endregion double pythagoras3d = Math.Sqrt( Math.Pow(XBounds.Length, 2) + Math.Pow(YBounds.Length, 2) + Math.Pow(ZBounds.Length, 2)); if (double.IsInfinity(pythagoras3d) || pythagoras3d == 0) //no clusters { XBounds = sbsp.XBounds; YBounds = sbsp.YBounds; ZBounds = sbsp.ZBounds; pythagoras3d = Math.Sqrt( Math.Pow(XBounds.Length, 2) + Math.Pow(YBounds.Length, 2) + Math.Pow(ZBounds.Length, 2)); } if (XBounds.Length / 2 > (YBounds.Length)) //side view { var p = new Point3D( XBounds.MidPoint, YBounds.Max + pythagoras3d * 0.5, ZBounds.MidPoint); renderer1.MoveCamera(p, new Vector3D(0, 0, -2)); } else //normal camera position { var p = new Point3D( XBounds.Max + pythagoras3d * 0.5, YBounds.MidPoint, ZBounds.MidPoint); renderer1.MoveCamera(p, new Vector3D(-1, 0, 0)); } renderer1.CameraSpeed = Math.Ceiling(pythagoras3d * 3) / 1000; renderer1.MaxCameraSpeed = Math.Ceiling(pythagoras3d * 3) * 5 / 1000; renderer1.MaxPosition = new Point3D( sbsp.XBounds.Max + pythagoras3d * 2, sbsp.YBounds.Max + pythagoras3d * 2, sbsp.ZBounds.Max + pythagoras3d * 2); renderer1.MinPosition = new Point3D( sbsp.XBounds.Min - pythagoras3d * 2, sbsp.YBounds.Min - pythagoras3d * 2, sbsp.ZBounds.Min - pythagoras3d * 2); renderer1.FarPlaneMin = pythagoras3d * 0.1; renderer1.FarPlane = pythagoras3d; renderer1.FarPlaneMax = pythagoras3d; #endregion renderer1.Start(); RenderSelected(); }
/// <summary> /// Saves selected permutations of a sound tag. /// </summary> /// <param name="Folder">The folder to save all files in. Each file will be named as the permutation name.</param> /// <param name="Cache">The CacheFile containing the tag.</param> /// <param name="Tag">The sound tag.</param> /// <param name="Format">The format in which to save the data.</param> /// <param name="Indices">The indices of the permutations to extract.</param> public static void SaveSelected(string Folder, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format, List <int> Indices, bool Overwrite) { var snd_ = DefinitionsManager.snd_(Cache, Tag); List <byte[]> perms = new List <byte[]>(); var ugh_ = Cache.ugh_; var playback = ugh_.PlayBacks[snd_.PlaybackIndex]; var data = Cache.GetSoundRaw(snd_.RawID, GetTotalSize(ugh_, playback)); if (playback.PermutationCount == 1) { perms.Add(data); } else { Folder = Directory.GetParent(Folder) + "\\" + Path.GetFileNameWithoutExtension(Folder); for (int i = 0; i < playback.PermutationCount; i++) { var perm = Cache.ugh_.SoundPermutations[playback.FirstPermutation + i]; perms.Add(GetPermData(data, ugh_, perm)); } } #region XMA if (Format == SoundFormat.XMA) { foreach (int index in Indices) { string Filename = (playback.PermutationCount == 1) ? Folder : Folder + "\\" + ugh_.SoundNames[ugh_.SoundPermutations[playback.FirstPermutation + index].NameIndex].Name + ".xma"; if (!Filename.EndsWith(".xma")) { Filename += ".xma"; } if (File.Exists(Filename) && !Overwrite) { continue; } byte[] buffer = perms[index]; var codec = Cache.ugh_.Codecs[snd_.CodecIndex]; var xma = GetXMA(buffer, snd_.SampleRate, codec.Type); if (!Directory.GetParent(Filename).Exists) { Directory.GetParent(Filename).Create(); } var fs = new FileStream(Filename, FileMode.Create); EndianWriter sw = new EndianWriter(fs, EndianFormat.BigEndian); sw.Write(xma); sw.Close(); sw.Dispose(); } } #endregion #region WAV else if (Format == SoundFormat.WAV) { foreach (int index in Indices) { string Filename = (playback.PermutationCount == 1) ? Folder : Folder + "\\" + ugh_.SoundNames[ugh_.SoundPermutations[playback.FirstPermutation + index].NameIndex].Name + ".wav"; if (!Filename.EndsWith(".wav")) { Filename += ".wav"; } if (File.Exists(Filename) && !Overwrite) { continue; } var tempName = Path.GetTempFileName(); #region Write XMA var buffer = perms[index]; var codec = Cache.ugh_.Codecs[snd_.CodecIndex]; var xma = GetXMA(buffer, snd_.SampleRate, codec.Type); var fs = File.OpenWrite(tempName); EndianWriter sw = new EndianWriter(fs, EndianFormat.BigEndian); sw.Write(xma); sw.Close(); sw.Dispose(); #endregion var info = new ProcessStartInfo(towav, tempName) { CreateNoWindow = true, UseShellExecute = false, WorkingDirectory = Directory.GetParent(tempName).FullName }; Process.Start(info).WaitForExit(); if (File.Exists(Filename)) { File.Delete(Filename); } if (!Directory.GetParent(Filename).Exists) { Directory.GetParent(Filename).Create(); } File.Move(Path.ChangeExtension(tempName, "wav"), Filename); if (File.Exists(tempName)) { File.Delete(tempName); } } } #endregion #region RAW else if (Format == SoundFormat.RAW) { foreach (int index in Indices) { string Filename = (playback.PermutationCount == 1) ? Folder : Folder + "\\" + ugh_.SoundNames[ugh_.SoundPermutations[playback.FirstPermutation + index].NameIndex].Name + ".bin"; if (!Filename.EndsWith(".bin")) { Filename += ".bin"; } if (File.Exists(Filename) && !Overwrite) { continue; } byte[] buffer = perms[index]; if (!Directory.GetParent(Filename).Exists) { Directory.GetParent(Filename).Create(); } var fs = new FileStream(Filename, FileMode.Create); BinaryWriter sw = new BinaryWriter(fs); sw.Write(buffer); sw.Close(); sw.Dispose(); } } #endregion }
private void RecursiveExtract(object SaveFolder) { List <CacheBase.IndexItem> tagsDone = new List <CacheBase.IndexItem>(); foreach (render_model.Shader shader in mode.Shaders) { var rmshTag = cache.IndexItems.GetItemByID(shader.tagID); if (rmshTag == null) { continue; } var rmsh = DefinitionsManager.rmsh(cache, rmshTag); #region Halo 2 Extract if (cache.Version == DefinitionSet.Halo2Xbox) { var h2rmsh = rmsh as Definitions.Halo2Xbox.shader; for (int i = 0; i < h2rmsh.BitmIDs.Length; i++) { var bitmTag = cache.IndexItems.GetItemByID(h2rmsh.BitmIDs[i]); if (bitmTag == null) { continue; } //dont need to waste time extracting the same ones over and over if (tagsDone.Contains(bitmTag)) { continue; } try { BitmapExtractor.SaveAllImages((string)SaveFolder + "\\" + bitmTag.Filename, cache, bitmTag, DefaultBitmFormat, true); TagExtracted(this, bitmTag); } catch (Exception ex) { ErrorExtracting(this, bitmTag, ex); } tagsDone.Add(bitmTag); } continue; } #endregion foreach (Definitions.shader.ShaderProperties prop in rmsh.Properties) { foreach (Definitions.shader.ShaderProperties.ShaderMap map in prop.ShaderMaps) { var bitmTag = cache.IndexItems.GetItemByID(map.BitmapTagID); if (bitmTag == null) { continue; } //dont need to waste time extracting the same ones over and over if (tagsDone.Contains(bitmTag)) { continue; } try { BitmapExtractor.SaveAllImages((string)SaveFolder + "\\" + bitmTag.Filename, cache, bitmTag, DefaultBitmFormat, true); TagExtracted(this, bitmTag); } catch (Exception ex) { ErrorExtracting(this, bitmTag, ex); } tagsDone.Add(bitmTag); } } } FinishedRecursiveExtract(this, tag); }
private void LoadShaders(bool spec) { var errMat = GetErrorMaterial(); if (mode.Shaders.Count == 0) { var matGroup = new MaterialGroup(); matGroup.Children.Add(errMat); shaders.Add(matGroup); } foreach (render_model.Shader s in mode.Shaders) { #region Skip Unused bool found = false; foreach (var sec in mode.ModelSections) { foreach (var sub in sec.Submeshes) { if (sub.ShaderIndex == mode.Shaders.IndexOf(s)) { found = true; break; } } if (found) { break; } } if (!found) { shaders.Add(null); continue; } #endregion var matGroup = new MaterialGroup(); try { var rmshTag = cache.IndexItems.GetItemByID(s.tagID); var rmsh = DefinitionsManager.rmsh(cache, rmshTag); int mapIndex = 0; if (cache.Version >= DefinitionSet.Halo3Beta && cache.Version <= DefinitionSet.HaloReachRetail) { var rmt2Tag = cache.IndexItems.GetItemByID(rmsh.Properties[0].TemplateTagID); var rmt2 = DefinitionsManager.rmt2(cache, rmt2Tag); for (int i = 0; i < rmt2.UsageBlocks.Count; i++) { if (rmt2.UsageBlocks[i].Usage == "base_map") { mapIndex = i; break; } } } var bitmTag = cache.IndexItems.GetItemByID(rmsh.Properties[0].ShaderMaps[mapIndex].BitmapTagID); var image = BitmapExtractor.GetBitmapByTag(cache, bitmTag, 0, System.Drawing.Imaging.PixelFormat.Format32bppArgb); if (image == null) { matGroup.Children.Add(errMat); shaders.Add(matGroup); continue; } int tileIndex = rmsh.Properties[0].ShaderMaps[mapIndex].TilingIndex; float uTiling; try { uTiling = rmsh.Properties[0].Tilings[tileIndex].UTiling; } catch { uTiling = 1; } float vTiling; try { vTiling = rmsh.Properties[0].Tilings[tileIndex].VTiling; } catch { vTiling = 1; } MemoryStream stream = new MemoryStream(); //PNG for transparency image.Save(stream, (rmshTag.ClassCode == "rmsh" || rmshTag.ClassCode == "mat") ? ImageFormat.Bmp : ImageFormat.Bmp); var diffuse = new BitmapImage(); diffuse.BeginInit(); diffuse.StreamSource = new MemoryStream(stream.ToArray()); diffuse.EndInit(); matGroup.Children.Add(new DiffuseMaterial() { Brush = new ImageBrush(diffuse) { ViewportUnits = BrushMappingMode.Absolute, TileMode = TileMode.Tile, Viewport = new System.Windows.Rect(0, 0, 1f / Math.Abs(uTiling), 1f / Math.Abs(vTiling)) } }); if (spec && rmshTag.ClassCode == "rmsh") { stream = new MemoryStream(); image.Save(stream, ImageFormat.Png); var specular = new BitmapImage(); specular.BeginInit(); specular.StreamSource = new MemoryStream(stream.ToArray()); specular.EndInit(); matGroup.Children.Add(new SpecularMaterial() { SpecularPower = 10, Brush = new ImageBrush(specular) { ViewportUnits = BrushMappingMode.Absolute, TileMode = TileMode.Tile, Viewport = new System.Windows.Rect(0, 0, 1f / Math.Abs(uTiling), 1f / Math.Abs(vTiling)) } }); } shaders.Add(matGroup); } catch { matGroup.Children.Add(errMat); shaders.Add(matGroup); } } }
/// <summary> /// Save all permutations of a sound tag as separate sound files. /// </summary> /// <param name="Folder">The base filename. Permutation names will be appended accordingly.</param> /// <param name="Cache">The CacheFile containing the tag.</param> /// <param name="Tag">The sound tag.</param> /// <param name="Format">The format in which to save the data.</param> public void SaveAllAsSeparate(string Folder, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format, bool Overwrite) { if (Format != SoundFormat.WAV) { throw new NotSupportedException("Halo4Retail only supports WAV."); } if (Cache.Version != DefinitionSet.Halo4Retail) { throw new Exception("This is for H4 ONLY"); } if (scanner == null) { scanner = new SoundScanner(); scanner.FoundSoundBankFile += FoundSoundBankFile; scanner.FoundSoundPackFile += FoundSoundPackFile; } cache = (CacheH4R)Cache; tag = Tag; snd = (SoundH4R)DefinitionsManager.snd_(cache, tag); LoadCacheSoundPacks(cache); if (cache.SoundFiles == null) { cache.SoundFiles = new Dictionary <uint, List <SoundFileInfo> >(); ObjectLoadWorker(); } bool s1, s2; List <SoundFileInfo> sfi1, sfi2, sfi3; s1 = cache.SoundFiles.TryGetValue(snd.SoundAddress1, out sfi1); s2 = cache.SoundFiles.TryGetValue(snd.SoundAddress2, out sfi2); if (!s1 && !s2) { throw new Exception("No permutations found."); } sfi3 = new List <SoundFileInfo>(); if (s1) { sfi3.AddRange(sfi1); } if (s2) { sfi3.AddRange(sfi2); } for (int i = 0; i < sfi3.Count; i++) { var info = sfi3[i]; var fName = Path.GetFileName(tag.Filename); fName = Folder + "\\" + fName + " [" + i.ToString() + "]" + ".wav"; if (File.Exists(fName) && !Overwrite) { return; } RIFX rifx = ReadRIFX(info); switch (info.Format) { case Composer.SoundFormat.XMA: if (!Directory.GetParent(fName).Exists) { Directory.GetParent(fName).Create(); } SoundExtraction.ExtractXMAToWAV(info.Reader, info.Offset, rifx, fName); break; case Composer.SoundFormat.WwiseOGG: if (!Directory.GetParent(fName).Exists) { Directory.GetParent(fName).Create(); } SoundExtraction.ExtractWwiseToOGG(info.Reader, info.Offset, info.Size, fName); break; default: throw new NotSupportedException(info.Format.ToString() + " not supported."); } } }
private void loadModelTag(CacheBase Cache, CacheBase.IndexItem Tag, bool Specular, bool UserPermFilter, bool Force) { if (!this.Enabled) { this.Enabled = true; } tvRegions.Nodes.Clear(); if (renderer1.Running) { renderer1.Stop("Loading..."); } Refresh(); cache = Cache; tag = Tag; mode = DefinitionsManager.mode(cache, tag); mode.LoadRaw(); isWorking = true; #region Build Tree foreach (var region in mode.Regions) { TreeNode node = new TreeNode(region.Name) { Tag = region }; foreach (var perm in region.Permutations) { if (perm.PieceIndex != -1) { if (mode.ModelSections[perm.PieceIndex].Submeshes.Count > 0) { node.Nodes.Add(new TreeNode(perm.Name) { Tag = perm }); } } } if (node.Nodes.Count > 0) { tvRegions.Nodes.Add(node); } } if (UserPermFilter) { foreach (TreeNode node in tvRegions.Nodes) { foreach (TreeNode child in node.Nodes) { if (PermutationFilter.Contains((child.Tag as render_model.Region.Permutation).Name)) { child.Checked = node.Checked = true; } } } } else { foreach (TreeNode node in tvRegions.Nodes) { node.Nodes[0].Checked = node.Checked = true; } } #endregion isWorking = false; LoadShaders(Specular); LoadMeshes(Force); #region BoundingBox Stuff PerspectiveCamera camera = (PerspectiveCamera)renderer1.Viewport.Camera; var bb = mode.BoundingBoxes[0]; double pythagoras3d = Math.Sqrt( Math.Pow(bb.XBounds.Length, 2) + Math.Pow(bb.YBounds.Length, 2) + Math.Pow(bb.ZBounds.Length, 2)); if (bb.XBounds.Length / 2 > (bb.YBounds.Length)) //side view for long models like weapons { var p = new Point3D( bb.XBounds.MidPoint, bb.YBounds.Max + pythagoras3d * 0.75, bb.ZBounds.MidPoint); renderer1.MoveCamera(p, new Vector3D(0, 0, -2)); } else //normal camera position { var p = new Point3D( bb.XBounds.Max + pythagoras3d * 0.75, bb.YBounds.MidPoint, bb.ZBounds.MidPoint); renderer1.MoveCamera(p, new Vector3D(-1, 0, 0)); } renderer1.CameraSpeed = Math.Ceiling(pythagoras3d * 5) / 1000; renderer1.MaxCameraSpeed = Math.Ceiling(pythagoras3d * 5) * 7 / 1000; renderer1.MaxPosition = new Point3D( bb.XBounds.Max + pythagoras3d * 3, bb.YBounds.Max + pythagoras3d * 3, bb.ZBounds.Max + pythagoras3d * 3); renderer1.MinPosition = new Point3D( bb.XBounds.Min - pythagoras3d * 3, bb.YBounds.Min - pythagoras3d * 3, bb.ZBounds.Min - pythagoras3d * 3); renderer1.FarPlaneMin = 100; renderer1.FarPlane = 1000; renderer1.FarPlaneMax = 5000; #endregion RenderSelected(); renderer1.Start(); }
/// <summary> /// Saves all permutations of a sound tag concatenated as a single sound file. /// </summary> /// <param name="Filename">The file to save the data to.</param> /// <param name="Cache">The CacheFile containing the tag.</param> /// <param name="Tag">The sound tag.</param> /// <param name="Format">The format in which to save the data.</param> public static void SaveAllAsSingle(string Filename, CacheBase Cache, CacheBase.IndexItem Tag, SoundFormat Format) { var snd_ = DefinitionsManager.snd_(Cache, Tag); #region XMA if (Format == SoundFormat.XMA) { var total = GetTotalSize(Cache.ugh_, Cache.ugh_.PlayBacks[snd_.PlaybackIndex]); byte[] buffer = Cache.GetSoundRaw(snd_.RawID, total); if (buffer.Length == 0) { throw new Exception("Empty raw data."); } var codec = Cache.ugh_.Codecs[snd_.CodecIndex]; var xma = GetXMA(buffer, snd_.SampleRate, codec.Type); if (!Directory.GetParent(Filename).Exists) { Directory.GetParent(Filename).Create(); } var fs = File.OpenWrite(Filename); EndianWriter sw = new EndianWriter(fs, EndianFormat.BigEndian); sw.Write(xma); sw.Close(); sw.Dispose(); } #endregion #region WAV else if (Format == SoundFormat.WAV) { var tempName = Path.GetTempFileName(); SaveAllAsSingle(tempName, Cache, Tag, SoundFormat.XMA); var info = new ProcessStartInfo(towav, tempName) { CreateNoWindow = true, UseShellExecute = false, WorkingDirectory = Directory.GetParent(tempName).FullName }; Process.Start(info).WaitForExit(); if (File.Exists(Filename)) { File.Delete(Filename); } if (!Directory.GetParent(Filename).Exists) { Directory.GetParent(Filename).Create(); } File.Move(Path.ChangeExtension(tempName, "wav"), Filename); if (File.Exists(tempName)) { File.Delete(tempName); } } #endregion #region RAW else if (Format == SoundFormat.RAW) { byte[] buffer = Cache.GetSoundRaw(snd_.RawID, GetTotalSize(Cache.ugh_, Cache.ugh_.PlayBacks[snd_.PlaybackIndex])); if (!Directory.GetParent(Filename).Exists) { Directory.GetParent(Filename).Create(); } var fs = new FileStream(Filename, FileMode.Create); BinaryWriter sw = new BinaryWriter(fs); sw.Write(buffer); sw.Close(); sw.Dispose(); } #endregion #region Other else { throw new InvalidOperationException("Invalid sound format received."); } #endregion }
/// <summary> /// Gets an image from a bitmap tag. /// </summary> /// <param name="Cache">The CacheFile containing the bitmap tag.</param> /// <param name="Tag">The bitmap tag.</param> /// <param name="Index">The index of the BitmapData chunk to use.</param> /// <param name="Alpha">Whether to include the alpha channel in the image.</param> /// <returns>The image from the bitmap tag as a Bitmap.</returns> public static Bitmap GetBitmapByTag(CacheBase Cache, CacheBase.IndexItem Tag, int Index, PixelFormat PF) { var bitm = DefinitionsManager.bitm(Cache, Tag); return(GetBitmapByTag(Cache, bitm, Index, PF)); }
/// <summary> /// Gets all images from the a bitmap tag. /// </summary> /// <param name="Cache">The CacheFile containing the bitmap tag.</param> /// <param name="Tag">The bitmap tag.</param> /// <param name="Alpha">Whether to include the alpha channels in the images.</param> /// <returns>A List containing each image as a Bitmap.</returns> public static List <Bitmap> GetBitmapsByTag(CacheBase Cache, CacheBase.IndexItem Tag, PixelFormat PF) { var bitm = DefinitionsManager.bitm(Cache, Tag); return(GetBitmapsByTag(Cache, bitm, PF)); }
public override bool Execute(List <string> args) { if (args.Count != 1) { return(false); } // // Verify and load the blam shader // var shaderName = args[0]; CacheBase.IndexItem item = null; Console.WriteLine("Verifying blam shader tag..."); foreach (var tag in BlamCache.IndexItems) { if ((tag.ParentClass == "rm") && tag.Filename == shaderName) { item = tag; break; } } if (item == null) { Console.WriteLine("Blam shader tag does not exist: " + shaderName); return(false); } var renderMethod = DefinitionsManager.rmsh(BlamCache, item); var templateItem = BlamCache.IndexItems.Find(i => i.ID == renderMethod.Properties[0].TemplateTagID); var template = DefinitionsManager.rmt2(BlamCache, templateItem); // // Determine the blam shader's base bitmap // var bitmapIndex = -1; var bitmapArgName = ""; for (var i = 0; i < template.UsageBlocks.Count; i++) { var entry = template.UsageBlocks[i]; if (entry.Usage.StartsWith("base_map") || entry.Usage.StartsWith("diffuse_map") || entry.Usage == "foam_texture") { bitmapIndex = i; bitmapArgName = entry.Usage; break; } } // // Load and decode the blam shader's base bitmap // var bitmItem = BlamCache.IndexItems.Find(i => i.ID == renderMethod.Properties[0].ShaderMaps[bitmapIndex].BitmapTagID); var bitm = DefinitionsManager.bitm(BlamCache, bitmItem); var submap = bitm.Bitmaps[0]; byte[] raw; if (BlamCache.Version <= DefinitionSet.Halo2Vista) { raw = BlamCache.GetRawFromID(submap.PixelsOffset, submap.RawSize); } else { if (bitm.RawChunkBs.Count > 0) { int rawID = bitm.RawChunkBs[submap.InterleavedIndex].RawID; byte[] buffer = BlamCache.GetRawFromID(rawID); raw = new byte[submap.RawSize]; Array.Copy(buffer, submap.Index2 * submap.RawSize, raw, 0, submap.RawSize); } else { int rawID = bitm.RawChunkAs[0].RawID; raw = BlamCache.GetRawFromID(rawID, submap.RawSize); } } var vHeight = submap.VirtualHeight; var vWidth = submap.VirtualWidth; var ms = new MemoryStream(); var bw = new BinaryWriter(ms); if (submap.Flags.Values[3]) { raw = DXTDecoder.ConvertToLinearTexture(raw, vWidth, vHeight, submap.Format); } if (submap.Format != BitmapFormat.A8R8G8B8) { for (int i = 0; i < raw.Length; i += 2) { Array.Reverse(raw, i, 2); } } else { for (int i = 0; i < (raw.Length); i += 4) { Array.Reverse(raw, i, 4); } } new DDS(submap).Write(bw); bw.Write(raw); raw = ms.ToArray(); bw.Close(); bw.Dispose(); // // ElDorado Serialization // using (var cacheStream = Info.CacheFile.Open(FileMode.Open, FileAccess.ReadWrite)) { // // Create the new eldorado bitmap // var resourceManager = new ResourceDataManager(); resourceManager.LoadCachesFromDirectory(Info.CacheFile.DirectoryName); var newBitm = Info.Cache.DuplicateTag(cacheStream, Info.Cache.Tags[0x101F]); var bitmap = new TagDefinitions.Bitmap { Flags = TagDefinitions.Bitmap.RuntimeFlags.UseResource, Sequences = new List <TagDefinitions.Bitmap.Sequence> { new TagDefinitions.Bitmap.Sequence { Name = "", FirstBitmapIndex = 0, BitmapCount = 1 } }, Images = new List <TagDefinitions.Bitmap.Image> { new TagDefinitions.Bitmap.Image { Signature = new Tag("bitm").Value, Unknown28 = -1 } }, Resources = new List <TagDefinitions.Bitmap.BitmapResource> { new TagDefinitions.Bitmap.BitmapResource() } }; using (var imageStream = new MemoryStream(raw)) { var injector = new BitmapDdsInjector(resourceManager); imageStream.Seek(0, SeekOrigin.Begin); injector.InjectDds(Info.Serializer, Info.Deserializer, bitmap, 0, imageStream); } var context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, newBitm); Info.Serializer.Serialize(context, bitmap); // // Create the new eldorado shader // var newRmsh = Info.Cache.DuplicateTag(cacheStream, Info.Cache.Tags[0x331A]); context = new TagSerializationContext(cacheStream, Info.Cache, Info.StringIDs, newRmsh); var shader = Info.Deserializer.Deserialize <TagDefinitions.Shader>(context); shader.ShaderProperties[0].ShaderMaps[0].Bitmap = newBitm; Info.Serializer.Serialize(context, shader); Console.WriteLine("Done! New shader tag is 0x" + newRmsh.Index.ToString("X8")); } return(true); }