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 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(); }
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 scenario_structure_bsp(CacheBase Cache, CacheBase.IndexItem Tag) { cache = Cache; int Address = Tag.Offset; EndianReader Reader = Cache.Reader; Reader.SeekTo(Address); Reader.SeekTo(Address + 68); XBounds = new Range <float>(Reader.ReadSingle(), Reader.ReadSingle()); YBounds = new Range <float>(Reader.ReadSingle(), Reader.ReadSingle()); ZBounds = new Range <float>(Reader.ReadSingle(), Reader.ReadSingle()); #region Clusters Block Reader.SeekTo(Address + 172); int iCount = Reader.ReadInt32(); int iOffset = Reader.ReadInt32() - Tag.Magic; for (int i = 0; i < iCount; i++) { ModelSections.Add(new ModelSection(Cache, Tag, iOffset + 176 * i, null) { FacesIndex = i, VertsIndex = i, NodeIndex = 255 }); Clusters.Add(new Cluster(i)); } #endregion #region Shaders Block Reader.SeekTo(Address + 180); iCount = Reader.ReadInt32(); iOffset = Reader.ReadInt32() - Tag.Magic; for (int i = 0; i < iCount; i++) { Shaders.Add(new Halo2Xbox.render_model.Shader(Cache, iOffset + 32 * i)); } #endregion #region ModelParts Block Reader.SeekTo(Address + 328); iCount = Reader.ReadInt32(); iOffset = Reader.ReadInt32() - Tag.Magic; for (int i = 0; i < iCount; i++) { ModelSections.Add(new ModelSection(Cache, Tag, iOffset + 200 * i, BoundingBoxes) { FacesIndex = i + Clusters.Count, VertsIndex = i + Clusters.Count, NodeIndex = 255 }); } #endregion #region GeometryInstances Block Reader.SeekTo(Address + 336); iCount = Reader.ReadInt32(); iOffset = Reader.ReadInt32() - Tag.Magic; for (int i = 0; i < iCount; i++) { GeomInstances.Add(new InstancedGeometry(Cache, iOffset + 88 * i, Clusters.Count)); } #endregion }
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 void LoadLocales(CacheBase Cache, Language Language) { cache = Cache; tag = null; label1.Enabled = cmbLang.Enabled = true; cmbLang.SelectedIndex = -1; cmbLang.SelectedIndex = (int)Language; }
public scenario_structure_bsp(CacheBase Cache, CacheBase.IndexItem Tag) { cache = Cache; int Address = Tag.Offset; EndianReader Reader = Cache.Reader; Reader.SeekTo(Address + 0xE0); XBounds = new Range <float>(Reader.ReadSingle(), Reader.ReadSingle()); YBounds = new Range <float>(Reader.ReadSingle(), Reader.ReadSingle()); ZBounds = new Range <float>(Reader.ReadSingle(), Reader.ReadSingle()); Reader.SeekTo(Address + 0x110); indexCount = Reader.ReadInt32() * 3; indexOffset = Reader.ReadInt32() - Tag.Magic; #region Lightmaps Block Reader.SeekTo(Address + 0x11C); int iCount = Reader.ReadInt32(); int iOffset = Reader.ReadInt32() - Tag.Magic; for (int i = 0; i < iCount; i++) { ModelSections.Add(new Lightmap(cache, iOffset + 32 * i, Tag.Magic) { VertsIndex = i, FacesIndex = i, NodeIndex = 255 }); } #endregion #region Create Shader List var sIDs = new List <int>(); for (int i = 0; i < ModelSections.Count; i++) { var section = ModelSections[i]; for (int j = 0; j < section.Submeshes.Count; j++) { var mesh = (Lightmap.Material)section.Submeshes[j]; if (!sIDs.Contains(mesh.shaderID)) { sIDs.Add(mesh.shaderID); } mesh.ShaderIndex = sIDs.IndexOf(mesh.shaderID); } } foreach (int ID in sIDs) { Shaders.Add(new Shader(ID)); } for (int i = 0; i < ModelSections.Count; i++) { Clusters.Add(new Cluster(i)); } #endregion }
public ModelSection(CacheBase Cache, CacheBase.IndexItem Tag, int Address, List <mode.BoundingBox> bounds) { EndianReader Reader = Cache.Reader; Reader.SeekTo(Address); Submeshes = new List <mode.ModelSection.Submesh>(); Subsets = new List <mode.ModelSection.Subset>(); VertexFormat = 0; vertcount = Reader.ReadUInt16(); if (vertcount == 0) { rSize = rOffset = rType = new int[0]; rawOffset = -1; return; } facecount = Reader.ReadUInt16(); int iCount, iOffset; if (bounds != null) { Reader.SeekTo(Address + 24); iCount = Reader.ReadInt32(); iOffset = Reader.ReadInt32() - Tag.Magic; bounds.Add(new BoundingBox(Cache, iOffset)); } Reader.SeekTo(Address + 40); rawOffset = Reader.ReadInt32(); rawSize = Reader.ReadInt32(); hSize = Reader.ReadInt32() + 8; Reader.ReadInt32(); iCount = Reader.ReadInt32(); iOffset = Reader.ReadInt32() - Tag.Magic; rSize = new int[iCount]; rOffset = new int[iCount]; rType = new int[iCount]; for (int i = 0; i < iCount; i++) { Reader.SeekTo(iOffset + 16 * i + 4); rType[i] = Reader.ReadInt32(); rSize[i] = Reader.ReadInt32(); rOffset[i] = Reader.ReadInt32(); } }
/// <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 LoadTagMeta(CacheBase Cache, CacheBase.IndexItem Tag, bool ShowInvisibles, string PluginsFolder) { cache = Cache; tag = Tag; pluginDir = PluginsFolder; chkInvis.Visible = true; isWorking = true; chkInvis.Checked = showInvis = ShowInvisibles; isWorking = false; var path = pluginDir + "\\" + cache.PluginDir + "\\" + tag.ClassCode.Replace("<", "_").Replace(">", "_").PadRight(4) + ".xml"; if (File.Exists(path)) { try { var fs = new FileStream(path, FileMode.Open); var doc = new XmlDocument(); doc.Load(fs); element = doc.DocumentElement; fs.Close(); fs.Dispose(); LoadControls(); } catch { pnlContainer.Controls.Clear(); var header = new mComment() { Location = new Point(5, 5) }; pnlContainer.Controls.Add(header); header.SetText("Error loading plugin: " + cache.PluginDir + "\\" + tag.ClassCode.Replace("<", "_").Replace(">", "_").PadRight(4) + ".xml", ""); } } else { pnlContainer.Controls.Clear(); var header = new mComment() { Location = new Point(5, 5) }; pnlContainer.Controls.Add(header); header.SetText("Plugin not found: " + cache.PluginDir + "\\" + tag.ClassCode.Replace("<", "_").Replace(">", "_").PadRight(4) + ".xml", ""); } }
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; }
public void LoadStrings(CacheBase Cache) { cache = Cache; tag = null; label1.Enabled = cmbLang.Enabled = false; var strings = sList = cache.Strings; lstStrings.Items.Clear(); for (int i = 0; i < strings.Count; i++) { lstStrings.Items.Add(new ListViewItem(new string[] { i.ToString("D6"), strings[i] })); } }
public mStructure(iValue Value, CacheBase Cache, CacheBase.IndexItem Tag, bool ShowInvisibles) { InitializeComponent(); value = Value; cache = Cache; showInvis = ShowInvisibles; tag = Tag; lblName.Text = value.Node.Attributes["name"].Value.ToUpper(); try { chunkSize = int.Parse(value.Node.Attributes["size"].Value); } catch { chunkSize = Convert.ToInt32(value.Node.Attributes["size"].Value, 16); } isLoaded = isLoading = false; }
public void LoadBSPTag(CacheBase Cache, CacheBase.IndexItem Tag, bool Force) { try { Clear(); loadBspTag(Cache, Tag, false, Force); } catch (Exception ex) { renderer1.ClearViewport(); Clear(); renderer1.Stop("Loading failed: " + ex.Message); tvRegions.Nodes.Clear(); this.Enabled = false; } }
/// <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 void LoadModelTag(CacheBase Cache, CacheBase.IndexItem Tag, bool Specular, bool UserPermFilter, bool Force) { try { Clear(); loadModelTag(Cache, Tag, Specular, UserPermFilter, Force); } catch (Exception ex) { renderer1.ClearViewport(); Clear(); renderer1.Stop("Loading failed: " + ex.Message); tvRegions.Nodes.Clear(); this.Enabled = false; } }
/// <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 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); }
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 shader_model(CacheBase Cache, CacheBase.IndexItem Tag) { EndianReader Reader = Cache.Reader; int Address = Tag.Offset; Reader.SeekTo(Address); switch (Tag.ClassCode) { case "soso": Reader.SeekTo(Address + 0xB0); break; case "senv": Reader.SeekTo(Address + 0x94); break; case "sgla": Reader.SeekTo(Address + 356); break; case "schi": Reader.SeekTo(Address + 228); break; case "scex": Reader.SeekTo(Address + 900); break; case "swat": case "smet": Reader.SeekTo(Address + 88); break; } baseMapID = Reader.ReadInt32(); Properties.Add(new ShaderProperties(this)); }
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; }
/// <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> /// 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 }
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> /// 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)); }
/// <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); }
public void LoadUnicTag(CacheBase Cache, CacheBase.IndexItem Tag) { LoadUnicTag(Cache, Tag, Language.English); }
public void LoadBinkTag(CacheBase Cache, CacheBase.IndexItem Tag) { cache = Cache; tag = Tag; }