diff --git a/WADExplorer/Properties/AssemblyInfo.cs b/WADExplorer/Properties/AssemblyInfo.cs index 225fa90..c011c4c 100644 --- a/WADExplorer/Properties/AssemblyInfo.cs +++ b/WADExplorer/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // É possível especificar todos os valores ou usar como padrão os Números de Build e da Revisão // utilizando o "*" como mostrado abaixo: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.5")] -[assembly: AssemblyFileVersion("1.0.5")] +[assembly: AssemblyVersion("1.0.6")] +[assembly: AssemblyFileVersion("1.0.6")] diff --git a/WADExplorer/REWAD/InsideItem.cs b/WADExplorer/REWAD/InsideItem.cs index 925a172..a64b9a3 100644 --- a/WADExplorer/REWAD/InsideItem.cs +++ b/WADExplorer/REWAD/InsideItem.cs @@ -75,10 +75,10 @@ public class InsideItem //[ReadOnly(true)] //[Browsable(false)] - public int ParentId { get; set; } + public int Priority { get; set; } - public int Unk2 { get; set; } - public int Unk3 { get; set; } + public int FolderStartIndex { get; set; } + public int FolderNextItemIndex { get; set; } [ReadOnly(true)] [Browsable(false)] @@ -104,9 +104,9 @@ public InsideItem( uint totalsize, uint size, - int parentID, - int unk2, - int unk3, + int priority, + int folderSI, + int folderNII, byte[] buffer = null, InsideItem parent = null @@ -121,9 +121,9 @@ public InsideItem( TotalSize = totalsize; Size = size; - ParentId = parentID; - Unk2 = unk2; - Unk3 = unk3; + Priority = priority; + FolderStartIndex = folderSI; + FolderNextItemIndex = folderNII; if (buffer != null) Buffer = buffer; @@ -131,7 +131,7 @@ public InsideItem( Parent = parent; // force this to be a folder if - if (Offset == 0 && Size == 0 && Unk2!=-1) + if (FolderStartIndex != -1) IsFolder = true; } } diff --git a/WADExplorer/REWAD/Package.cs b/WADExplorer/REWAD/Package.cs index 18dc6e4..ea80ae7 100644 --- a/WADExplorer/REWAD/Package.cs +++ b/WADExplorer/REWAD/Package.cs @@ -174,7 +174,7 @@ public virtual void ParseParents() if (item.IsFolder) { item.Children = new List(); - int id = item.Unk2; + int id = item.FolderStartIndex; if (id != -1) { @@ -182,10 +182,10 @@ public virtual void ParseParents() { item.Children.Add(Items[id]); Items[id].Parent = item; - if (id == Items[id].Unk3) + if (id == Items[id].FolderNextItemIndex) break; - id = Items[id].Unk3; + id = Items[id].FolderNextItemIndex; } } /* @@ -206,13 +206,18 @@ public virtual void RecastParentChainsForItem(InsideItem item, bool loopChain = if (!item.IsFolder) return; - item.Unk2 = item.Children[0].Index; + item.FolderStartIndex = item.Children[0].Index; + + if (item.Children.Count == 0) + item.FolderStartIndex = -1; + int idx = 0; foreach (InsideItem child in item.Children) { + child.Priority = item.Priority; if (idx != item.Children.Count-1) { - child.Unk3 = item.Children[idx + 1].Index; + child.FolderNextItemIndex = item.Children[idx + 1].Index; if (child.IsFolder & loopChain) RecastParentChainsForItem(child, true); @@ -220,7 +225,7 @@ public virtual void RecastParentChainsForItem(InsideItem item, bool loopChain = } else { - child.Unk3 = -1; + child.FolderNextItemIndex = -1; break; } } @@ -329,7 +334,7 @@ public InsideItem GetChildByPath(string path) if (pathNames[0].Contains(":")) { - throw new InvalidOperationException("The path cannot be a path to a disk unit"); + throw new InvalidOperationException("The path cannot be a path to a hard drive"); } InsideItem r = Items[0].FindFirstChildByName(pathNames[0].Replace("\0", "")); @@ -384,7 +389,7 @@ public virtual byte[] RegenerateAndReturnBuffer(bool saveInNewFormat = true) dataStream.SetLength(bufferSize); // regenerate parent chain - RecastParentChainsForItem(Items[0], true); + //RecastParentChainsForItem(Items[0], true); using (var f = new BinaryWriter(dataStream, Encoding.UTF8, false)) { f.Write(Magic); @@ -418,10 +423,10 @@ public virtual byte[] RegenerateAndReturnBuffer(bool saveInNewFormat = true) f.Write(item.Buffer.Length); f.Write(item.Buffer.Length); - f.Write(item.ParentId); + f.Write(item.Priority); - f.Write(item.Unk2); - f.Write(item.Unk3); + f.Write(item.FolderStartIndex); + f.Write(item.FolderNextItemIndex); lastOffset += (int)item.Buffer.Length; } @@ -444,7 +449,7 @@ public virtual byte[] RegenerateAndReturnBuffer(bool saveInNewFormat = true) return dataStream.GetBuffer(); } - public virtual void Dispose() + public virtual void DisposeStreams() { if (StreamPackage!=null) StreamPackage.Dispose(); @@ -452,7 +457,96 @@ public virtual void Dispose() f.Dispose(); } + /// + /// Adds items from a directory. + /// + /// The directory to add items as files or folders. + /// The item where the result is added, will be attached to the root of this package if null. + /// Specifies if it will add more items from each folder like a chain. + public void AddItemsFromDirectory(string directory, InsideItem relativeTo = null, bool addSiblings = true) + { + if (!Directory.Exists(directory)) + throw new InvalidOperationException("The directory does not exist"); + + string[] files = Directory.GetFiles(directory); + string[] directories = Directory.GetDirectories(directory); + + InsideItem _r = Items[0]; // root + if (relativeTo != null) + _r = relativeTo; + + // files + foreach (string entry in files) + { + InsideItem item = new InsideItem() + { + Name = Path.GetFileName(entry), + + Offset = 0, + Size = 0, + Buffer = new byte[0], + Children = new List() + }; + FileStream file = new FileStream(entry, FileMode.Open, FileAccess.Read); + using (var f = new BinaryReader(file, Encoding.UTF8, false)) + { + item.Buffer = f.ReadBytes((int)file.Length); + item.Size = (uint)item.Buffer.Length; + } + + item.Index = Items.Count; + Items.Add(item); + _r.Children.Add(item); + } + // directories + foreach (string entry in directories) + { + InsideItem item = new InsideItem() + { + Name = Path.GetFileName(entry), + + Offset = 0, + Size = 0, + Buffer = new byte[0], + Children = new List(), + IsFolder = true + }; + if (addSiblings) + AddItemsFromDirectory(entry, item, true); + + item.Index = Items.Count; + Items.Add(item); + _r.Children.Add(item); + } + } + + public static Package FromDirectory(string directory) + { + Package pkg = new Package(new List(1) { + + new InsideItem() + { + Children = new List(), + Offset = 0, + Size = 0, + CRC = -1, + Buffer = new byte[0] + } + + } + + ); + + // add the items + pkg.AddItemsFromDirectory(directory, null, true); + + pkg.RecastParentChainsForItem(pkg.Items[0],true); + + return pkg; + } + public Package() { } + public Package(List items) { Items = items; } public Package(string filename) { FileStream fileS = new FileStream(filename, FileMode.Open, FileAccess.Read); Load(fileS); @@ -589,7 +683,7 @@ public override byte[] RegenerateAndReturnBuffer(bool saveInNewFormat = false) dataStream.SetLength(bufferSize); // regenerate parent chain - RecastParentChainsForItem(Items[0], true); + //RecastParentChainsForItem(Items[0], true); using (var f = new BinaryWriter(dataStream, Encoding.UTF8, false)) { f.Write(Magic); @@ -623,10 +717,10 @@ public override byte[] RegenerateAndReturnBuffer(bool saveInNewFormat = false) //f.Write(item.Buffer.Length); f.Write(item.Buffer.Length); - f.Write(item.ParentId); + f.Write(item.Priority); - f.Write(item.Unk2); - f.Write(item.Unk3); + f.Write(item.FolderStartIndex); + f.Write(item.FolderNextItemIndex); lastOffset += (int)item.Buffer.Length; } @@ -650,7 +744,7 @@ public override byte[] RegenerateAndReturnBuffer(bool saveInNewFormat = false) return dataStream.GetBuffer(); } - public override void Dispose() + public override void DisposeStreams() { StreamPackage.Dispose(); f.Dispose(); diff --git a/WADExplorer/Window.Designer.cs b/WADExplorer/Window.Designer.cs index a453584..ae51325 100644 --- a/WADExplorer/Window.Designer.cs +++ b/WADExplorer/Window.Designer.cs @@ -32,6 +32,8 @@ private void InitializeComponent() System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Window)); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.NewBTN = new System.Windows.Forms.ToolStripMenuItem(); + this.NewFromFolderBTN = new System.Windows.Forms.ToolStripMenuItem(); this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.newFormatToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.oldFormatToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -82,6 +84,7 @@ private void InitializeComponent() this.AddButton = new System.Windows.Forms.Button(); this.DeleteButton = new System.Windows.Forms.Button(); this.PicturePanel = new System.Windows.Forms.Panel(); + this.ViewportEHost = new System.Windows.Forms.Integration.ElementHost(); this.PreviewUnavailableLabel = new System.Windows.Forms.Label(); this.AnyLabel = new System.Windows.Forms.Label(); this.TextPreview = new System.Windows.Forms.RichTextBox(); @@ -109,7 +112,9 @@ private void InitializeComponent() this.ToolStripReplaceButton = new System.Windows.Forms.ToolStripButton(); this.ToolStripExtractButton = new System.Windows.Forms.ToolStripButton(); this.ProgressBar = new System.Windows.Forms.ProgressBar(); - this.ViewportEHost = new System.Windows.Forms.Integration.ElementHost(); + this.NewEmpty = new System.Windows.Forms.ToolStripMenuItem(); + this.addNewFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AddFolderEditMenuBTN = new System.Windows.Forms.ToolStripMenuItem(); this.menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.SplitPanel)).BeginInit(); this.SplitPanel.Panel1.SuspendLayout(); @@ -139,6 +144,7 @@ private void InitializeComponent() // fileToolStripMenuItem // this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.NewBTN, this.openToolStripMenuItem, this.toolStripSeparator1, this.saveToolStripMenuItem, @@ -147,13 +153,29 @@ private void InitializeComponent() this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); this.fileToolStripMenuItem.Text = "&File"; // + // NewBTN + // + this.NewBTN.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.NewFromFolderBTN, + this.NewEmpty}); + this.NewBTN.Name = "NewBTN"; + this.NewBTN.Size = new System.Drawing.Size(180, 22); + this.NewBTN.Text = "New"; + // + // NewFromFolderBTN + // + this.NewFromFolderBTN.Name = "NewFromFolderBTN"; + this.NewFromFolderBTN.Size = new System.Drawing.Size(180, 22); + this.NewFromFolderBTN.Text = "From Folder"; + this.NewFromFolderBTN.Click += new System.EventHandler(this.NewFromFolderBTN_Click); + // // openToolStripMenuItem // this.openToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.newFormatToolStripMenuItem, this.oldFormatToolStripMenuItem}); this.openToolStripMenuItem.Name = "openToolStripMenuItem"; - this.openToolStripMenuItem.Size = new System.Drawing.Size(123, 22); + this.openToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.openToolStripMenuItem.Text = "&Open"; // // newFormatToolStripMenuItem @@ -173,19 +195,19 @@ private void InitializeComponent() // toolStripSeparator1 // this.toolStripSeparator1.Name = "toolStripSeparator1"; - this.toolStripSeparator1.Size = new System.Drawing.Size(120, 6); + this.toolStripSeparator1.Size = new System.Drawing.Size(177, 6); // // saveToolStripMenuItem // this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - this.saveToolStripMenuItem.Size = new System.Drawing.Size(123, 22); + this.saveToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.saveToolStripMenuItem.Text = "&Save"; this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click); // // saveAsToolStripMenuItem // this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem"; - this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(123, 22); + this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.saveAsToolStripMenuItem.Text = "&Save As..."; this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click); // @@ -495,15 +517,17 @@ private void InitializeComponent() this.replaceWithToolStripMenuItem1, this.deleteToolStripMenuItem1, this.addFileToolStripMenuItem1, + this.addNewFolderToolStripMenuItem, + this.AddFolderEditMenuBTN, this.renameToolStripMenuItem}); this.EditContextMenu.Name = "EditContextMenu"; - this.EditContextMenu.Size = new System.Drawing.Size(153, 114); + this.EditContextMenu.Size = new System.Drawing.Size(181, 180); // // extractToToolStripMenuItem1 // this.extractToToolStripMenuItem1.Enabled = false; this.extractToToolStripMenuItem1.Name = "extractToToolStripMenuItem1"; - this.extractToToolStripMenuItem1.Size = new System.Drawing.Size(152, 22); + this.extractToToolStripMenuItem1.Size = new System.Drawing.Size(180, 22); this.extractToToolStripMenuItem1.Text = "Extract To..."; this.extractToToolStripMenuItem1.Click += new System.EventHandler(this.ExtractButton_Click); // @@ -511,7 +535,7 @@ private void InitializeComponent() // this.replaceWithToolStripMenuItem1.Enabled = false; this.replaceWithToolStripMenuItem1.Name = "replaceWithToolStripMenuItem1"; - this.replaceWithToolStripMenuItem1.Size = new System.Drawing.Size(152, 22); + this.replaceWithToolStripMenuItem1.Size = new System.Drawing.Size(180, 22); this.replaceWithToolStripMenuItem1.Text = "Replace With..."; this.replaceWithToolStripMenuItem1.Click += new System.EventHandler(this.ReplaceButton_Click); // @@ -519,7 +543,7 @@ private void InitializeComponent() // this.deleteToolStripMenuItem1.Enabled = false; this.deleteToolStripMenuItem1.Name = "deleteToolStripMenuItem1"; - this.deleteToolStripMenuItem1.Size = new System.Drawing.Size(152, 22); + this.deleteToolStripMenuItem1.Size = new System.Drawing.Size(180, 22); this.deleteToolStripMenuItem1.Text = "Delete"; this.deleteToolStripMenuItem1.Click += new System.EventHandler(this.DeleteButton_Click); // @@ -527,14 +551,14 @@ private void InitializeComponent() // this.addFileToolStripMenuItem1.Enabled = false; this.addFileToolStripMenuItem1.Name = "addFileToolStripMenuItem1"; - this.addFileToolStripMenuItem1.Size = new System.Drawing.Size(152, 22); + this.addFileToolStripMenuItem1.Size = new System.Drawing.Size(180, 22); this.addFileToolStripMenuItem1.Text = "Add File(s)..."; this.addFileToolStripMenuItem1.Click += new System.EventHandler(this.AddButton_Click); // // renameToolStripMenuItem // this.renameToolStripMenuItem.Name = "renameToolStripMenuItem"; - this.renameToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.renameToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.renameToolStripMenuItem.Text = "Rename"; this.renameToolStripMenuItem.Click += new System.EventHandler(this.renameToolStripMenuItem_Click); // @@ -606,6 +630,18 @@ private void InitializeComponent() this.PicturePanel.Size = new System.Drawing.Size(414, 246); this.PicturePanel.TabIndex = 4; // + // ViewportEHost + // + this.ViewportEHost.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.ViewportEHost.Location = new System.Drawing.Point(0, 0); + this.ViewportEHost.Name = "ViewportEHost"; + this.ViewportEHost.Size = new System.Drawing.Size(411, 246); + this.ViewportEHost.TabIndex = 6; + this.ViewportEHost.Text = "3D Preview"; + this.ViewportEHost.Visible = false; + this.ViewportEHost.Child = null; + // // PreviewUnavailableLabel // this.PreviewUnavailableLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); @@ -892,17 +928,26 @@ private void InitializeComponent() this.ProgressBar.Size = new System.Drawing.Size(167, 15); this.ProgressBar.TabIndex = 5; // - // ViewportEHost + // NewEmpty // - this.ViewportEHost.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.ViewportEHost.Location = new System.Drawing.Point(0, 0); - this.ViewportEHost.Name = "ViewportEHost"; - this.ViewportEHost.Size = new System.Drawing.Size(411, 246); - this.ViewportEHost.TabIndex = 6; - this.ViewportEHost.Text = "3D Preview"; - this.ViewportEHost.Visible = false; - this.ViewportEHost.Child = null; + this.NewEmpty.Name = "NewEmpty"; + this.NewEmpty.Size = new System.Drawing.Size(180, 22); + this.NewEmpty.Text = "Empty"; + this.NewEmpty.Click += new System.EventHandler(this.NewEmpty_Click); + // + // addNewFolderToolStripMenuItem + // + this.addNewFolderToolStripMenuItem.Name = "addNewFolderToolStripMenuItem"; + this.addNewFolderToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.addNewFolderToolStripMenuItem.Text = "Add New Folder"; + this.addNewFolderToolStripMenuItem.Click += new System.EventHandler(this.NewFolderButton_Click); + // + // AddFolderEditMenuBTN + // + this.AddFolderEditMenuBTN.Name = "AddFolderEditMenuBTN"; + this.AddFolderEditMenuBTN.Size = new System.Drawing.Size(180, 22); + this.AddFolderEditMenuBTN.Text = "Add Folder"; + this.AddFolderEditMenuBTN.Click += new System.EventHandler(this.AddFolderEditMenuBTN_Click); // // Window // @@ -1022,6 +1067,11 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem renameToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem toX3DToolStripMenuItem; private System.Windows.Forms.Integration.ElementHost ViewportEHost; + private System.Windows.Forms.ToolStripMenuItem NewBTN; + private System.Windows.Forms.ToolStripMenuItem NewFromFolderBTN; + private System.Windows.Forms.ToolStripMenuItem NewEmpty; + private System.Windows.Forms.ToolStripMenuItem addNewFolderToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem AddFolderEditMenuBTN; } } diff --git a/WADExplorer/Window.cs b/WADExplorer/Window.cs index f943ec8..4be7197 100644 --- a/WADExplorer/Window.cs +++ b/WADExplorer/Window.cs @@ -41,6 +41,7 @@ public void OnFileBufferLoadFail(PackageLoadFileBufferFailureEventArgs e) if (!showErrors) return; + e.File.Buffer = new byte[0]; // make it non-null if (MessageBox.Show($"The file {e.File.Name} (0x{e.File.CRC:X4}/0x{e.File.Offset:X4}) has failed to load it's buffer\nExpect some errors for now on!\n\nShow more errors?","Warning",MessageBoxButtons.YesNo,MessageBoxIcon.Warning)==DialogResult.No) { showErrors = false; @@ -561,7 +562,7 @@ private void openToolStripMenuItem_Click(object sender, EventArgs e) if (fileDialog.ShowDialog() == DialogResult.OK) { if (OpenPackage != null) - OpenPackage.Dispose(); + OpenPackage.DisposeStreams(); // old format detection FileStream fs = new FileStream(fileDialog.FileName, FileMode.Open, FileAccess.Read); @@ -593,6 +594,8 @@ private void openToolStripMenuItem_Click(object sender, EventArgs e) showErrors = true; ProgressBar.Enabled = true; + + // format if (!loadedOldFormat) OpenPackage = new Package(); else @@ -603,8 +606,6 @@ private void openToolStripMenuItem_Click(object sender, EventArgs e) float pg = (float)(ev.File.Index) / ev.ToLoad; ProgressBar.Value = (int)(pg*100); ProgressBar.Update(); - //StatusLabel.Text = "Loading... " + ev.File.Index.ToString() + " / " + ev.ToLoad.ToString(); - //StatusStripbar.Update(); }; OpenPackage.Loaded += delegate { ProgressBar.Enabled = false; @@ -615,10 +616,8 @@ private void openToolStripMenuItem_Click(object sender, EventArgs e) InitTools(); }; - + // all set up, let's rock! OpenPackage.Load(fileDialog.FileName); - // LoadThread_FileName = fileDialog.FileName; - // LoadThread.Start(); } } @@ -657,7 +656,8 @@ private void ExtractButton_Click(object sender, EventArgs e) { FolderBrowserDialog folder = new FolderBrowserDialog() { - Description = "Choose a folder to extract the checked files" + Description = "Choose a folder to extract the checked files", + SelectedPath = Path.GetDirectoryName(OpenPackage.FileName) }; if (folder.ShowDialog() == DialogResult.OK) { @@ -730,7 +730,7 @@ private void ExtractButton_Click(object sender, EventArgs e) if (saveFile.ShowDialog() == DialogResult.OK) { - byte[] buffer = OpenPackage.GetItemBuffer(SelectedIndex); + byte[] buffer = OpenPackage.Items[SelectedIndex].Buffer; //OpenPackage.GetItemBuffer(SelectedIndex); FileStream file = new FileStream(saveFile.FileName, FileMode.Create, FileAccess.Write); file.Write(buffer, 0, buffer.Length); @@ -755,11 +755,12 @@ private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) { byte[] buffer = OpenPackage.RegenerateAndReturnBuffer(saveInNewFormat); - OpenPackage.Dispose(); // dispose old stream + OpenPackage.DisposeStreams(); // dispose old stream FileStream file = new FileStream(saveFile.FileName, FileMode.OpenOrCreate, FileAccess.Write); file.Write(buffer, 0, buffer.Length); file.Close(); + this.Text = this.Tag + " - " + OpenPackage.FileName; MessageBox.Show(String.Format("Successfully saved to '{0}'!", saveFile.FileName), "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } } @@ -810,7 +811,7 @@ private void saveToolStripMenuItem_Click(object sender, EventArgs e) byte[] buffer = OpenPackage.RegenerateAndReturnBuffer(saveInNewFormat); - OpenPackage.Dispose(); // dispose old stream + OpenPackage.DisposeStreams(); // dispose old stream FileStream file = new FileStream(OpenPackage.FileName, FileMode.OpenOrCreate, FileAccess.Write); file.Write(buffer, 0, buffer.Length); file.Close(); @@ -926,11 +927,17 @@ private void AddButton_Click(object sender, EventArgs e) Name = Path.GetFileName(file.Name), Index = OpenPackage.Items.Count, Buffer = buffer, - Offset = (uint)buffer.Length + Offset = (uint)buffer.Length, + + FolderStartIndex = -1, + Children = new List() }; OpenPackage.Items.Add(item); selectedItem.Children.Add(item); + + // fix + OpenPackage.RecastParentChainsForItem(selectedItem); } // update the list @@ -965,12 +972,18 @@ private void NewFolderButton_Click(object sender, EventArgs e) Index = OpenPackage.Items.Count, Children = new List(), Buffer = new byte[0], - Parent = selectedItem + Parent = selectedItem, + + // this folder is empty so add this + FolderStartIndex = -1 }; OpenPackage.Items.Add(folder); selectedItem.Children.Add(folder); + // fix + OpenPackage.RecastParentChainsForItem(selectedItem,true); + GenerateList(); } @@ -1427,5 +1440,72 @@ private void Window_KeyDown(object sender, KeyEventArgs e) Viewport.Viewport3D.Camera.UpDirection = new Vector3D(0,0,1); } } + + private void NewFromFolderBTN_Click(object sender, EventArgs e) + { + FolderBrowserDialog folder = new FolderBrowserDialog() + { + Description = "Select a folder to create a new .WAD archive file from" + }; + if (folder.ShowDialog()==DialogResult.OK) + { + OpenPackage = Package.FromDirectory(folder.SelectedPath); + OpenPackage.FileName = folder.SelectedPath + ".wad"; // append file name from folder + GenerateList(); + InitTools(); + } + } + + private void NewEmpty_Click(object sender, EventArgs e) + { + OpenPackage = new Package() + { + Items = new List(), + BaseOffset = 0 + }; + OpenPackage.Items.Add(new InsideItem() { Children = new List(), CRC = -1 } ); + OpenPackage.FileName = Path.GetFullPath("untitled") + ".wad"; + GenerateList(); + InitTools(); + } + + private void AddFolderEditMenuBTN_Click(object sender, EventArgs e) + { + if (FilePG.SelectedObject == null) + { + MessageBox.Show("Nothing is selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + InsideItem item = FilePG.SelectedObject as InsideItem; + if (item.IsFolder==false) + { + MessageBox.Show("Selected item is not a folder", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } + FolderBrowserDialog folder = new FolderBrowserDialog() + { + Description = "Choose a folder to add files from", + SelectedPath = Path.GetFullPath(OpenPackage.FileName).Replace(Path.GetFileName(OpenPackage.FileName), "") + }; + if (folder.ShowDialog() == DialogResult.OK) + { + InsideItem newFolder = new InsideItem() + { + Name = Path.GetFileName(folder.SelectedPath), + + Children = new List(), + IsFolder = true, + Buffer = new byte[0], + Offset = 0, + Size = 0, + Index = OpenPackage.Items.Count + }; + item.Children.Add(newFolder); + OpenPackage.Items.Add(newFolder); + + OpenPackage.AddItemsFromDirectory(folder.SelectedPath, newFolder, true); + GenerateList(); + } + } } } diff --git a/WADExplorer/Window.resx b/WADExplorer/Window.resx index dc6b487..a30f1b3 100644 --- a/WADExplorer/Window.resx +++ b/WADExplorer/Window.resx @@ -131,7 +131,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAS - EgAAAk1TRnQBSQFMAgEBCgEAAVgBAAFYAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + EgAAAk1TRnQBSQFMAgEBCgEAAWgBAAFoAQABEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA @@ -221,16 +221,16 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIKSURBVDhP3ZHNa9NgHMfz13hwdnNKOteBBxFkJ0WmOw3f - 8CDsIFMEQRAP2yrCxrb6whzbBKmgAwV3mSdnJwi6rrVha9PaLnEbrdM2T96TJvnuaQkzw5eLN3/kA08g - n8/zPIT5T2Z1/nBKWDhji296A5y1xcU+iInz8D/786Sfh03PcwF49Gngryli4hzEpYu/krjwM8y9ZCXP - MWBujEArjkFbn4EuzO1Gfkcj4ut7A0Fqs4fwZfpogMguewJ8vF12bUJ3j0EtTKC6fB0b86dQetjaFAuz - x5B/3In8ZAeK8e5mQHh1OhB4wdp1vYwaF0M1GUVl8RosiQe2M4BFAKMKqGWAbNJ1411GiYZ9vXGCDrt5 - N9ek6ICjwXMUaMke6Ikj0N53QVuivItAexsBBA6l0bZA4FHY8hwdjvwB9doC7O9zsMpTML7eg75+C3qh - H1quD+rqSSiZ4/DqBOlx1vN1+hsnw6Zry7B/vIZVeQpz6z4McRB68Qa0/GWoa71QuG7I6S6Q5EG4VgX8 - FGv7Og2MthmeXaPyE5ibYzCEO1QegMZfonIP3fUE5FQnyHIrpI/76E0F8DHW8nWGyd0NbekSJ21zz1w1 - Pw2FfwAlOwJlbQgydxty5ibI5wGQVD/IyhWQ8icvN94u+zrDZIdarmajB+Lc8P5vK9GQ8VeGQ0Y6GiLZ - wZYJX/+XYZgdRzoFbo+EiJcAAAAASUVORK5CYII= + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIJSURBVDhP3ZHNa9NgHMfz13hwdnNKOteBBxFkJ0UrnoZO + 8SDsIFMEQRAP2yrC5lzdYI5tglTBgYID9ebsBFHWdmvY2rS2S9xK60vz/tokX5+WMDN8uXjzRz7wBPL5 + PM9DqP9k1hcPZriXp2z+1ekAUZtf6gOfPAf/sz9P+knY9DwXgEeeJv6awCfPgl8+/yvJ/p9h5hkteo4B + c2sUWmkc2uYcdG5hJ/I7mhFf3x0IIswfwKfZwwEiO+wKsIlO2bUlsnscanEC9ZWr2Fo8gfJUe0sszh9B + 4UE3CtNdKCV6WwHu+clA4CltN/QqBCaOeiqG2tIVWCILfM0ClgQYdUCtAtI2WTffZZRJ2NebJ+iyW3dz + TYIOOBo8R4GWikJPHoL2rgfaMuFtBNqbCMAxKI91BAKTYctzdDjyezSE17C/LcCqzsD4fAf65g3oxQFo + +T6o68ehZI/Ca0hI36U9Xye/cTpsurYM+/sLWLVHMCv3YfBD0EvXoBUuQt04A4XphbzaAym1H65VAztD + 275OAmMdhmcLRH4Ic3scBneLyIPQ2AtEjpJdj0HOdENaaYf4cQ+5KQc2Tlu+TlH526GKLjJibe2xqxZm + obCTUHKjUDaGITM3IWevQ1obhJQZgJS+BKHywcvf65R9naJyw22Xc7F9CWZk75d0LGT8lZGQsRoLSbmh + tglf/5ehqB/nqwVCoFd9xgAAAABJRU5ErkJggg== @@ -247,61 +247,60 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJsSURBVDhPlZPvSxNxHMe/Qg+DxKYzBKGMBEtKdCfU3xE9 - MOhhlIm1MAODejRX2sa6yVrioNlOyEHBVJzY2FrKjP0Kl5gNoyid1ZpOd7ud7t59d90Dh5Pwzb2543O8 - X9/393scKan6znpyvPMaIfqrhNw/pEwPoFM3LpAT7SukTLdC6ui94fpJ5c1B9KiOkN5l2uCwMthfC2PN - 0a/ui+K3qUuyh21XtiubOqSKo32oaO7Cfxt8eMkIkpQHINGr4Dzi8SSqjz2RAY7Rcfh8vj1W4oTEXmnW - pZ0shO8GZJZNmB5nodZ0yYDq8z1Y+rJGuVKR9wUU7JnUUYAWVVX9GBoahsPh2OMiwBLXlM6LG3R1M7bi - LCY4Gj7XjiPlepQ3aWE022C322U7nU4Z4HK5dgFGNeI2n0AqZsafsB5rvttYiIRRW2tGMrkJQRCQyWSw - ufnvuWCO43Y3aBXlA8wL1Dzevf+I6tYeqFSPUdHShRHnBPx+v1zb6/UikUhgcHBwF+Apk5N2eOykA9hO - uSH+dmIhYEVllRGVzF1MegKYn59HJBJBMBiEKIqwWq2SEqef8Rkj5MU0xKQLubUX8Lj76CHeogADVEw3 - XO63CIVCmJubw+zsrLwFeh6iEqcA49msJKZo+DmEHya8Gb9HAZ2oqTHRQFBeNRAIYGZmRt4Kz/OwWCw5 - JU7Ip4eNK/x6bP1XbCS/9dmGqdf9ULdooSo00HRjzO1HNBpFOByWm6yurkosy6aVOCGLutM3F/VnuFhv - w8+IvjFb8PQdRlCrH0gGgzFrNBZ7YGBggwJYJV5SZfSPvEyIro3Ud7QpsxIi5C/g5fEXjDAm7AAAAABJ - RU5ErkJggg== + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJrSURBVDhPlZPhSxNxGMd/Qi+DxKZbCEIZCZaU6CbUnxG9 + MuhllMlqsQwMfDdX2oZtJiUOXG0GDgrmbAsT19rYYm6jrWE6jKKNLVrqdLfz5u7bb9e92HASPtyXO57j + +3m+v+c4UrPalG3kpPIGIdrrhAwdEbuHqDO3LpFTfSlSp0mRVnpvv3lafHOYetRKyPA6TXBUbBxc8bmu + yPe3l7kfziuCpk3Xio2d/XzD8RE0dKnx3wThVwqW50sAeHqVVUIikYXsxBMBYJl1wO1275NoJyT2Wr7J + 7xXA/tQhvz6GBYcBUrlaAMguDmL1W4Zy+SodCChr0amhABWamkYxNfUCFotln6oAq9bOXInbotON2EkY + MG+l5gt9OFavRX2nCnqjCWazWZDNZhMAdru9AjAr54pMGhsxI/6EtMi47yIeDqGlxYhsdhssyyKfz2N7 + +99zWVartTJBDycssMRSMfj46QtkPYOQSB6joVuNGds8PB6PEHtpaQnpdBqTk5MVgKeKXX6PwV7Oj+KG + C9xvG+L+Z2hs0qNRcR/ORT+i0SjC4TCCwSA4jsPExAQv2ulnfK5gS1wOXNaO3cxLLLpG6BLvUIAOEsUA + 7K4PWF5eRiAQgM/nE45A98GJdgrQny/w3AY1T4NNjuG94wEFKNHcPEYNQWGq3++H1+sVjsIwDMbHx3dF + OyFfH3akmM3YZubzTGlnzYR3b0Yh7VZBUk4gH8Ccy4NIJIJQKCQkSSaTvMFgyIl2QlY0Z2+vaM9ZY8Pt + v8LajkJZC/cUrFQ6xOt0+oJeXy06fYsCDKK9ZtXRP/IqIZpe0tbfK/ZqFCF/AYzk8Oibc+j6AAAAAElF + TkSuQmCC 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 - gg== + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVDhPlZM7S8NgFIZT0/4AF3HwCg4iOFW6iVovmz9A + cVAUcXJwUHRxE1QcNIROnVx0sKBSVBC8LILg4uDmpSApvVl7SdP76zmhqVWjrQceEj6+98k530eEUjUR + dsJRhTaijvhR9lQq9U5VyOfzMCOdTkOSpG3aaypxcDiZTEJV1TKxWAzRaBSBQECX+P1+yLL8Q2IhHLxB + 0zRkMhn9ySQSCZAYwWBQF1CX4I+4XC5DoldZwGEDFnAgHo8jFAp9GYfhTCn7KcjlcuUN/M5zG6OEw2G9 + E0VRfhd8p1LCnfB5RCKR2gWMIeFx+ExYxOs1C5hsNqufC0sYXvuXgLt4OdjBzVQXzgdtuBpvheSwyH8K + OGTg80i4X+yF5t1C8eEU6t4CLia7C2f91vmqAm7/eqIDKQpjZxRYqgfW2hHa6Id3QHz6VVAp4baLdx5U + VnS1EYdOa7EsoLsumkmYy7EWJN3TAIXSiwLeCN+ciNNh8ZUFXD10PSpJTH+m5/1N3M52QllqR3DZhscZ + C86d1sLJUN1KKS80Ez0EX40p7pEG+cgpKtz2cZ8Y2O0V1wVBED4Ah+iGr0VkoXkAAAAASUVORK5CYII= @@ -319,12 +318,12 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEuSURBVDhPjZO7boMwFIbJ3LFjyBApD1CJiq1TFalTh67J - 3ifI1kfq1qEv0KdACJC6wEQx91vd8xvZJWCUHOnjGOPv5yJjjOqWuGG7HaduX8AiTEIV5A1kdnjj6F3X - aWGM9UVR/NB6hKj6lyV0HscxT5KE53muyLJMhJCDJxlKyC+nOTSfpikvy1JQ17XoeBLSELAa5MfXZei6 - lCX6APSFcdu26hvIsQrAAYuCIDiTHMeZyWPOAog9Ar63W+48HEWvqmpRBhcDmqbRihJtwJdp8k/rWYAx - 0MlAG+C6rgp5v3sSfKzX2leZBURRxD3PE8i7A9/3rwqwERCGoRDGYG4qTwNQNu24HiFTdDKt/YVDqACL - 9jjNp71OGIM19C/k5NwP6lAbAn8XUq8BMjmG8Qe6EFLltSCxywAAAABJRU5ErkJggg== + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEtSURBVDhPjZM7boNAFEVJnTKlcWHJC7BERJcqipQqRdqk + 9wrSeUnuUmQDWQVCgJQGKmD4f5zJu4NmgmGQ/aTjwXjOMbbAGM0dccu2W06rfQGLMAk1kNeQ2duBY+37 + XkuSJKeyLBPaj4iaf1lC7+M45mma8qIoFHmeiwg5uJJhhPz6MYfOZ1nGq6oSNE0jVlwJaQjcDPLjfhn6 + XMoSfQDrwnHXdeo/kMcqgBdsCoLgTHIcZyaPOQsQTwj8bDbceXgXa13XizK4GGjbVitKtIFv0+Rf1osA + x0AnA23AdV0VOe6eBZ+rlfanzAJRFHHP8wTy24Hv+1cFbATCMBTCGJybytMAxqZb9oTIFJ1Me3/hECpg + 0T2eIaITxmAPY6wg535Qh1kTeLpQvQbI5BjGH4QWUsE5MrlUAAAAAElFTkSuQmCC