From 4bc51f8d69b60ab77c9a805cfac20108448740ec Mon Sep 17 00:00:00 2001 From: dexy Date: Fri, 22 Mar 2019 20:07:12 +1100 Subject: [PATCH] Added Save button to ModelForm, fixed material editor not updating all relevant geometries on parameter change --- Forms/ModelForm.Designer.cs | 73 +++++++++++++++ Forms/ModelForm.cs | 182 +++++++++++++++++++++++++++++++++++- Forms/ModelForm.resx | 25 +++++ Forms/ModelMatForm.cs | 42 ++++++++- 4 files changed, 319 insertions(+), 3 deletions(-) diff --git a/Forms/ModelForm.Designer.cs b/Forms/ModelForm.Designer.cs index 2264b9f..523c3eb 100644 --- a/Forms/ModelForm.Designer.cs +++ b/Forms/ModelForm.Designer.cs @@ -38,6 +38,11 @@ this.ConsolePanel = new System.Windows.Forms.Panel(); this.ConsoleTextBox = new CodeWalker.WinForms.TextBoxFix(); this.ToolsPanel = new System.Windows.Forms.Panel(); + this.MainToolbarPanel = new System.Windows.Forms.Panel(); + this.MainToolbar = new System.Windows.Forms.ToolStrip(); + this.SaveButton = new System.Windows.Forms.ToolStripSplitButton(); + this.SaveMenuButton = new System.Windows.Forms.ToolStripMenuItem(); + this.SaveAsMenuButton = new System.Windows.Forms.ToolStripMenuItem(); this.ToolsTabControl = new System.Windows.Forms.TabControl(); this.ToolsModelsTabPage = new System.Windows.Forms.TabPage(); this.ModelsTreeView = new CodeWalker.WinForms.TreeViewFix(); @@ -76,9 +81,12 @@ this.ToolsPanelHideButton = new System.Windows.Forms.Button(); this.ToolsDragPanel = new System.Windows.Forms.Panel(); this.ToolsPanelShowButton = new System.Windows.Forms.Button(); + this.SaveFileDialog = new System.Windows.Forms.SaveFileDialog(); this.StatusStrip.SuspendLayout(); this.ConsolePanel.SuspendLayout(); this.ToolsPanel.SuspendLayout(); + this.MainToolbarPanel.SuspendLayout(); + this.MainToolbar.SuspendLayout(); this.ToolsTabControl.SuspendLayout(); this.ToolsModelsTabPage.SuspendLayout(); this.ToolsMaterialsTabPage.SuspendLayout(); @@ -158,6 +166,7 @@ this.ToolsPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); this.ToolsPanel.BackColor = System.Drawing.SystemColors.ControlDark; + this.ToolsPanel.Controls.Add(this.MainToolbarPanel); this.ToolsPanel.Controls.Add(this.ToolsTabControl); this.ToolsPanel.Controls.Add(this.ToolsPanelHideButton); this.ToolsPanel.Controls.Add(this.ToolsDragPanel); @@ -167,6 +176,56 @@ this.ToolsPanel.TabIndex = 2; this.ToolsPanel.Visible = false; // + // MainToolbarPanel + // + this.MainToolbarPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.MainToolbarPanel.BackColor = System.Drawing.SystemColors.ControlDark; + this.MainToolbarPanel.Controls.Add(this.MainToolbar); + this.MainToolbarPanel.Location = new System.Drawing.Point(181, 2); + this.MainToolbarPanel.Name = "MainToolbarPanel"; + this.MainToolbarPanel.Size = new System.Drawing.Size(34, 24); + this.MainToolbarPanel.TabIndex = 4; + // + // MainToolbar + // + this.MainToolbar.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden; + this.MainToolbar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.SaveButton}); + this.MainToolbar.Location = new System.Drawing.Point(0, 0); + this.MainToolbar.Name = "MainToolbar"; + this.MainToolbar.Size = new System.Drawing.Size(34, 25); + this.MainToolbar.TabIndex = 7; + this.MainToolbar.Text = "Main Toolbar"; + // + // SaveButton + // + this.SaveButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.SaveButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.SaveMenuButton, + this.SaveAsMenuButton}); + this.SaveButton.Image = ((System.Drawing.Image)(resources.GetObject("SaveButton.Image"))); + this.SaveButton.ImageTransparentColor = System.Drawing.Color.Magenta; + this.SaveButton.Name = "SaveButton"; + this.SaveButton.Size = new System.Drawing.Size(32, 22); + this.SaveButton.Text = "Save"; + this.SaveButton.ButtonClick += new System.EventHandler(this.SaveButton_ButtonClick); + // + // SaveMenuButton + // + this.SaveMenuButton.Image = ((System.Drawing.Image)(resources.GetObject("SaveMenuButton.Image"))); + this.SaveMenuButton.ImageTransparentColor = System.Drawing.Color.Magenta; + this.SaveMenuButton.Name = "SaveMenuButton"; + this.SaveMenuButton.Size = new System.Drawing.Size(123, 22); + this.SaveMenuButton.Text = "Save"; + this.SaveMenuButton.Click += new System.EventHandler(this.SaveMenuButton_Click); + // + // SaveAsMenuButton + // + this.SaveAsMenuButton.Name = "SaveAsMenuButton"; + this.SaveAsMenuButton.Size = new System.Drawing.Size(123, 22); + this.SaveAsMenuButton.Text = "Save As..."; + this.SaveAsMenuButton.Click += new System.EventHandler(this.SaveAsMenuButton_Click); + // // ToolsTabControl // this.ToolsTabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) @@ -639,6 +698,10 @@ this.ToolsPanelShowButton.UseVisualStyleBackColor = true; this.ToolsPanelShowButton.Click += new System.EventHandler(this.ToolsPanelShowButton_Click); // + // SaveFileDialog + // + this.SaveFileDialog.Filter = "All files|*.*"; + // // ModelForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -665,6 +728,10 @@ this.ConsolePanel.ResumeLayout(false); this.ConsolePanel.PerformLayout(); this.ToolsPanel.ResumeLayout(false); + this.MainToolbarPanel.ResumeLayout(false); + this.MainToolbarPanel.PerformLayout(); + this.MainToolbar.ResumeLayout(false); + this.MainToolbar.PerformLayout(); this.ToolsTabControl.ResumeLayout(false); this.ToolsModelsTabPage.ResumeLayout(false); this.ToolsMaterialsTabPage.ResumeLayout(false); @@ -725,5 +792,11 @@ private System.Windows.Forms.Button TextureViewerButton; private System.Windows.Forms.CheckBox HDTexturesCheckBox; private System.Windows.Forms.Button MaterialEditorButton; + private System.Windows.Forms.Panel MainToolbarPanel; + private System.Windows.Forms.ToolStrip MainToolbar; + private System.Windows.Forms.ToolStripSplitButton SaveButton; + private System.Windows.Forms.ToolStripMenuItem SaveMenuButton; + private System.Windows.Forms.ToolStripMenuItem SaveAsMenuButton; + private System.Windows.Forms.SaveFileDialog SaveFileDialog; } } \ No newline at end of file diff --git a/Forms/ModelForm.cs b/Forms/ModelForm.cs index 4012ebb..d443bbf 100644 --- a/Forms/ModelForm.cs +++ b/Forms/ModelForm.cs @@ -101,7 +101,10 @@ namespace CodeWalker.Forms ModelMatForm materialForm = null; + private bool modelModified = false; + ExploreForm exploreForm = null; + RpfFileEntry rpfFileEntry = null; @@ -109,6 +112,7 @@ namespace CodeWalker.Forms { InitializeComponent(); + exploreForm = ExpForm; gameFileCache = ExpForm?.GetFileCache(); @@ -569,6 +573,7 @@ namespace CodeWalker.Forms FileName = ydr.Name; Ydr = ydr; + rpfFileEntry = Ydr.RpfFileEntry; if (ydr.Drawable != null) { @@ -583,6 +588,7 @@ namespace CodeWalker.Forms FileName = ydd.Name; Ydd = ydd; + rpfFileEntry = Ydd.RpfFileEntry; UpdateModelsUI(ydd.Dict); @@ -594,6 +600,7 @@ namespace CodeWalker.Forms FileName = yft.Name; Yft = yft; + rpfFileEntry = Yft.RpfFileEntry; var dr = yft.Fragment?.Drawable; if (dr != null) @@ -609,6 +616,7 @@ namespace CodeWalker.Forms FileName = ybn.Name; Ybn = ybn; + rpfFileEntry = Ybn.RpfFileEntry; if (Ybn.Bounds != null) { @@ -623,6 +631,7 @@ namespace CodeWalker.Forms FileName = ypt.Name; Ypt = ypt; + rpfFileEntry = Ypt.RpfFileEntry; UpdateModelsUI(ypt.DrawableDict); @@ -634,6 +643,7 @@ namespace CodeWalker.Forms FileName = ynv.Name; Ynv = ynv; + rpfFileEntry = Ynv.RpfFileEntry; if (ynv.Nav.SectorTree != null) { @@ -655,7 +665,7 @@ namespace CodeWalker.Forms private void UpdateFormTitle() { - Text = fileName + " - CodeWalker by dexyfex"; + Text = fileName + (modelModified ? "*" : "") + " - CodeWalker by dexyfex"; } @@ -1077,6 +1087,161 @@ namespace CodeWalker.Forms } + public void OnModelModified() + { + modelModified = true; + UpdateFormTitle(); + } + + + + + + private void Save(bool saveAs = false) + { + var editMode = exploreForm?.EditMode ?? false; + + if (string.IsNullOrEmpty(FilePath)) + { + if (!editMode) saveAs = true; + if (rpfFileEntry?.Parent == null) saveAs = true; + } + else + { + if ((FilePath.ToLowerInvariant().StartsWith(GTAFolder.CurrentGTAFolder.ToLowerInvariant()))) saveAs = true; + if (!File.Exists(FilePath)) saveAs = true; + } + + var fn = FilePath; + if (saveAs) + { + if (!string.IsNullOrEmpty(fn)) + { + var dir = new FileInfo(fn).DirectoryName; + if (!Directory.Exists(dir)) dir = ""; + SaveFileDialog.InitialDirectory = dir; + } + SaveFileDialog.FileName = FileName; + + var fileExt = Path.GetExtension(FileName); + if ((fileExt.Length > 1) && fileExt.StartsWith(".")) + { + fileExt = fileExt.Substring(1); + } + SaveFileDialog.Filter = fileExt.ToUpperInvariant() + " files|*." + fileExt + "|All files|*.*"; + + if (SaveFileDialog.ShowDialog() != DialogResult.OK) return; + fn = SaveFileDialog.FileName; + } + + + + byte[] fileBytes = null; + +#if !DEBUG + try + { +#endif + if (Ydr != null) + { + fileBytes = Ydr.Save(); + } + else if (Ydd != null) + { + fileBytes = Ydd.Save(); + } + else if (Yft != null) + { + fileBytes = Yft.Save(); + } + else if (Ybn != null) + { + fileBytes = Ybn.Save(); + } + else if (Ypt != null) + { + fileBytes = Ypt.Save(); + } + else if (Ynv != null) + { + fileBytes = Ynv.Save(); + } +#if !DEBUG + } + catch(Exception ex) + { + MessageBox.Show("Error saving file!\n" + ex.ToString()); + return; + } +#endif + if (fileBytes == null) + { + MessageBox.Show("Error saving file!\n fileBytes was null!"); + return; + } + + + var rpfSave = editMode && (rpfFileEntry?.Parent != null) && !saveAs; + + if (rpfSave) + { + if (!rpfFileEntry.Path.ToLowerInvariant().StartsWith("mods")) + { + if (MessageBox.Show("This file is NOT located in the mods folder - Are you SURE you want to save this file?\r\nWARNING: This could cause permanent damage to your game!!!", "WARNING: Are you sure about this?", MessageBoxButtons.YesNo) != DialogResult.Yes) + { + return;//that was a close one + } + } + + try + { + if (!(exploreForm?.EnsureRpfValidEncryption(rpfFileEntry.File) ?? false)) return; + + var newentry = RpfFile.CreateFile(rpfFileEntry.Parent, rpfFileEntry.Name, fileBytes); + if (newentry != rpfFileEntry) + { } + rpfFileEntry = newentry; + + exploreForm?.RefreshMainListViewInvoke(); //update the file details in explorer... + + StatusLabel.Text = rpfFileEntry.Name + " saved successfully at " + DateTime.Now.ToString(); + + //victory! + } + catch (Exception ex) + { + MessageBox.Show("Error saving file to RPF! The RPF archive may be corrupted...\r\n" + ex.ToString(), "Really Bad Error"); + } + + } + else + { + try + { + File.WriteAllBytes(fn, fileBytes); + + fileName = Path.GetFileName(fn); + FilePath = fn; + + StatusLabel.Text = fileName + " saved successfully at " + DateTime.Now.ToString(); + } + catch (Exception ex) + { + MessageBox.Show("Error writing file to disk!\n" + ex.ToString()); + return; + } + } + + + modelModified = false; + UpdateFormTitle(); + + } + + + + + @@ -1656,5 +1821,20 @@ namespace CodeWalker.Forms } + + private void SaveButton_ButtonClick(object sender, EventArgs e) + { + Save(); + } + + private void SaveMenuButton_Click(object sender, EventArgs e) + { + Save(); + } + + private void SaveAsMenuButton_Click(object sender, EventArgs e) + { + Save(true); + } } } diff --git a/Forms/ModelForm.resx b/Forms/ModelForm.resx index 0f54839..138334d 100644 --- a/Forms/ModelForm.resx +++ b/Forms/ModelForm.resx @@ -123,7 +123,32 @@ 166, 17 + + 276, 17 + + + 276, 17 + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABWSURBVDhPY6AK+Pbt238S8PsvX74YQLVCAEjCyckJjj+8 + /wjHyGIguq2tDdMQUgwAYZghUO2kGwDCID1Q7fgNQMbIamhrADF41IBBaQA5GKqdEsDAAADtDPd9n5qK + lQAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABWSURBVDhPY6AK+Pbt238S8PsvX74YQLVCAEjCyckJjj+8 + /wjHyGIguq2tDdMQUgwAYZghUO2kGwDCID1Q7fgNQMbIamhrADF41IBBaQA5GKqdEsDAAADtDPd9n5qK + lQAAAABJRU5ErkJggg== + + + + 397, 17 + AAABAAMAICAAAAAAGACoDAAANgAAABAQAAAAABgAaAMAAN4MAABAQAAAAAAYACgyAABGEAAAKAAAACAA diff --git a/Forms/ModelMatForm.cs b/Forms/ModelMatForm.cs index 26bbbef..8258841 100644 --- a/Forms/ModelMatForm.cs +++ b/Forms/ModelMatForm.cs @@ -15,6 +15,8 @@ namespace CodeWalker.Forms public partial class ModelMatForm : Form { private ModelForm ModelForm; + private DrawableBase Drawable; + private Dictionary DrawableDict; public ModelMatForm(ModelForm modelForm) @@ -28,6 +30,7 @@ namespace CodeWalker.Forms public void LoadModel(DrawableBase drawable) { + Drawable = drawable; ModelsTreeView.Nodes.Clear(); ModelsTreeView.ShowRootLines = false; @@ -64,6 +67,8 @@ namespace CodeWalker.Forms } public void LoadModels(Dictionary dict) { + DrawableDict = dict; + ModelsTreeView.Nodes.Clear(); //ModelsTreeView.ShowRootLines = true; @@ -198,11 +203,16 @@ namespace CodeWalker.Forms if (parm.DataType == 0)//texture { var tex = parm.Data as TextureBase; - if (!(tex is Texture))//don't do this for embedded textures! + var ttex = tex as Texture; + if (ttex == null)//don't do this for embedded textures! { tex.Name = txt; tex.NameHash = JenkHash.GenHash(txt.ToLowerInvariant()); } + else + { + //TODO: modify embedded textures! + } } else if (parm.DataType == 1)//Vector4 { @@ -228,11 +238,39 @@ namespace CodeWalker.Forms var geom = ModelsTreeView.SelectedNode?.Tag as DrawableGeometry; if (geom != null) { - geom.UpdateRenderableParameters = true; + if (Drawable != null) + { + UpdateRenderableParams(Drawable, geom.Shader); + } + if (DrawableDict != null) + { + foreach (var dwbl in DrawableDict.Values) + { + UpdateRenderableParams(dwbl, geom.Shader); + } + } } + ModelForm.OnModelModified(); + } + private void UpdateRenderableParams(DrawableBase dwbl, ShaderFX shader) + { + foreach (var model in dwbl.AllModels) + { + if (model?.Geometries?.data_items == null) continue; + foreach (var geom in model.Geometries.data_items) + { + if (geom.Shader == shader) + { + geom.UpdateRenderableParameters = true; + } + } + } + } + + private void ModelMatForm_FormClosed(object sender, FormClosedEventArgs e) { ModelForm.OnMaterialFormClosed();