diff --git a/MDF-Manager/App.xaml b/MDF-Manager/App.xaml
index 02be92f..27725ca 100644
--- a/MDF-Manager/App.xaml
+++ b/MDF-Manager/App.xaml
@@ -1,9 +1,9 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/MDF-Manager/App.xaml.cs b/MDF-Manager/App.xaml.cs
index 3bda4a3..1f89031 100644
--- a/MDF-Manager/App.xaml.cs
+++ b/MDF-Manager/App.xaml.cs
@@ -1,17 +1,17 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Windows;
-
-namespace MDF_Manager
-{
- ///
- /// Interaction logic for App.xaml
- ///
- public partial class App : Application
- {
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace MDF_Manager
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+}
diff --git a/MDF-Manager/AssemblyInfo.cs b/MDF-Manager/AssemblyInfo.cs
index 8b5504e..74087a1 100644
--- a/MDF-Manager/AssemblyInfo.cs
+++ b/MDF-Manager/AssemblyInfo.cs
@@ -1,10 +1,10 @@
-using System.Windows;
-
-[assembly: ThemeInfo(
- ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
- //(used if a resource is not found in the page,
- // or application resource dictionaries)
- ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
- //(used if a resource is not found in the page,
- // app, or any theme specific resource dictionaries)
-)]
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/MDF-Manager/BatchConverter.xaml b/MDF-Manager/BatchConverter.xaml
index ee89299..41f91d1 100644
--- a/MDF-Manager/BatchConverter.xaml
+++ b/MDF-Manager/BatchConverter.xaml
@@ -1,28 +1,28 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MDF-Manager/BatchConverter.xaml.cs b/MDF-Manager/BatchConverter.xaml.cs
index d595e2e..9e4a743 100644
--- a/MDF-Manager/BatchConverter.xaml.cs
+++ b/MDF-Manager/BatchConverter.xaml.cs
@@ -1,96 +1,96 @@
-using MDF_Manager.Classes;
-using Microsoft.Win32;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Shapes;
-using Path = System.IO.Path;
-
-namespace MDF_Manager
-{
- ///
- /// Interaction logic for BatchConverter.xaml
- ///
- public partial class BatchConverter : Window
- {
- private List MDFTypeList = new List();
- public List TypeList { get => MDFTypeList; }
- public MDFTypes ExportType { get; set; }
- public BatchConverter()
- {
- InitializeComponent();
- foreach(MDFTypes type in Enum.GetValues(typeof(MDFTypes)))
- {
- MDFTypeList.Add(type);
- }
- ExportType = MDFTypes.Sunbreak;
- DataContext = this;
- }
-
- private void AddToList(object sender, RoutedEventArgs e)
- {
- OpenFileDialog importFile = new OpenFileDialog();
- importFile.Multiselect = true;
- importFile.Filter = MainWindow.MDFFilter;
- if (importFile.ShowDialog() == true)
- {
- foreach(string file in importFile.FileNames)
- {
- MDFView.Items.Add(new ListBoxItem() { Content = file });
- }
- }
- }
-
- private void RemoveSelected(object sender, RoutedEventArgs e)
- {
- MDFView.Items.Remove(MDFView.SelectedItem);
- MDFView.SelectedIndex = 0;
- }
-
- public void ConvertSingle(string path, string output)
- {
- BinaryReader readFile = HelperFunctions.OpenFileR(path, Encoding.Unicode);
- if (readFile != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(path).Replace(".", ""));
- MDFFile file = new MDFFile(path, readFile, type);
- //now export with proper format/path
- string outPath = Path.ChangeExtension(Path.Combine(output, Path.GetFileName(path)), ((int)ExportType).ToString());
- BinaryWriter bw = HelperFunctions.OpenFileW(outPath, Encoding.Unicode);
- if(bw != null)
- {
- file.Export(bw, ExportType);
- }
- bw.Close();
- }
- readFile.Close();
- }
-
- public void ConvertAll(object sender, RoutedEventArgs e)
- {
- OpenFileDialog exportFile = new OpenFileDialog();
- exportFile.CheckFileExists = false;
- exportFile.FileName = "Save Here";
- if(exportFile.ShowDialog() == true)
- {
- foreach (ListBoxItem item in MDFView.Items)
- {
- string path = item.Content as string;
- ConvertSingle(path, System.IO.Path.GetDirectoryName(exportFile.FileName));
- }
- MessageBox.Show("Batch conversion completed successfully!");
- this.Close();
- }
- }
- }
-}
+using MDF_Manager.Classes;
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+using Path = System.IO.Path;
+
+namespace MDF_Manager
+{
+ ///
+ /// Interaction logic for BatchConverter.xaml
+ ///
+ public partial class BatchConverter : Window
+ {
+ private List MDFTypeList = new List();
+ public List TypeList { get => MDFTypeList; }
+ public MDFTypes ExportType { get; set; }
+ public BatchConverter()
+ {
+ InitializeComponent();
+ foreach(MDFTypes type in Enum.GetValues(typeof(MDFTypes)))
+ {
+ MDFTypeList.Add(type);
+ }
+ ExportType = MDFTypes.Sunbreak;
+ DataContext = this;
+ }
+
+ private void AddToList(object sender, RoutedEventArgs e)
+ {
+ OpenFileDialog importFile = new OpenFileDialog();
+ importFile.Multiselect = true;
+ importFile.Filter = MainWindow.MDFFilter;
+ if (importFile.ShowDialog() == true)
+ {
+ foreach(string file in importFile.FileNames)
+ {
+ MDFView.Items.Add(new ListBoxItem() { Content = file });
+ }
+ }
+ }
+
+ private void RemoveSelected(object sender, RoutedEventArgs e)
+ {
+ MDFView.Items.Remove(MDFView.SelectedItem);
+ MDFView.SelectedIndex = 0;
+ }
+
+ public void ConvertSingle(string path, string output)
+ {
+ BinaryReader readFile = HelperFunctions.OpenFileR(path, Encoding.Unicode);
+ if (readFile != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(path).Replace(".", ""));
+ MDFFile file = new MDFFile(path, readFile, type);
+ //now export with proper format/path
+ string outPath = Path.ChangeExtension(Path.Combine(output, Path.GetFileName(path)), ((int)ExportType).ToString());
+ BinaryWriter bw = HelperFunctions.OpenFileW(outPath, Encoding.Unicode);
+ if(bw != null)
+ {
+ file.Export(bw, ExportType);
+ }
+ bw.Close();
+ }
+ readFile.Close();
+ }
+
+ public void ConvertAll(object sender, RoutedEventArgs e)
+ {
+ OpenFileDialog exportFile = new OpenFileDialog();
+ exportFile.CheckFileExists = false;
+ exportFile.FileName = "Save Here";
+ if(exportFile.ShowDialog() == true)
+ {
+ foreach (ListBoxItem item in MDFView.Items)
+ {
+ string path = item.Content as string;
+ ConvertSingle(path, System.IO.Path.GetDirectoryName(exportFile.FileName));
+ }
+ MessageBox.Show("Batch conversion completed successfully!");
+ this.Close();
+ }
+ }
+ }
+}
diff --git a/MDF-Manager/Classes/Compendium.cs b/MDF-Manager/Classes/Compendium.cs
index 17270c6..1242b1f 100644
--- a/MDF-Manager/Classes/Compendium.cs
+++ b/MDF-Manager/Classes/Compendium.cs
@@ -1,191 +1,210 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MDF_Manager.Classes
-{
- public class CompendiumEntry
- {
- //library entry only needs 2 things, material name/index (name will let it be future-proof) and filepath
- private string _MDFPath;
- public string Header { get; set; }
- public ObservableCollection Items { get; set; }
- public string MDFPath { get => _MDFPath; set { _MDFPath = value; Header = value;} }
- public CompendiumEntry()
- {
- Items = new ObservableCollection();
- MDFPath = "";
-
- }
- public CompendiumEntry(string path)
- {
- Items = new ObservableCollection(); //how did this not crash
- MDFPath = path;
- }
- }
- public class CompendiumEntryHeader : IComparable
- {
- private string _MMTRName;
- public string Header { get; set; }
- public ObservableCollection Items { get; set; }
- public string MMTRName { get => _MMTRName; set { _MMTRName = value; Header = value; } }
- public CompendiumEntryHeader()
- {
- Items = new ObservableCollection();
- MMTRName = "";
- }
- public CompendiumEntryHeader(string mmtr)
- {
- Items = new ObservableCollection();
- MMTRName = mmtr;
- }
- public int FindEntry(string path)
- {
- for(int i = 0; i < Items.Count; i++)
- {
- if(Items[i].MDFPath == path)
- {
- return i;
- }
- }
- return -1;//the wanted approach here
- }
- public int CompareTo(CompendiumEntryHeader compare)
- {
- if (compare == null)
- {
- return 1;
- }
- else return this.MMTRName.CompareTo(compare.MMTRName);
- }
- }
- public class CompendiumTopLevel : INotifyPropertyChanged
- {
- //entryHeader contains children as
- private string _Game;
- public string Header { get; set; }
- private List _Items = new List();
- public ObservableCollection Items { get => new ObservableCollection(_Items); set { _Items = new List(value); OnPropertyChanged("Items"); } }
- public string Game { get => _Game; set { _Game = value; Header = value; } }
- public CompendiumTopLevel()
- {
- Game = "";
- }
- public CompendiumTopLevel(string game)
- {
- Game = game;
- }
- public void ClearChildren()
- {
- _Items.Clear();
- }
- public void Sort()
- {
- _Items.Sort();
- OnPropertyChanged("Items");
- }
- public void AddChild(CompendiumEntryHeader ceh)
- {
- _Items.Add(ceh);
- }
- public CompendiumEntryHeader FindItem(Predicate predicate)
- {
- return _Items.Find(predicate);
- }
- protected void OnPropertyChanged([CallerMemberName] string name = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- }
- public event PropertyChangedEventHandler PropertyChanged;
- }
- public class Compendium : INotifyPropertyChanged
- {
- public ObservableCollection entries { get; set; }
- //here, set references to each one, so we can attach to them
- public CompendiumTopLevel RE7 { get; set; }
- public CompendiumTopLevel RE2DMC5 { get; set; }
- public CompendiumTopLevel RE3 { get; set; }
- public CompendiumTopLevel MHRiseRE8 { get; set; }
- public CompendiumTopLevel RERT { get; set; }
- public CompendiumTopLevel Sunbreak { get; set; }
- public CompendiumTopLevel SF6 { get; set; }
-
- protected void OnPropertyChanged([CallerMemberName] string name = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- }
- public Compendium()
- {
- RE7 = new CompendiumTopLevel("Version 6 (RE7)");
- RE2DMC5 = new CompendiumTopLevel("Version 10 (RE2/DMC5)");
- RE3 = new CompendiumTopLevel("Version 13 (RE3)");
- MHRiseRE8 = new CompendiumTopLevel("Version 19 (MHRise/RE8)");
- RERT = new CompendiumTopLevel("Version 21 (RE Raytracing)");
- Sunbreak = new CompendiumTopLevel("Version 23 (MHRS)");
- SF6 = new CompendiumTopLevel("Version 31 (SF6)");
- entries = new ObservableCollection { RE7, RE2DMC5, RE3, MHRiseRE8, RERT, Sunbreak, SF6 };
-
- }
- public void SetEntries(ObservableCollection newEntries)
- {
- foreach (CompendiumTopLevel entry in newEntries)
- {
- switch (entry.Game)
- {
- case "RE7":
- case "Version 6 (RE7)":
- RE7.Items = entry.Items;
- break;
- case "RE2/DMC5":
- case "Version 10 (RE2/DMC5)":
- RE2DMC5.Items = entry.Items;
- break;
- case "RE3":
- case "Version 13 (RE3)":
- RE3.Items = entry.Items;
- break;
- case "MHRise/RE8":
- case "Version 19 (MHRise/RE8)":
- MHRiseRE8.Items = entry.Items;
- break;
- case "Version 21 (RE Raytracing)":
- RERT.Items = entry.Items;
- break;
- case "Version 23 (MHRS)":
- Sunbreak.Items = entry.Items;
- break;
- case "Version 31 (SF6)":
- SF6.Items = entry.Items;
- break;
- }
- }
- OnPropertyChanged("entries");
- Sort();
- }
-
- public void ClearList()
- {
- foreach(CompendiumTopLevel ctl in entries)
- {
- ctl.ClearChildren();
- }
- }
-
- public void Sort()
- {
- RE7.Sort();
- RE2DMC5.Sort();
- RE3.Sort();
- MHRiseRE8.Sort();
- RERT.Sort();
- Sunbreak.Sort();
- OnPropertyChanged("entries");
- }
- public event PropertyChangedEventHandler PropertyChanged;
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MDF_Manager.Classes
+{
+ public class CompendiumEntry
+ {
+ //library entry only needs 2 things, material name/index (name will let it be future-proof) and filepath
+ private string _MDFPath;
+ public string Header { get; set; }
+ public ObservableCollection Items { get; set; }
+ public string MDFPath { get => _MDFPath; set { _MDFPath = value; Header = value;} }
+ public CompendiumEntry()
+ {
+ Items = new ObservableCollection();
+ MDFPath = "";
+
+ }
+ public CompendiumEntry(string path)
+ {
+ Items = new ObservableCollection(); //how did this not crash
+ MDFPath = path;
+ }
+ }
+ public class CompendiumEntryHeader : IComparable
+ {
+ private string _MMTRName;
+ public string Header { get; set; }
+ public ObservableCollection Items { get; set; }
+ public string MMTRName { get => _MMTRName; set { _MMTRName = value; Header = value; } }
+ public CompendiumEntryHeader()
+ {
+ Items = new ObservableCollection();
+ MMTRName = "";
+ }
+ public CompendiumEntryHeader(string mmtr)
+ {
+ Items = new ObservableCollection();
+ MMTRName = mmtr;
+ }
+ public int FindEntry(string path)
+ {
+ for(int i = 0; i < Items.Count; i++)
+ {
+ if(Items[i].MDFPath == path)
+ {
+ return i;
+ }
+ }
+ return -1;//the wanted approach here
+ }
+ public int CompareTo(CompendiumEntryHeader compare)
+ {
+ if (compare == null)
+ {
+ return 1;
+ }
+ else return this.MMTRName.CompareTo(compare.MMTRName);
+ }
+ }
+ public class CompendiumTopLevel : INotifyPropertyChanged
+ {
+ //entryHeader contains children as
+ private string _Game;
+ public string Header { get; set; }
+ private List _Items = new List();
+ public ObservableCollection Items { get => new ObservableCollection(_Items); set { _Items = new List(value); OnPropertyChanged("Items"); } }
+ public string Game { get => _Game; set { _Game = value; Header = value; } }
+ public CompendiumTopLevel()
+ {
+ Game = "";
+ }
+ public CompendiumTopLevel(string game)
+ {
+ Game = game;
+ }
+ public void ClearChildren()
+ {
+ _Items.Clear();
+ }
+ public void Sort()
+ {
+ _Items.Sort();
+ OnPropertyChanged("Items");
+ }
+ public void AddChild(CompendiumEntryHeader ceh)
+ {
+ _Items.Add(ceh);
+ }
+ public CompendiumEntryHeader FindItem(Predicate predicate)
+ {
+ return _Items.Find(predicate);
+ }
+ protected void OnPropertyChanged([CallerMemberName] string name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+ public event PropertyChangedEventHandler PropertyChanged;
+ }
+ public class Compendium : INotifyPropertyChanged
+ {
+ public ObservableCollection entries { get; set; }
+ //here, set references to each one, so we can attach to them
+ public CompendiumTopLevel RE7 { get; set; }
+ public CompendiumTopLevel RE2DMC5 { get; set; }
+ public CompendiumTopLevel RE3 { get; set; }
+ public CompendiumTopLevel MHRiseRE8 { get; set; }
+ public CompendiumTopLevel RERT { get; set; }
+ public CompendiumTopLevel Sunbreak { get; set; }
+ public CompendiumTopLevel SF6 { get; set; }
+ public CompendiumTopLevel RE4 { get; set; }
+ public CompendiumTopLevel DD2 { get; set; }
+ public CompendiumTopLevel MHWilds { get; set; }
+
+ protected void OnPropertyChanged([CallerMemberName] string name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+ public Compendium()
+ {
+ RE7 = new CompendiumTopLevel("Version 6 (RE7)");
+ RE2DMC5 = new CompendiumTopLevel("Version 10 (RE2/DMC5)");
+ RE3 = new CompendiumTopLevel("Version 13 (RE3)");
+ MHRiseRE8 = new CompendiumTopLevel("Version 19 (MHRise/RE8)");
+ RERT = new CompendiumTopLevel("Version 21 (RE Raytracing)");
+ Sunbreak = new CompendiumTopLevel("Version 23 (MHRS)");
+ SF6 = new CompendiumTopLevel("Version 31 (SF6)");
+ RE4 = new CompendiumTopLevel("Version 32 (RE4)");
+ DD2 = new CompendiumTopLevel("Version 40 (DD2/DRDR)");
+ MHWilds = new CompendiumTopLevel("Version 45 (MHWilds)");
+ entries = new ObservableCollection { RE7, RE2DMC5, RE3, MHRiseRE8, RERT, Sunbreak, SF6, RE4, DD2, MHWilds };
+
+ }
+ public void SetEntries(ObservableCollection newEntries)
+ {
+ foreach (CompendiumTopLevel entry in newEntries)
+ {
+ switch (entry.Game)
+ {
+ case "RE7":
+ case "Version 6 (RE7)":
+ RE7.Items = entry.Items;
+ break;
+ case "RE2/DMC5":
+ case "Version 10 (RE2/DMC5)":
+ RE2DMC5.Items = entry.Items;
+ break;
+ case "RE3":
+ case "Version 13 (RE3)":
+ RE3.Items = entry.Items;
+ break;
+ case "MHRise/RE8":
+ case "Version 19 (MHRise/RE8)":
+ MHRiseRE8.Items = entry.Items;
+ break;
+ case "Version 21 (RE Raytracing)":
+ RERT.Items = entry.Items;
+ break;
+ case "Version 23 (MHRS)":
+ Sunbreak.Items = entry.Items;
+ break;
+ case "Version 31 (SF6)":
+ SF6.Items = entry.Items;
+ break;
+ case "Version 32 (RE4)":
+ RE4.Items = entry.Items;
+ break;
+ case "Version 40 (DD2/DRDR)":
+ DD2.Items = entry.Items;
+ break;
+ case "Version 45 (MHWilds)":
+ MHWilds.Items = entry.Items;
+ break;
+ }
+ }
+ OnPropertyChanged("entries");
+ Sort();
+ }
+
+ public void ClearList()
+ {
+ foreach(CompendiumTopLevel ctl in entries)
+ {
+ ctl.ClearChildren();
+ }
+ }
+
+ public void Sort()
+ {
+ RE7.Sort();
+ RE2DMC5.Sort();
+ RE3.Sort();
+ MHRiseRE8.Sort();
+ RERT.Sort();
+ Sunbreak.Sort();
+ SF6.Sort();
+ RE4.Sort();
+ DD2.Sort();
+ MHWilds.Sort();
+ OnPropertyChanged("entries");
+ }
+ public event PropertyChangedEventHandler PropertyChanged;
+ }
+}
diff --git a/MDF-Manager/Classes/Defs.cs b/MDF-Manager/Classes/Defs.cs
index e2fe3f8..fbfe31a 100644
--- a/MDF-Manager/Classes/Defs.cs
+++ b/MDF-Manager/Classes/Defs.cs
@@ -1,33 +1,33 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Media;
-
-namespace MDF_Manager.Classes
-{
- public class Defs
- {
- public List lastOpenFiles { get; set; }
- public string lastOpenComp { get; set; }
- public string lastOpenLib { get; set; }
- private Color _Background = new Color { R = 226, G = 226, B = 226, A = 255 };
- private Color _Foreground = new Color { R = 255, G = 255, B = 255, A = 255 };
- private Color _Windows = new Color { R = 255, G = 255, B = 255, A = 255 };
- private Color _Button = new Color { R = 226, G = 226, B = 226, A = 255 };
- private Color _Text = new Color { R = 0, G = 0, B = 0, A = 255 };
- public Color background { get => _Background; set => _Background = value; }
- public Color foreground { get => _Foreground; set => _Foreground = value; }
- public Color windows { get => _Windows; set => _Windows = value; }
- public Color buttons { get => _Button; set => _Button = value; }
- public Color text { get => _Text; set => _Text = value; }
-
- public Defs()
- {
- lastOpenFiles = new List();
- lastOpenLib = "";
- lastOpenComp = "";
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+
+namespace MDF_Manager.Classes
+{
+ public class Defs
+ {
+ public List lastOpenFiles { get; set; }
+ public string lastOpenComp { get; set; }
+ public string lastOpenLib { get; set; }
+ private Color _Background = new Color { R = 226, G = 226, B = 226, A = 255 };
+ private Color _Foreground = new Color { R = 255, G = 255, B = 255, A = 255 };
+ private Color _Windows = new Color { R = 255, G = 255, B = 255, A = 255 };
+ private Color _Button = new Color { R = 226, G = 226, B = 226, A = 255 };
+ private Color _Text = new Color { R = 0, G = 0, B = 0, A = 255 };
+ public Color background { get => _Background; set => _Background = value; }
+ public Color foreground { get => _Foreground; set => _Foreground = value; }
+ public Color windows { get => _Windows; set => _Windows = value; }
+ public Color buttons { get => _Button; set => _Button = value; }
+ public Color text { get => _Text; set => _Text = value; }
+
+ public Defs()
+ {
+ lastOpenFiles = new List();
+ lastOpenLib = "";
+ lastOpenComp = "";
+ }
+ }
+}
diff --git a/MDF-Manager/Classes/GPUBuffer.cs b/MDF-Manager/Classes/GPUBuffer.cs
new file mode 100644
index 0000000..77bee27
--- /dev/null
+++ b/MDF-Manager/Classes/GPUBuffer.cs
@@ -0,0 +1,24 @@
+using System;
+
+public class GPUBuffer
+{
+ public Int64 GPUBufferNameOffset { get; set; }
+ public string GPUBufferName { get; set; }
+ public uint GPBFNameUTF16Hash { get; set; }
+ public uint GPBFNameASCIIHash { get; set; }
+ public int NameOffsetIndex { get; set; }
+
+ public GPUBuffer()
+ {
+ //SILVER: Placeholder for json files?
+ GPUBufferName = "RainAddressBuffer";
+ }
+
+ public GPUBuffer(Int64 NameOffset, string Name, uint utf16Hash, uint asciiHash)
+ {
+ GPUBufferNameOffset = NameOffset;
+ GPUBufferName = Name;
+ GPBFNameUTF16Hash = utf16Hash;
+ GPBFNameASCIIHash = asciiHash;
+ }
+}
diff --git a/MDF-Manager/Classes/Library.cs b/MDF-Manager/Classes/Library.cs
index 4f7a26b..73c9f9a 100644
--- a/MDF-Manager/Classes/Library.cs
+++ b/MDF-Manager/Classes/Library.cs
@@ -1,72 +1,72 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows.Controls;
-
-namespace MDF_Manager.Classes
-{
- public class LibraryEntry
- {
- //library entry only needs 2 things, material name/index (name will let it be future-proof) and filepath
- private string _MatName;
- public string Header { get; set; }
- public ObservableCollection Items { get; set; }
- public string MaterialName { get => _MatName; set { _MatName = value; Header = value; } }
- public string MDFPath { get; set; }
- public LibraryEntry()
- {
- Items = new ObservableCollection();
- MaterialName = "";
- MDFPath = "";
-
- }
- public LibraryEntry(string name, string path)
- {
- Items = new ObservableCollection(); //how did this not crash
- MaterialName = name;
- MDFPath = path;
- }
- }
- public class LibraryEntryHeader
- {
- //entryHeader contains children as
- private string _Path;
- public string Header { get; set; }
- public ObservableCollection Items { get; set; }
- public string MDFPath { get => _Path; set { _Path = value; Header = value; } }
- public LibraryEntryHeader()
- {
- Items = new ObservableCollection();
- MDFPath = "";
- }
- public LibraryEntryHeader(string path)
- {
- Items = new ObservableCollection();
- MDFPath = path;
- }
- }
- public class Library : INotifyPropertyChanged
- {
- public ObservableCollection entries { get; set; }
- protected void OnPropertyChanged([CallerMemberName] string name = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- }
- public Library()
- {
- entries = new ObservableCollection();
- }
- public void SetEntries(ObservableCollection newEntries)
- {
- entries = newEntries;
- OnPropertyChanged("entries");
- }
-
- public event PropertyChangedEventHandler PropertyChanged;
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+
+namespace MDF_Manager.Classes
+{
+ public class LibraryEntry
+ {
+ //library entry only needs 2 things, material name/index (name will let it be future-proof) and filepath
+ private string _MatName;
+ public string Header { get; set; }
+ public ObservableCollection Items { get; set; }
+ public string MaterialName { get => _MatName; set { _MatName = value; Header = value; } }
+ public string MDFPath { get; set; }
+ public LibraryEntry()
+ {
+ Items = new ObservableCollection();
+ MaterialName = "";
+ MDFPath = "";
+
+ }
+ public LibraryEntry(string name, string path)
+ {
+ Items = new ObservableCollection(); //how did this not crash
+ MaterialName = name;
+ MDFPath = path;
+ }
+ }
+ public class LibraryEntryHeader
+ {
+ //entryHeader contains children as
+ private string _Path;
+ public string Header { get; set; }
+ public ObservableCollection Items { get; set; }
+ public string MDFPath { get => _Path; set { _Path = value; Header = value; } }
+ public LibraryEntryHeader()
+ {
+ Items = new ObservableCollection();
+ MDFPath = "";
+ }
+ public LibraryEntryHeader(string path)
+ {
+ Items = new ObservableCollection();
+ MDFPath = path;
+ }
+ }
+ public class Library : INotifyPropertyChanged
+ {
+ public ObservableCollection entries { get; set; }
+ protected void OnPropertyChanged([CallerMemberName] string name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+ public Library()
+ {
+ entries = new ObservableCollection();
+ }
+ public void SetEntries(ObservableCollection newEntries)
+ {
+ entries = newEntries;
+ OnPropertyChanged("entries");
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ }
+}
diff --git a/MDF-Manager/Classes/MDFFile.cs b/MDF-Manager/Classes/MDFFile.cs
index 4379cc0..61933c1 100644
--- a/MDF-Manager/Classes/MDFFile.cs
+++ b/MDF-Manager/Classes/MDFFile.cs
@@ -1,215 +1,264 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.IO;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Windows;
-using System.Windows.Controls;
-
-namespace MDF_Manager.Classes
-{
- public class MDFFile : INotifyPropertyChanged
- {
- private string _Header;
- public string Header { get => _Header; set { _Header = value; OnPropertyChanged("Header"); } }
- public DataTemplate HeaderTemplate { get; set; }
- public string FileName = "";
- static byte[] magic = { (byte)'M', (byte)'D', (byte)'F', 0x00 };
- UInt16 unkn = 1;
-
- public event PropertyChangedEventHandler PropertyChanged;
- protected void OnPropertyChanged([CallerMemberName] string name = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- }
-
- public ObservableCollection Materials { get; set; }
-
- public MDFFile(string fileName, BinaryReader br, MDFTypes types)
- {
- Materials = new ObservableCollection();
- Header = fileName;
- FileName = fileName;
- byte[] mBytes = br.ReadBytes(4);
- if (Encoding.ASCII.GetString(mBytes) != Encoding.ASCII.GetString(magic))
- {
- MessageBox.Show("Not a valid MDF file!");
- return;
- }
- UInt16 unkn1 = br.ReadUInt16();
- if(unkn1 != unkn)
- {
- MessageBox.Show("Potentially bad MDF file.");
- }
- UInt16 MaterialCount = br.ReadUInt16();
- br.ReadUInt64();
- for(int i = 0; i < MaterialCount; i++)
- {
- Materials.Add(new Material(br, types,i));
- }
-
- }
-
- public List GenerateStringTable(ref List offsets)
- {
- List strings = new List();
- for(int i = 0; i < Materials.Count; i++)
- {
- if (!strings.Contains(Materials[i].Name))
- {
- strings.Add(Materials[i].Name);
- Materials[i].NameOffsetIndex = strings.Count - 1;
- }
- else
- {
- Materials[i].NameOffsetIndex = strings.FindIndex(name => name == Materials[i].Name);
- }
- if (!strings.Contains(Materials[i].MasterMaterial))
- {
- strings.Add(Materials[i].MasterMaterial);
- Materials[i].MMOffsetIndex = strings.Count - 1;
- }
- else
- {
- Materials[i].MMOffsetIndex = strings.FindIndex(name => name == Materials[i].MasterMaterial);
- }
- }
- for(int i = 0; i < Materials.Count; i++)
- {
- for(int j = 0; j < Materials[i].Textures.Count; j++)
- {
- if (!strings.Contains(Materials[i].Textures[j].name))
- {
- strings.Add(Materials[i].Textures[j].name);
- Materials[i].Textures[j].NameOffsetIndex = strings.Count - 1;
- }
- else
- {
- Materials[i].Textures[j].NameOffsetIndex = strings.FindIndex(name => name == Materials[i].Textures[j].name);
- }
- if (!strings.Contains(Materials[i].Textures[j].path))
- {
- strings.Add(Materials[i].Textures[j].path);
- Materials[i].Textures[j].PathOffsetIndex = strings.Count - 1;
- }
- else
- {
- Materials[i].Textures[j].PathOffsetIndex = strings.FindIndex(name => name == Materials[i].Textures[j].path);
- }
- }
- }
- for (int i = 0; i < Materials.Count; i++)
- {
- for (int j = 0; j < Materials[i].Properties.Count; j++)
- {
- if (!strings.Contains(Materials[i].Properties[j].name))
- {
- strings.Add(Materials[i].Properties[j].name);
- Materials[i].Properties[j].NameOffsetIndex = strings.Count - 1;
- }
- else
- {
- Materials[i].Properties[j].NameOffsetIndex = strings.FindIndex(name => name == Materials[i].Properties[j].name);
- }
- }
- }
- List outputBuff = new List();
- offsets.Add(0);
- for(int i = 0; i < strings.Count; i++)
- {
- byte[] inBytes = Encoding.Unicode.GetBytes(strings[i]);
- for(int j = 0; j < inBytes.Length; j++)
- {
- outputBuff.Add(inBytes[j]);
- }
- outputBuff.Add(0);
- outputBuff.Add(0);
- offsets.Add(outputBuff.Count);//think this will end with the very last one being unused but that's fine
-
- }
- return outputBuff;
- }
-
- public void Export(BinaryWriter bw,MDFTypes type)
- {
- bw.Write(magic);
- bw.Write((short)1);
- bw.Write((short)Materials.Count);
- bw.Write((long)0);
- //before going further, we need accurate lengths for 4 of the 5 main sections of the mdf
- /*
- * header -set size
- * materials - set size
- * textures - set size
- * propHeaders - set size
- * stringtable - generate in a separate function
- * prop values - based off of prop headers
- */
- List strTableOffsets = new List();
- List stringTable = GenerateStringTable(ref strTableOffsets);
- //this function handles the biggest problem of writing materials, getting the name offsets
- long materialOffset = bw.BaseStream.Position;
- while ((materialOffset % 16) != 0)
- {
- materialOffset++;
- }
- long textureOffset = materialOffset;
- for(int i = 0; i < Materials.Count; i++)
- {
- textureOffset += Materials[i].GetSize(type);
- }
- while((textureOffset%16) != 0)
- {
- textureOffset++;
- }
- long propHeadersOffset = textureOffset;
- for(int i = 0; i < Materials.Count; i++)
- {
- for(int j = 0; j < Materials[i].Textures.Count; j++)
- {
- propHeadersOffset += Materials[i].Textures[j].GetSize(type);
- }
- }
- while ((propHeadersOffset % 16) != 0)
- {
- propHeadersOffset++;
- }
- long stringTableOffset = propHeadersOffset;
- for (int i = 0; i < Materials.Count; i++)
- {
- for (int j = 0; j < Materials[i].Properties.Count; j++)
- {
- stringTableOffset += Materials[i].Properties[j].GetPropHeaderSize();
- }
- }
- while ((stringTableOffset % 16) != 0)
- {
- stringTableOffset++;
- }
- long propertiesOffset = stringTableOffset + stringTable.Count;
- while ((propertiesOffset % 16) != 0)
- {
- propertiesOffset++;
- }
- bw.BaseStream.Seek(stringTableOffset,SeekOrigin.Begin);
- for(int i = 0; i < stringTable.Count; i++)
- {
- bw.Write(stringTable[i]);
- }
- for (int i = 0; i < Materials.Count; i++)
- {
- Materials[i].Export(bw,type, ref materialOffset, ref textureOffset, ref propHeadersOffset, stringTableOffset, strTableOffsets, ref propertiesOffset);
- }
- }
- public static IList ShadingTypes
- {
- get
- {
- return Enum.GetValues(typeof(ShadingType)).Cast().ToList();
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.IO;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace MDF_Manager.Classes
+{
+ public class MDFFile : INotifyPropertyChanged
+ {
+ private string _Header;
+ public string Header { get => _Header; set { _Header = value; OnPropertyChanged("Header"); } }
+ public DataTemplate HeaderTemplate { get; set; }
+ public string FileName = "";
+ static byte[] magic = { (byte)'M', (byte)'D', (byte)'F', 0x00 };
+ public int largestPropsSize;
+ UInt16 unkn = 1;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ protected void OnPropertyChanged([CallerMemberName] string name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public ObservableCollection Materials { get; set; }
+
+ public MDFFile(string fileName, BinaryReader br, MDFTypes types)
+ {
+ Materials = new ObservableCollection();
+ Header = fileName;
+ FileName = fileName;
+ byte[] mBytes = br.ReadBytes(4);
+ if (Encoding.ASCII.GetString(mBytes) != Encoding.ASCII.GetString(magic))
+ {
+ MessageBox.Show("Not a valid MDF file!");
+ return;
+ }
+ UInt16 unkn1 = br.ReadUInt16();
+ if(unkn1 != unkn)
+ {
+ MessageBox.Show("Potentially bad MDF file.");
+ }
+ UInt16 MaterialCount = br.ReadUInt16();
+ br.ReadUInt64();
+ for(int i = 0; i < MaterialCount; i++)
+ {
+ Materials.Add(new Material(br, types, i, this));
+ if (Materials[i].matSize > largestPropsSize)
+ largestPropsSize = Materials[i].matSize;
+ }
+ /*for (int i = 0; i < MaterialCount; i++)
+ {
+ if (i < MaterialCount - 1)
+ Materials[i].matGapSize = (int)(Materials[i + 1].propsStart - Materials[i].propsEnd);
+ else
+ Materials[i].matGapSize = 1024;
+ }*/
+ }
+
+ public List GenerateStringTable(ref List offsets)
+ {
+ List strings = new List();
+ for(int i = 0; i < Materials.Count; i++)
+ {
+ if (!strings.Contains(Materials[i].Name))
+ {
+ strings.Add(Materials[i].Name);
+ Materials[i].NameOffsetIndex = strings.Count - 1;
+ }
+ else
+ {
+ Materials[i].NameOffsetIndex = strings.FindIndex(name => name == Materials[i].Name);
+ }
+ if (!strings.Contains(Materials[i].MasterMaterial))
+ {
+ strings.Add(Materials[i].MasterMaterial);
+ Materials[i].MMOffsetIndex = strings.Count - 1;
+ }
+ else
+ {
+ Materials[i].MMOffsetIndex = strings.FindIndex(name => name == Materials[i].MasterMaterial);
+ }
+ }
+ for(int i = 0; i < Materials.Count; i++)
+ {
+ for(int j = 0; j < Materials[i].Textures.Count; j++)
+ {
+ if (!strings.Contains(Materials[i].Textures[j].name))
+ {
+ strings.Add(Materials[i].Textures[j].name);
+ Materials[i].Textures[j].NameOffsetIndex = strings.Count - 1;
+ }
+ else
+ {
+ Materials[i].Textures[j].NameOffsetIndex = strings.FindIndex(name => name == Materials[i].Textures[j].name);
+ }
+ if (!strings.Contains(Materials[i].Textures[j].path))
+ {
+ strings.Add(Materials[i].Textures[j].path);
+ Materials[i].Textures[j].PathOffsetIndex = strings.Count - 1;
+ }
+ else
+ {
+ Materials[i].Textures[j].PathOffsetIndex = strings.FindIndex(name => name == Materials[i].Textures[j].path);
+ }
+ }
+ }
+ for (int i = 0; i < Materials.Count; i++)
+ {
+ for (int j = 0; j < Materials[i].Properties.Count; j++)
+ {
+ if (!strings.Contains(Materials[i].Properties[j].name))
+ {
+ strings.Add(Materials[i].Properties[j].name);
+ Materials[i].Properties[j].NameOffsetIndex = strings.Count - 1;
+ }
+ else
+ {
+ Materials[i].Properties[j].NameOffsetIndex = strings.FindIndex(name => name == Materials[i].Properties[j].name);
+ }
+ }
+ }
+ for (int i = 0; i < Materials.Count; i++)
+ {
+ for (int j = 0; j < Materials[i].GPUBuffers.Count; j++)
+ {
+ if (!strings.Contains(Materials[i].GPUBuffers[j].GPUBufferName))
+ {
+ strings.Add(Materials[i].GPUBuffers[j].GPUBufferName);
+ Materials[i].GPUBuffers[j].NameOffsetIndex = strings.Count - 1;
+ }
+ else
+ {
+ Materials[i].GPUBuffers[j].NameOffsetIndex = strings.FindIndex(name => name == Materials[i].GPUBuffers[j].GPUBufferName);
+ }
+ }
+ }
+ List outputBuff = new List();
+ offsets.Add(0);
+ for(int i = 0; i < strings.Count; i++)
+ {
+ byte[] inBytes = Encoding.Unicode.GetBytes(strings[i]);
+ for(int j = 0; j < inBytes.Length; j++)
+ {
+ outputBuff.Add(inBytes[j]);
+ }
+ outputBuff.Add(0);
+ outputBuff.Add(0);
+ offsets.Add(outputBuff.Count);//think this will end with the very last one being unused but that's fine
+
+ }
+ return outputBuff;
+ }
+
+ public void Export(BinaryWriter bw, MDFTypes type)
+ {
+ bw.Write(magic);
+ bw.Write((short)1);
+ bw.Write((short)Materials.Count);
+ bw.Write((long)0);
+ //before going further, we need accurate lengths for 4 of the 5 main sections of the mdf
+ /*
+ * header -set size
+ * materials - set size
+ * textures - set size
+ * propHeaders - set size
+ * stringtable - generate in a separate function
+ * prop values - based off of prop headers
+ */
+ List strTableOffsets = new List();
+ List stringTable = GenerateStringTable(ref strTableOffsets);
+ //this function handles the biggest problem of writing materials, getting the name offsets
+ long GPBFsize = 0;
+ long materialOffset = bw.BaseStream.Position;
+ while ((materialOffset % 16) != 0)
+ {
+ materialOffset++;
+ }
+ long textureOffset = materialOffset;
+ for(int i = 0; i < Materials.Count; i++)
+ {
+ textureOffset += Materials[i].GetSize(type);
+ GPBFsize += Materials[i].GPBFCount * 16;
+ }
+ while((textureOffset%16) != 0)
+ {
+ textureOffset++;
+ }
+ long propHeadersOffset = textureOffset;
+ for(int i = 0; i < Materials.Count; i++)
+ {
+ for(int j = 0; j < Materials[i].Textures.Count; j++)
+ {
+ propHeadersOffset += Materials[i].Textures[j].GetSize(type);
+ }
+ }
+ while ((propHeadersOffset % 16) != 0)
+ {
+ propHeadersOffset++;
+ }
+ long GPBFOffset = propHeadersOffset;
+ for (int i = 0; i < Materials.Count; i++)
+ {
+ for (int j = 0; j < Materials[i].Properties.Count; j++)
+ {
+ GPBFOffset += Materials[i].Properties[j].GetPropHeaderSize();
+ }
+ }
+ while ((GPBFOffset % 16) != 0)
+ {
+ GPBFOffset++;
+ }
+
+ long stringTableOffset = GPBFOffset;
+ for (int i = 0; i < Materials.Count; i++)
+ {
+ for (int j = 0; j < Materials[i].GPBFCount; j++)
+ {
+ stringTableOffset += Materials[i].GetGPBFSize();
+ }
+ }
+ while ((stringTableOffset % 16) != 0)
+ {
+ GPBFOffset++;
+ }
+
+ long propertiesOffset = stringTableOffset + stringTable.Count;
+ while (propertiesOffset % 16 != Materials[0].propsStart % 16)
+ {
+ propertiesOffset++;
+ }
+ bw.BaseStream.Seek(stringTableOffset,SeekOrigin.Begin);
+ for(int i = 0; i < stringTable.Count; i++)
+ {
+ bw.Write(stringTable[i]);
+ }
+ int starter = Materials[0].Properties[0].dataStartOffs;
+ long runningGPBFStart = GPBFOffset;
+
+ for (int i = 0; i < Materials.Count; i++)
+ {
+ //int adjustedSize = Materials[i].matSize;
+ /*while (adjustedSize % 16 != starter % 16)
+ adjustedSize++;
+ while (adjustedSize % 64 != 0)
+ adjustedSize++;*/
+ Materials[i].Export(bw, type, ref materialOffset, ref textureOffset, ref propHeadersOffset, runningGPBFStart, stringTableOffset, strTableOffsets, ref propertiesOffset, Materials[i].matSize);
+ runningGPBFStart += Materials[i].GPBFCount * Materials[i].GetGPBFSize();
+ }
+ }
+ public static IList ShadingTypes
+ {
+ get
+ {
+ return Enum.GetValues(typeof(ShadingType)).Cast().ToList();
+ }
+ }
+ }
+}
diff --git a/MDF-Manager/Classes/MDFTab.cs b/MDF-Manager/Classes/MDFTab.cs
index e335c6a..cdd556d 100644
--- a/MDF-Manager/Classes/MDFTab.cs
+++ b/MDF-Manager/Classes/MDFTab.cs
@@ -1,20 +1,20 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-
-namespace MDF_Manager.Classes
-{
- public class MDFTab : TabItem
- {
- public MDFFile mdf;
- public MDFTab(MDFFile mdfFile)
- {
- mdf = mdfFile;
- Header = mdf.Header;
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace MDF_Manager.Classes
+{
+ public class MDFTab : TabItem
+ {
+ public MDFFile mdf;
+ public MDFTab(MDFFile mdfFile)
+ {
+ mdf = mdfFile;
+ Header = mdf.Header;
+ }
+ }
+}
diff --git a/MDF-Manager/Classes/Material.cs b/MDF-Manager/Classes/Material.cs
index 720567e..7d5d596 100644
--- a/MDF-Manager/Classes/Material.cs
+++ b/MDF-Manager/Classes/Material.cs
@@ -1,636 +1,766 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Text;
-
-namespace MDF_Manager.Classes
-{
- [Flags]
- public enum AlphaFlags
- {
- None = 0,
- BaseTwoSideEnable = 1,
- BaseAlphaTestEnable = 2,
- ShadowCastDisable = 4,
- VertexShaderUsed = 8,
- EmissiveUsed = 16,
- TessellationEnable = 32,
- EnableIgnoreDepth = 64,
- AlphaMaskUsed = 128
- }
- [Flags]
- public enum Flags2
- {
- None = 0,
- ForcedTwoSideEnable = 1,
- TwoSideEnable = 2
- }
- [Flags]
- public enum Flags3
- {
- None = 0,
- RoughTransparentEnable = 1,
- ForcedAlphaTestEnable = 2,
- AlphaTestEnable = 4,
- SSSProfileUsed = 8,
- EnableStencilPriority = 16,
- RequireDualQuaternion = 32,
- PixelDepthOffsetUsed = 64,
- NoRayTracing = 128
- }
-
- public enum ShadingType
- {
- Standard = 0,
- Decal = 1,
- DecalWithMetallic = 2,
- DecalNRMR = 3,
- Transparent = 4,
- Distortion = 5,
- PrimitiveMesh = 6,
- PrimitiveSolidMesh = 7,
- Water = 8,
- SpeedTree = 9,
- GUI = 10,
- GUIMesh = 11,
- GUIMeshTransparent = 12,
- ExpensiveTransparent =13,
- Forward = 14,
- RenderTarget = 15,
- PostProcess = 16,
- PrimitiveMaterial = 17,
- PrimitiveSolidMaterial = 18,
- SpineMaterial = 19
- }
-
- public enum MDFTypes
- {
- RE7 = 6,
- RE2DMC5 = 10,
- RE3 = 13,
- MHRiseRE8 = 19,
- RERT = 21, //Resident Evil raytracing update
- Sunbreak = 23,
- SF6 = 31
- }
-
- public class BooleanHolder : INotifyPropertyChanged
- {
- private string _name;
- private bool _selected;
- protected void OnPropertyChanged([CallerMemberName] string name = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- }
- public string Name
- {
- get => _name; set
- {
- _name = value;
- OnPropertyChanged(nameof(Name));
- }
- }
- public bool Selected
- {
- get => _selected; set
- {
- _selected = value;
- OnPropertyChanged(nameof(Selected));
- }
- }
- public BooleanHolder(string name, bool selected)
- {
- Name = name;
- Selected = selected;
- }
- public event PropertyChangedEventHandler PropertyChanged;
- }
-
- public class Material : INotifyPropertyChanged
- {
- private string _Name;
- private uint _Hash;
- public int NameOffsetIndex; //applied and used only on export
- public int MMOffsetIndex;
- public int materialIndex; //used for deleting and adding new
- private void UpdateHash()
- {
- _Hash = HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(_Name));
- OnPropertyChanged("UTF16Hash");
- }
- public string Name { get => _Name; set { _Name = value; OnPropertyChanged("Name"); UpdateHash(); } }
- public uint UTF16Hash { get => _Hash; set => _Hash = value; }
- public string MasterMaterial { get; set; }
- public ShadingType ShaderType { get; set; }
- public byte TessFactor { get; set; }
- public byte PhongFactor { get; set; }//shrug bytes are unsigned by default in C#
- public ObservableCollection flags { get; set; }
- public List Textures { get; set; }
- public List Properties { get; set; }
-
- public event PropertyChangedEventHandler PropertyChanged;
- protected void OnPropertyChanged([CallerMemberName] string name = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- }
-
- public TextureBinding ReadTextureBinding(BinaryReader br, MDFTypes type)
- {
- Int64 TextureTypeOff = br.ReadInt64();
- uint UTF16MMH3Hash = br.ReadUInt32();
- uint ASCIIMMH3Hash = br.ReadUInt32();
- Int64 FilePathOff = br.ReadInt64();
- if(type >= MDFTypes.RE3)
- {
- Int64 Unkn0 = br.ReadInt64(); //value of 0 in most mdf, possible alignment?
- }
- Int64 EOT = br.BaseStream.Position;
- br.BaseStream.Seek(TextureTypeOff, SeekOrigin.Begin);
- string TextureType = HelperFunctions.ReadUniNullTerminatedString(br);
- br.BaseStream.Seek(FilePathOff, SeekOrigin.Begin);
- string FilePath = HelperFunctions.ReadUniNullTerminatedString(br);
- br.BaseStream.Seek(EOT, SeekOrigin.Begin);
- TextureBinding tb = new TextureBinding(TextureType,FilePath);
- return tb;
- }
-
- public IVariableProp ReadProperty(BinaryReader br, Int64 dataOff, MDFTypes type, int matIndex, int propIndex)
- {
- Int64 PropNameOff = br.ReadInt64();
- uint UTF16MMH3Hash = br.ReadUInt32();
- uint ASCIIMMH3Hash = br.ReadUInt32();
- int PropDataOff = 0;
- int ParamCount = 0;
- if (type >= MDFTypes.RE3)
- {
- PropDataOff = br.ReadInt32();
- ParamCount = br.ReadInt32();
- }
- else
- {
- ParamCount = br.ReadInt32();
- PropDataOff = br.ReadInt32();
- }
-
- Int64 EOP = br.BaseStream.Position;
- br.BaseStream.Seek(PropNameOff, SeekOrigin.Begin);
- string PropName = HelperFunctions.ReadUniNullTerminatedString(br);
- br.BaseStream.Seek(dataOff + PropDataOff, SeekOrigin.Begin);
- switch (ParamCount)
- {
- case 1:
- Float fData = new Float(br.ReadSingle());
- br.BaseStream.Seek(EOP, SeekOrigin.Begin);
- return new FloatProperty(PropName, fData, matIndex, propIndex);
- case 4:
- Float4 f4Data = new Float4(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
- br.BaseStream.Seek(EOP, SeekOrigin.Begin);
- return new Float4Property(PropName, f4Data, matIndex, propIndex);
- default:
- br.BaseStream.Seek(EOP, SeekOrigin.Begin);
- return new FloatProperty(Name, new Float((float)1.0), matIndex, propIndex);//shouldn't really come up ever
-
- }
- }
-
- public int GetSize(MDFTypes type)
- {
- int baseVal = 64;
- if(type == MDFTypes.RE7)
- {
- baseVal += 8;
- }
- else if (type >= MDFTypes.SF6)
- {
- baseVal += 36;
- }
- else if (type >= MDFTypes.MHRiseRE8){
- baseVal += 16;
- }
- return baseVal;
- }
-
- public void ReadFlagsSection(BinaryReader br)
- {
- AlphaFlags alphaFlags = (AlphaFlags)br.ReadByte();
- if ((alphaFlags & AlphaFlags.BaseTwoSideEnable) == AlphaFlags.BaseTwoSideEnable)
- {
- flags.Add(new BooleanHolder("BaseTwoSideEnable",true));
- }
- else
- {
- flags.Add(new BooleanHolder("BaseTwoSideEnable", false));
- }
- if ((alphaFlags & AlphaFlags.BaseAlphaTestEnable) == AlphaFlags.BaseAlphaTestEnable)
- {
- flags.Add(new BooleanHolder("BaseAlphaTestEnable", true));
- }
- else
- {
- flags.Add(new BooleanHolder("BaseAlphaTestEnable", false));
- }
- if ((alphaFlags & AlphaFlags.ShadowCastDisable) == AlphaFlags.ShadowCastDisable)
- {
- flags.Add(new BooleanHolder("ShadowCastDisable", true));
- }
- else
- {
- flags.Add(new BooleanHolder("ShadowCastDisable", false));
- }
- if ((alphaFlags & AlphaFlags.VertexShaderUsed) == AlphaFlags.VertexShaderUsed)
- {
- flags.Add(new BooleanHolder("VertexShaderUsed", true));
- }
- else
- {
- flags.Add(new BooleanHolder("VertexShaderUsed", false));
- }
- if ((alphaFlags & AlphaFlags.EmissiveUsed) == AlphaFlags.EmissiveUsed)
- {
- flags.Add(new BooleanHolder("EmissiveUsed", true));
- }
- else
- {
- flags.Add(new BooleanHolder("EmissiveUsed", false));
- }
- if ((alphaFlags & AlphaFlags.TessellationEnable) == AlphaFlags.TessellationEnable)
- {
- flags.Add(new BooleanHolder("TessellationEnable", true));
- }
- else
- {
- flags.Add(new BooleanHolder("TessellationEnable", false));
- }
- if ((alphaFlags & AlphaFlags.EnableIgnoreDepth) == AlphaFlags.EnableIgnoreDepth)
- {
- flags.Add(new BooleanHolder("EnableIgnoreDepth", true));
- }
- else
- {
- flags.Add(new BooleanHolder("EnableIgnoreDepth", false));
- }
- if ((alphaFlags & AlphaFlags.AlphaMaskUsed) == AlphaFlags.AlphaMaskUsed)
- {
- flags.Add(new BooleanHolder("AlphaMaskUsed", true));
- }
- else
- {
- flags.Add(new BooleanHolder("AlphaMaskUsed", false));
- }
- byte flagByte = br.ReadByte();
- Flags2 flagVals = (Flags2)flagByte;
- if ((flagVals & Flags2.ForcedTwoSideEnable) == Flags2.ForcedTwoSideEnable)
- {
- flags.Add(new BooleanHolder("ForcedTwoSideEnable", true));
- }
- else
- {
- flags.Add(new BooleanHolder("ForcedTwoSideEnable", false));
- }
- if ((flagVals & Flags2.TwoSideEnable) == Flags2.TwoSideEnable)
- {
- flags.Add(new BooleanHolder("TwoSideEnable", true));
- }
- else
- {
- flags.Add(new BooleanHolder("TwoSideEnable", false));
- }
- TessFactor = (byte)(flagByte >> 2);
- PhongFactor = br.ReadByte();
- Flags3 Flags3 = (Flags3)br.ReadByte();
- if ((Flags3 & Flags3.RoughTransparentEnable) == Flags3.RoughTransparentEnable)
- {
- flags.Add(new BooleanHolder("RoughTransparentEnable", true));
- }
- else
- {
- flags.Add(new BooleanHolder("RoughTransparentEnable", false));
- }
- if ((Flags3 & Flags3.ForcedAlphaTestEnable) == Flags3.ForcedAlphaTestEnable)
- {
- flags.Add(new BooleanHolder("ForcedAlphaTestEnable", true));
- }
- else
- {
- flags.Add(new BooleanHolder("ForcedAlphaTestEnable", false));
- }
- if ((Flags3 & Flags3.AlphaTestEnable) == Flags3.AlphaTestEnable)
- {
- flags.Add(new BooleanHolder("AlphaTestEnable", true));
- }
- else
- {
- flags.Add(new BooleanHolder("AlphaTestEnable", false));
- }
- if ((Flags3 & Flags3.SSSProfileUsed) == Flags3.SSSProfileUsed)
- {
- flags.Add(new BooleanHolder("SSSProfileUsed", true));
- }
- else
- {
- flags.Add(new BooleanHolder("SSSProfileUsed", false));
- }
- if ((Flags3 & Flags3.EnableStencilPriority) == Flags3.EnableStencilPriority)
- {
- flags.Add(new BooleanHolder("EnableStencilPriority", true));
- }
- else
- {
- flags.Add(new BooleanHolder("EnableStencilPriority", false));
- }
- if ((Flags3 & Flags3.RequireDualQuaternion) == Flags3.RequireDualQuaternion)
- {
- flags.Add(new BooleanHolder("RequireDualQuaternion", true));
- }
- else
- {
- flags.Add(new BooleanHolder("RequireDualQuaternion", false));
- }
- if ((Flags3 & Flags3.PixelDepthOffsetUsed) == Flags3.PixelDepthOffsetUsed)
- {
- flags.Add(new BooleanHolder("PixelDepthOffsetUsed", true));
- }
- else
- {
- flags.Add(new BooleanHolder("PixelDepthOffsetUsed", false));
- }
- if ((Flags3 & Flags3.NoRayTracing) == Flags3.NoRayTracing)
- {
- flags.Add(new BooleanHolder("NoRayTracing", true));
- }
- else
- {
- flags.Add(new BooleanHolder("NoRayTracing", false));
- }
-
- }
-
- public Material(BinaryReader br,MDFTypes type,int matIndex)
- {
- flags = new ObservableCollection();
- materialIndex = matIndex;
- Int64 MatNameOffset = br.ReadInt64();
- int MatNameHash = br.ReadInt32();//not storing, since it'll just be easier to export proper
- if(type == MDFTypes.RE7)
- {
- Int64 unknRE7 = br.ReadInt64();//I don't own RE7 so I'm just gonna hope these are 0s
- }
- int PropBlockSize = br.ReadInt32();
- int PropertyCount = br.ReadInt32();
- int TextureCount = br.ReadInt32();
- if(type >= MDFTypes.MHRiseRE8)
- {
- br.ReadInt64();
- }
- ShaderType = (ShadingType)br.ReadInt32();
- if (type >= MDFTypes.SF6)
- {
- br.ReadInt32();
- }
- ReadFlagsSection(br);
- if (type >= MDFTypes.SF6)
- {
- br.ReadInt64();
- }
- Int64 PropHeadersOff = br.ReadInt64();
- Int64 TexHeadersOff = br.ReadInt64();
- if(type >= MDFTypes.MHRiseRE8)
- {
- Int64 StringTableOff = br.ReadInt64();//not at all useful, given everything uses absolute offsets
- //it's possible that this is an offset for something that is not used by most mdfs, this will need to be looked into
- //given the extra Int64, I find this very likely
- }
- Int64 PropDataOff = br.ReadInt64();
- Int64 MMTRPathOff = br.ReadInt64();
- if (type >= MDFTypes.SF6)
- {
- br.ReadInt64();
- }
- Int64 EOM = br.BaseStream.Position;//to return to after reading the rest of the parameters
- Textures = new List();
- Properties = new List();
- //now we'll go grab names and values
- br.BaseStream.Seek(MatNameOffset, SeekOrigin.Begin);
- Name = HelperFunctions.ReadUniNullTerminatedString(br);
- br.BaseStream.Seek(MMTRPathOff, SeekOrigin.Begin);
- MasterMaterial = HelperFunctions.ReadUniNullTerminatedString(br);
-
- //read textures
- br.BaseStream.Seek(TexHeadersOff,SeekOrigin.Begin);
- for(int i = 0; i < TextureCount; i++)
- {
- Textures.Add(ReadTextureBinding(br,type));
- }
-
- //read properties
- br.BaseStream.Seek(PropHeadersOff, SeekOrigin.Begin);
- for(int i = 0; i < PropertyCount; i++)
- {
- Properties.Add(ReadProperty(br,PropDataOff,type,matIndex,i));
- }
- br.BaseStream.Seek(EOM,SeekOrigin.Begin);
- }
- public byte[] GenerateFlagsSection()
- {
- AlphaFlags flags1 = 0;
- Flags2 flags2 = (Flags2)(TessFactor << 2);
- Flags3 flags3 = 0;
- for(int i = 0; i < flags.Count; i++)
- {
- switch (flags[i].Name)
- {
- case "BaseTwoSideEnable":
- if (flags[i].Selected)
- {
- flags1 = flags1 | AlphaFlags.BaseTwoSideEnable;
- }
- break;
- case "BaseAlphaTestEnable":
- if (flags[i].Selected)
- {
- flags1 = flags1 | AlphaFlags.BaseAlphaTestEnable;
- }
- break;
- case "ShadowCastDisable":
- if (flags[i].Selected)
- {
- flags1 = flags1 | AlphaFlags.ShadowCastDisable;
- }
- break;
- case "VertexShaderUsed":
- if (flags[i].Selected)
- {
- flags1 = flags1 | AlphaFlags.VertexShaderUsed;
- }
- break;
- case "EmissiveUsed":
- if (flags[i].Selected)
- {
- flags1 = flags1 | AlphaFlags.EmissiveUsed;
- }
- break;
- case "TessellationEnable":
- if (flags[i].Selected)
- {
- flags1 = flags1 | AlphaFlags.TessellationEnable;
- }
- break;
- case "EnableIgnoreDepth":
- if (flags[i].Selected)
- {
- flags1 = flags1 | AlphaFlags.EnableIgnoreDepth;
- }
- break;
- case "AlphaMaskUsed":
- if (flags[i].Selected)
- {
- flags1 = flags1 | AlphaFlags.AlphaMaskUsed;
- }
- break;
- case "ForcedTwoSideEnable":
- if (flags[i].Selected)
- {
- flags2 = flags2 | Flags2.ForcedTwoSideEnable;
- }
- break;
- case "TwoSideEnable":
- if (flags[i].Selected)
- {
- flags2 = flags2 | Flags2.TwoSideEnable;
- }
- break;
- case "RoughTransparentEnable":
- if (flags[i].Selected)
- {
- flags3 = flags3 | Flags3.RoughTransparentEnable;
- }
- break;
- case "ForcedAlphaTestEnable":
- if (flags[i].Selected)
- {
- flags3 = flags3 | Flags3.ForcedAlphaTestEnable;
- }
- break;
- case "AlphaTestEnable":
- if (flags[i].Selected)
- {
- flags3 = flags3 | Flags3.AlphaTestEnable;
- }
- break;
- case "SSSProfileUsed":
- if (flags[i].Selected)
- {
- flags3 = flags3 | Flags3.SSSProfileUsed;
- }
- break;
- case "EnableStencilPriority":
- if (flags[i].Selected)
- {
- flags3 = flags3 | Flags3.EnableStencilPriority;
- }
- break;
- case "RequireDualQuaternion":
- if (flags[i].Selected)
- {
- flags3 = flags3 | Flags3.RequireDualQuaternion;
- }
- break;
- case "PixelDepthOffsetUsed":
- if (flags[i].Selected)
- {
- flags3 = flags3 | Flags3.PixelDepthOffsetUsed;
- }
- break;
- case "NoRayTracing":
- if (flags[i].Selected)
- {
- flags3 = flags3 | Flags3.NoRayTracing;
- }
- break;
-
- }
- }
- byte[] returnBytes = new byte[4];
- returnBytes[0] = (byte)flags1;
- returnBytes[1] = (byte)flags2;
- returnBytes[2] = PhongFactor;
- returnBytes[3] = (byte)flags3;
- return returnBytes;
- }
- public void UpdateMaterialIndex(int index)
- {
- materialIndex = index;
- for(int i = 0; i < Properties.Count; i++)
- {
- Properties[i].indexes[0] = index;
- }
- }
- public void Export(BinaryWriter bw, MDFTypes type, ref long materialOffset, ref long textureOffset, ref long propHeaderOffset, long stringTableOffset, List strTableOffsets, ref long propertiesOffset)
- {
- bw.BaseStream.Seek(materialOffset,SeekOrigin.Begin);
- bw.Write(stringTableOffset + strTableOffsets[NameOffsetIndex]);
- bw.Write(HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(Name)));
- if(type == MDFTypes.RE7)
- {
- bw.Write((long)0);
- }
- int propSize = 0;
- for(int i = 0; i < Properties.Count; i++)
- {
- propSize += Properties[i].GetSize();
- }
- while((propSize %16) != 0)
- {
- propSize += 1;
- }
- bw.Write(propSize);
- bw.Write(Properties.Count);
- bw.Write(Textures.Count);
- if(type >= MDFTypes.MHRiseRE8)
- {
- bw.Write((long)0);
- }
- bw.Write((uint)ShaderType);
- if (type >= MDFTypes.SF6)
- {
- bw.Write((int)0);
- }
- bw.Write(GenerateFlagsSection());
- if (type >= MDFTypes.SF6)
- {
- bw.Write((long)0);
- }
- bw.Write(propHeaderOffset);
- bw.Write(textureOffset);
- if(type >= MDFTypes.MHRiseRE8)
- {
- bw.Write(stringTableOffset);
- }
- bw.Write(propertiesOffset);
- bw.Write(stringTableOffset + strTableOffsets[MMOffsetIndex]);
- if (type >= MDFTypes.SF6)
- {
- bw.Write((long)0);
- }
- //end of actual material file, now update material offset and write textures/properties
- materialOffset += GetSize(type);
- for(int i = 0; i < Textures.Count; i++)
- {
- Textures[i].Export(bw, type, ref textureOffset, stringTableOffset, strTableOffsets);
- }
- long basePropOffset = propertiesOffset;//subtract by current prop offset to make inner offset
- for(int i = 0; i < Properties.Count; i++)
- {
- Properties[i].Export(bw, type, ref propHeaderOffset, ref propertiesOffset, basePropOffset, stringTableOffset, strTableOffsets);
- }
- if ((basePropOffset + propSize) != propertiesOffset)
- {
- Int64 diff = basePropOffset + propSize - propertiesOffset;
- propertiesOffset += diff;
- }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace MDF_Manager.Classes
+{
+ [Flags]
+ public enum AlphaFlags
+ {
+ None = 0,
+ BaseTwoSideEnable = 1,
+ BaseAlphaTestEnable = 2,
+ ShadowCastDisable = 4,
+ VertexShaderUsed = 8,
+ EmissiveUsed = 16,
+ TessellationEnable = 32,
+ EnableIgnoreDepth = 64,
+ AlphaMaskUsed = 128
+ }
+ [Flags]
+ public enum Flags2
+ {
+ None = 0,
+ ForcedTwoSideEnable = 1,
+ TwoSideEnable = 2
+ }
+ [Flags]
+ public enum Flags3
+ {
+ None = 0,
+ RoughTransparentEnable = 1,
+ ForcedAlphaTestEnable = 2,
+ AlphaTestEnable = 4,
+ SSSProfileUsed = 8,
+ EnableStencilPriority = 16,
+ RequireDualQuaternion = 32,
+ PixelDepthOffsetUsed = 64,
+ NoRayTracing = 128
+ }
+
+ public enum ShadingType
+ {
+ Standard = 0,
+ Decal = 1,
+ DecalWithMetallic = 2,
+ DecalNRMR = 3,
+ Transparent = 4,
+ Distortion = 5,
+ PrimitiveMesh = 6,
+ PrimitiveSolidMesh = 7,
+ Water = 8,
+ SpeedTree = 9,
+ GUI = 10,
+ GUIMesh = 11,
+ GUIMeshTransparent = 12,
+ ExpensiveTransparent =13,
+ Forward = 14,
+ RenderTarget = 15,
+ PostProcess = 16,
+ PrimitiveMaterial = 17,
+ PrimitiveSolidMaterial = 18,
+ SpineMaterial = 19
+ }
+
+ public enum MDFTypes
+ {
+ RE7 = 6,
+ RE2DMC5 = 10,
+ RE3 = 13,
+ MHRiseRE8 = 19,
+ RERT = 21,
+ Sunbreak = 23,
+ SF6 = 31,
+ DD2 = 40,
+ MHWilds = 45,
+ }
+
+ public class BooleanHolder : INotifyPropertyChanged
+ {
+ private string _name;
+ private bool _selected;
+ protected void OnPropertyChanged([CallerMemberName] string name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+ public string Name
+ {
+ get => _name; set
+ {
+ _name = value;
+ OnPropertyChanged(nameof(Name));
+ }
+ }
+ public bool Selected
+ {
+ get => _selected; set
+ {
+ _selected = value;
+ OnPropertyChanged(nameof(Selected));
+ }
+ }
+ public BooleanHolder(string name, bool selected)
+ {
+ Name = name;
+ Selected = selected;
+ }
+ public event PropertyChangedEventHandler PropertyChanged;
+ }
+
+ public class Material : INotifyPropertyChanged
+ {
+ private string _Name;
+ private uint _Hash;
+ public int NameOffsetIndex; //applied and used only on export
+ public int MMOffsetIndex;
+ public int materialIndex; //used for deleting and adding new
+ public int matSize;
+ public long propsStart;
+ public long propsEnd;
+ public int unk0;
+ public int unk1;
+ public int unk2;
+ public int gpbf0;
+ public int gpbf1;
+ public int GPBFCount = 0;
+ public MDFFile _Owner;
+
+ private void UpdateHash()
+ {
+ _Hash = HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(_Name));
+ OnPropertyChanged("UTF16Hash");
+ }
+ public string Name { get => _Name; set { _Name = value; OnPropertyChanged("Name"); UpdateHash(); } }
+ public MDFFile Owner { get => _Owner; set => _Owner = value; }
+ public uint UTF16Hash { get => _Hash; set => _Hash = value; }
+ public int MatSize {
+ get => matSize;
+ set {
+ matSize = value;
+ for (int i = 0; i < _Owner.Materials.Count; i++) {
+ if (_Owner.Materials[i].matSize > _Owner.largestPropsSize)
+ _Owner.largestPropsSize = _Owner.Materials[i].matSize;
+ }
+ for (int i = 0; i < _Owner.Materials.Count; i++)
+ _Owner.Materials[i].matSize = _Owner.largestPropsSize;
+ }
+ }
+ public string MasterMaterial { get; set; }
+ public ShadingType ShaderType { get; set; }
+ public byte TessFactor { get; set; }
+ public byte PhongFactor { get; set; }//shrug bytes are unsigned by default in C#
+ public long LastPropOffset { get; set; }
+ public int Unk0 { get; set; }
+ public int Unk1 { get; set; }
+ public int Unk2 { get; set; }
+ public int GPBF0 { get; set; }
+ public int GPBF1 { get; set; }
+ public int GetGPBFSize() { return 16; }
+ public int MaterialPropertyCount { get; set; }
+ public int MaterialTextureCount { get; set; }
+ public ObservableCollection flags { get; set; }
+ public List Textures { get; set; }
+ public List Properties { get; set; }
+ public List GPUBuffers { get; set; }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ protected void OnPropertyChanged([CallerMemberName] string name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public TextureBinding ReadTextureBinding(BinaryReader br, MDFTypes type)
+ {
+ Int64 TextureTypeOff = br.ReadInt64();
+ uint UTF16MMH3Hash = br.ReadUInt32();
+ uint ASCIIMMH3Hash = br.ReadUInt32();
+ Int64 FilePathOff = br.ReadInt64();
+ if(type >= MDFTypes.RE3)
+ {
+ Int64 Unkn0 = br.ReadInt64(); //value of 0 in most mdf, possible alignment?
+ }
+ Int64 EOT = br.BaseStream.Position;
+ br.BaseStream.Seek(TextureTypeOff, SeekOrigin.Begin);
+ string TextureType = HelperFunctions.ReadUniNullTerminatedString(br);
+ br.BaseStream.Seek(FilePathOff, SeekOrigin.Begin);
+ string FilePath = HelperFunctions.ReadUniNullTerminatedString(br);
+ br.BaseStream.Seek(EOT, SeekOrigin.Begin);
+ TextureBinding tb = new TextureBinding(TextureType,FilePath);
+ return tb;
+ }
+
+ public IVariableProp ReadProperty(BinaryReader br, Int64 dataOff, MDFTypes type, int matIndex, int propIndex)
+ {
+ Int64 PropNameOff = br.ReadInt64();
+ uint UTF16MMH3Hash = br.ReadUInt32();
+ uint ASCIIMMH3Hash = br.ReadUInt32();
+ int PropDataOff = 0;
+ int ParamCount = 0;
+
+ if (type >= MDFTypes.RE3)
+ {
+ PropDataOff = br.ReadInt32();
+ ParamCount = br.ReadInt32();
+ }
+ else
+ {
+ ParamCount = br.ReadInt32();
+ PropDataOff = br.ReadInt32();
+ }
+
+ Int64 EOP = br.BaseStream.Position;
+ br.BaseStream.Seek(PropNameOff, SeekOrigin.Begin);
+ string PropName = HelperFunctions.ReadUniNullTerminatedString(br);
+ br.BaseStream.Seek(dataOff + PropDataOff, SeekOrigin.Begin);
+
+ if (LastPropOffset == 0)
+ LastPropOffset = dataOff;
+ long GapSize = br.BaseStream.Position - LastPropOffset;
+
+ if (propsStart == 0)
+ propsStart = LastPropOffset;
+
+ switch (ParamCount)
+ {
+ case 1:
+ Float fData = new Float(br.ReadSingle());
+ LastPropOffset = br.BaseStream.Position;
+ propsEnd = br.BaseStream.Position;
+ while (propsEnd % 16 != propsStart % 16) propsEnd++;
+ br.BaseStream.Seek(EOP, SeekOrigin.Begin);
+ return new FloatProperty(PropName, fData, matIndex, propIndex, GapSize, (int)(dataOff + PropDataOff), this);
+ case 4:
+ Float4 f4Data = new Float4(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
+ LastPropOffset = br.BaseStream.Position;
+ propsEnd = br.BaseStream.Position;
+ while (propsEnd % 16 != propsStart % 16) propsEnd++;
+ br.BaseStream.Seek(EOP, SeekOrigin.Begin);
+ return new Float4Property(PropName, f4Data, matIndex, propIndex, GapSize, (int)(dataOff + PropDataOff), this);
+ default:
+ LastPropOffset = br.BaseStream.Position+4;
+ propsEnd = br.BaseStream.Position;
+ while (propsEnd % 16 != propsStart % 16) propsEnd++;
+ br.BaseStream.Seek(EOP, SeekOrigin.Begin);
+ return new FloatProperty(Name, new Float((float)1.0), matIndex, propIndex, GapSize, (int)(dataOff + PropDataOff), this);//shouldn't really come up ever
+ }
+
+ }
+
+ //SILVER: List for storing GPUBuffers
+ private List GPUBuffersList = new List();
+
+ public GPUBuffer ReadGPUBuffer(BinaryReader br)
+ {
+ Int64 GPBFNameOffset = br.ReadInt64();
+ //char[] GPBFNameUTF16Hash = Encoding.Unicode.GetChars(br.ReadBytes(4));
+ //char[] GPBFNameASCIIHash = Encoding.ASCII.GetChars(br.ReadBytes(4));
+ uint GPBFNameUTF16Hash = br.ReadUInt32();
+ uint GPBFNameASCIIHash = br.ReadUInt32();
+
+ Int64 EndOfGPUBuffer = br.BaseStream.Position;
+ br.BaseStream.Seek(GPBFNameOffset, SeekOrigin.Begin);
+ string GPBFName = HelperFunctions.ReadUniNullTerminatedString(br);
+ br.BaseStream.Seek(EndOfGPUBuffer, SeekOrigin.Begin);
+
+ Debug.WriteLine("GPBFNameOffset: " + GPBFNameOffset);
+ Debug.WriteLine("GPBFName: " + GPBFName);
+ Debug.WriteLine("GPBFNameUTF16Hash: " + (GPBFNameUTF16Hash.ToString()));
+ Debug.WriteLine("GPBFNameASCIIHash: " + (GPBFNameASCIIHash.ToString()));
+
+ GPUBuffer buffer = new GPUBuffer(GPBFNameOffset, GPBFName, GPBFNameUTF16Hash, GPBFNameASCIIHash);
+ GPUBuffersList.Add(buffer);
+ return buffer;
+ }
+
+ public int GetSize(MDFTypes type)
+ {
+ int baseVal = 64;
+ if(type == MDFTypes.RE7)
+ {
+ baseVal += 8;
+ }
+ else if (type >= MDFTypes.SF6)
+ {
+ baseVal += 36;
+ }
+ else if (type >= MDFTypes.MHRiseRE8){
+ baseVal += 16;
+ }
+ return baseVal;
+ }
+
+ public void ReadFlagsSection(BinaryReader br)
+ {
+ AlphaFlags alphaFlags = (AlphaFlags)br.ReadByte();
+ if ((alphaFlags & AlphaFlags.BaseTwoSideEnable) == AlphaFlags.BaseTwoSideEnable)
+ {
+ flags.Add(new BooleanHolder("BaseTwoSideEnable",true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("BaseTwoSideEnable", false));
+ }
+ if ((alphaFlags & AlphaFlags.BaseAlphaTestEnable) == AlphaFlags.BaseAlphaTestEnable)
+ {
+ flags.Add(new BooleanHolder("BaseAlphaTestEnable", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("BaseAlphaTestEnable", false));
+ }
+ if ((alphaFlags & AlphaFlags.ShadowCastDisable) == AlphaFlags.ShadowCastDisable)
+ {
+ flags.Add(new BooleanHolder("ShadowCastDisable", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("ShadowCastDisable", false));
+ }
+ if ((alphaFlags & AlphaFlags.VertexShaderUsed) == AlphaFlags.VertexShaderUsed)
+ {
+ flags.Add(new BooleanHolder("VertexShaderUsed", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("VertexShaderUsed", false));
+ }
+ if ((alphaFlags & AlphaFlags.EmissiveUsed) == AlphaFlags.EmissiveUsed)
+ {
+ flags.Add(new BooleanHolder("EmissiveUsed", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("EmissiveUsed", false));
+ }
+ if ((alphaFlags & AlphaFlags.TessellationEnable) == AlphaFlags.TessellationEnable)
+ {
+ flags.Add(new BooleanHolder("TessellationEnable", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("TessellationEnable", false));
+ }
+ if ((alphaFlags & AlphaFlags.EnableIgnoreDepth) == AlphaFlags.EnableIgnoreDepth)
+ {
+ flags.Add(new BooleanHolder("EnableIgnoreDepth", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("EnableIgnoreDepth", false));
+ }
+ if ((alphaFlags & AlphaFlags.AlphaMaskUsed) == AlphaFlags.AlphaMaskUsed)
+ {
+ flags.Add(new BooleanHolder("AlphaMaskUsed", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("AlphaMaskUsed", false));
+ }
+ byte flagByte = br.ReadByte();
+ Flags2 flagVals = (Flags2)flagByte;
+ if ((flagVals & Flags2.ForcedTwoSideEnable) == Flags2.ForcedTwoSideEnable)
+ {
+ flags.Add(new BooleanHolder("ForcedTwoSideEnable", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("ForcedTwoSideEnable", false));
+ }
+ if ((flagVals & Flags2.TwoSideEnable) == Flags2.TwoSideEnable)
+ {
+ flags.Add(new BooleanHolder("TwoSideEnable", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("TwoSideEnable", false));
+ }
+ TessFactor = (byte)(flagByte >> 2);
+ PhongFactor = br.ReadByte();
+ Flags3 Flags3 = (Flags3)br.ReadByte();
+ if ((Flags3 & Flags3.RoughTransparentEnable) == Flags3.RoughTransparentEnable)
+ {
+ flags.Add(new BooleanHolder("RoughTransparentEnable", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("RoughTransparentEnable", false));
+ }
+ if ((Flags3 & Flags3.ForcedAlphaTestEnable) == Flags3.ForcedAlphaTestEnable)
+ {
+ flags.Add(new BooleanHolder("ForcedAlphaTestEnable", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("ForcedAlphaTestEnable", false));
+ }
+ if ((Flags3 & Flags3.AlphaTestEnable) == Flags3.AlphaTestEnable)
+ {
+ flags.Add(new BooleanHolder("AlphaTestEnable", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("AlphaTestEnable", false));
+ }
+ if ((Flags3 & Flags3.SSSProfileUsed) == Flags3.SSSProfileUsed)
+ {
+ flags.Add(new BooleanHolder("SSSProfileUsed", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("SSSProfileUsed", false));
+ }
+ if ((Flags3 & Flags3.EnableStencilPriority) == Flags3.EnableStencilPriority)
+ {
+ flags.Add(new BooleanHolder("EnableStencilPriority", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("EnableStencilPriority", false));
+ }
+ if ((Flags3 & Flags3.RequireDualQuaternion) == Flags3.RequireDualQuaternion)
+ {
+ flags.Add(new BooleanHolder("RequireDualQuaternion", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("RequireDualQuaternion", false));
+ }
+ if ((Flags3 & Flags3.PixelDepthOffsetUsed) == Flags3.PixelDepthOffsetUsed)
+ {
+ flags.Add(new BooleanHolder("PixelDepthOffsetUsed", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("PixelDepthOffsetUsed", false));
+ }
+ if ((Flags3 & Flags3.NoRayTracing) == Flags3.NoRayTracing)
+ {
+ flags.Add(new BooleanHolder("NoRayTracing", true));
+ }
+ else
+ {
+ flags.Add(new BooleanHolder("NoRayTracing", false));
+ }
+
+ }
+
+ public Material(BinaryReader br,MDFTypes type, int matIndex, MDFFile owner)
+ {
+ Int64 GPBFOffset = 0;
+
+ _Owner = owner;
+ flags = new ObservableCollection();
+ materialIndex = matIndex;
+ Int64 MatNameOffset = br.ReadInt64();
+ int MatNameHash = br.ReadInt32();//not storing, since it'll just be easier to export proper
+ if(type == MDFTypes.RE7)
+ {
+ Int64 unknRE7 = br.ReadInt64();//I don't own RE7 so I'm just gonna hope these are 0s
+ }
+ int PropBlockSize = br.ReadInt32();
+ matSize = PropBlockSize;
+ int PropertyCount = br.ReadInt32();
+ MaterialPropertyCount = PropertyCount;
+ int TextureCount = br.ReadInt32();
+ MaterialTextureCount = TextureCount;
+ if(type >= MDFTypes.MHRiseRE8)
+ {
+ gpbf0 = br.ReadInt32();
+ gpbf1 = br.ReadInt32();
+ GPBFCount = gpbf0 + gpbf0;
+ }
+ ShaderType = (ShadingType)br.ReadInt32();
+ if (type >= MDFTypes.SF6)
+ {
+ unk0 = br.ReadInt32();
+ }
+ ReadFlagsSection(br);
+ if (type >= MDFTypes.SF6)
+ {
+ unk1 = br.ReadInt32();
+ unk2 = br.ReadInt32();
+ }
+ Int64 PropHeadersOff = br.ReadInt64();
+ Int64 TexHeadersOff = br.ReadInt64();
+ if(type >= MDFTypes.MHRiseRE8)
+ {
+ /*
+ Int64 StringTableOff = br.ReadInt64();//not at all useful, given everything uses absolute offsets
+
+ //it's possible that this is an offset for something that is not used by most mdfs, this will need to be looked into
+ //given the extra Int64, I find this very likely
+ */
+ //SILVER: This is only used in games after DD2, but possibly used in some SF6 MDFs. 10.31.2024
+ GPBFOffset = br.ReadInt64();
+ }
+ Int64 PropDataOff = br.ReadInt64();
+ Int64 MMTRPathOff = br.ReadInt64();
+ if (type >= MDFTypes.SF6)
+ {
+ br.ReadInt64();
+ }
+ Int64 EOM = br.BaseStream.Position;//to return to after reading the rest of the parameters
+ Textures = new List();
+ Properties = new List();
+ //now we'll go grab names and values
+ br.BaseStream.Seek(MatNameOffset, SeekOrigin.Begin);
+ Name = HelperFunctions.ReadUniNullTerminatedString(br);
+ br.BaseStream.Seek(MMTRPathOff, SeekOrigin.Begin);
+ MasterMaterial = HelperFunctions.ReadUniNullTerminatedString(br);
+
+ //read textures
+ br.BaseStream.Seek(TexHeadersOff,SeekOrigin.Begin);
+ for(int i = 0; i < TextureCount; i++)
+ {
+ Textures.Add(ReadTextureBinding(br,type));
+ }
+
+ //read properties
+ br.BaseStream.Seek(PropHeadersOff, SeekOrigin.Begin);
+
+ for (int i = 0; i < PropertyCount; i++)
+ {
+ Properties.Add(ReadProperty(br,PropDataOff,type,matIndex,i));
+ }
+ //SILVER: Read GPUBuffers
+ GPUBuffers = new List();
+ br.BaseStream.Seek(GPBFOffset, SeekOrigin.Begin);
+ for (int i = 0; i < GPBFCount; i++)
+ {
+ GPUBuffers.Add(ReadGPUBuffer(br));
+ Debug.WriteLine("GPBFCount:" + GPBFCount);
+ }
+
+ //propsStart = Properties[0].dataStartOffs;
+ //propsEnd = Properties[0].dataStartOffs + Properties[0].GetSize();
+ //matSize = (int)(Properties[PropertyCount-1].dataStartOffs + Properties[PropertyCount - 1].GetSize() - Properties[0].dataStartOffs);
+
+ br.BaseStream.Seek(EOM,SeekOrigin.Begin);
+ }
+ public byte[] GenerateFlagsSection()
+ {
+ AlphaFlags flags1 = 0;
+ Flags2 flags2 = (Flags2)(TessFactor << 2);
+ Flags3 flags3 = 0;
+ for(int i = 0; i < flags.Count; i++)
+ {
+ switch (flags[i].Name)
+ {
+ case "BaseTwoSideEnable":
+ if (flags[i].Selected)
+ {
+ flags1 = flags1 | AlphaFlags.BaseTwoSideEnable;
+ }
+ break;
+ case "BaseAlphaTestEnable":
+ if (flags[i].Selected)
+ {
+ flags1 = flags1 | AlphaFlags.BaseAlphaTestEnable;
+ }
+ break;
+ case "ShadowCastDisable":
+ if (flags[i].Selected)
+ {
+ flags1 = flags1 | AlphaFlags.ShadowCastDisable;
+ }
+ break;
+ case "VertexShaderUsed":
+ if (flags[i].Selected)
+ {
+ flags1 = flags1 | AlphaFlags.VertexShaderUsed;
+ }
+ break;
+ case "EmissiveUsed":
+ if (flags[i].Selected)
+ {
+ flags1 = flags1 | AlphaFlags.EmissiveUsed;
+ }
+ break;
+ case "TessellationEnable":
+ if (flags[i].Selected)
+ {
+ flags1 = flags1 | AlphaFlags.TessellationEnable;
+ }
+ break;
+ case "EnableIgnoreDepth":
+ if (flags[i].Selected)
+ {
+ flags1 = flags1 | AlphaFlags.EnableIgnoreDepth;
+ }
+ break;
+ case "AlphaMaskUsed":
+ if (flags[i].Selected)
+ {
+ flags1 = flags1 | AlphaFlags.AlphaMaskUsed;
+ }
+ break;
+ case "ForcedTwoSideEnable":
+ if (flags[i].Selected)
+ {
+ flags2 = flags2 | Flags2.ForcedTwoSideEnable;
+ }
+ break;
+ case "TwoSideEnable":
+ if (flags[i].Selected)
+ {
+ flags2 = flags2 | Flags2.TwoSideEnable;
+ }
+ break;
+ case "RoughTransparentEnable":
+ if (flags[i].Selected)
+ {
+ flags3 = flags3 | Flags3.RoughTransparentEnable;
+ }
+ break;
+ case "ForcedAlphaTestEnable":
+ if (flags[i].Selected)
+ {
+ flags3 = flags3 | Flags3.ForcedAlphaTestEnable;
+ }
+ break;
+ case "AlphaTestEnable":
+ if (flags[i].Selected)
+ {
+ flags3 = flags3 | Flags3.AlphaTestEnable;
+ }
+ break;
+ case "SSSProfileUsed":
+ if (flags[i].Selected)
+ {
+ flags3 = flags3 | Flags3.SSSProfileUsed;
+ }
+ break;
+ case "EnableStencilPriority":
+ if (flags[i].Selected)
+ {
+ flags3 = flags3 | Flags3.EnableStencilPriority;
+ }
+ break;
+ case "RequireDualQuaternion":
+ if (flags[i].Selected)
+ {
+ flags3 = flags3 | Flags3.RequireDualQuaternion;
+ }
+ break;
+ case "PixelDepthOffsetUsed":
+ if (flags[i].Selected)
+ {
+ flags3 = flags3 | Flags3.PixelDepthOffsetUsed;
+ }
+ break;
+ case "NoRayTracing":
+ if (flags[i].Selected)
+ {
+ flags3 = flags3 | Flags3.NoRayTracing;
+ }
+ break;
+
+ }
+ }
+ byte[] returnBytes = new byte[4];
+ returnBytes[0] = (byte)flags1;
+ returnBytes[1] = (byte)flags2;
+ returnBytes[2] = PhongFactor;
+ returnBytes[3] = (byte)flags3;
+ return returnBytes;
+ }
+ public void UpdateMaterialIndex(int index)
+ {
+ materialIndex = index;
+ for(int i = 0; i < Properties.Count; i++)
+ {
+ Properties[i].indexes[0] = index;
+ }
+ }
+ public void Export(BinaryWriter bw, MDFTypes type, ref long materialOffset, ref long textureOffset, ref long propHeaderOffset, long GPBFOffset, long stringsOffset, List strTableOffsets, ref long propertiesOffset, int largestPropsSize)
+ {
+ bw.BaseStream.Seek(materialOffset,SeekOrigin.Begin);
+
+ bw.Write(stringsOffset + strTableOffsets[NameOffsetIndex]);
+ bw.Write(HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(Name)));
+
+ if (type == MDFTypes.RE7)
+ {
+ bw.Write((long)0);
+ }
+ int propSize = 0;
+ for(int i = 0; i < Properties.Count; i++)
+ {
+ propSize += Properties[i].GetSize();
+ }
+ while((propSize %16) != 0)
+ {
+ propSize += 1;
+ }
+ long pos = bw.BaseStream.Position;
+ bw.Write(propSize);
+ bw.Write(Properties.Count);
+ bw.Write(Textures.Count);
+ if(type >= MDFTypes.MHRiseRE8)
+ {
+ bw.Write(gpbf0);
+ bw.Write(gpbf1);
+ }
+ bw.Write((uint)ShaderType);
+ if (type >= MDFTypes.SF6)
+ {
+ bw.Write(unk0);
+ }
+ bw.Write(GenerateFlagsSection());
+ if (type >= MDFTypes.SF6)
+ {
+ bw.Write(unk1);
+ bw.Write(unk2);
+ }
+ bw.Write(propHeaderOffset);
+ bw.Write(textureOffset);
+ if(type >= MDFTypes.MHRiseRE8)
+ {
+ bw.Write(GPBFOffset);
+ }
+ bw.Write(propertiesOffset);
+ bw.Write(stringsOffset + strTableOffsets[MMOffsetIndex]);
+ if (type >= MDFTypes.SF6)
+ {
+ bw.Write((long)0);
+ }
+ //end of actual material file, now update material offset and write textures/properties
+ materialOffset += GetSize(type);
+ for(int i = 0; i < Textures.Count; i++)
+ {
+ Textures[i].Export(bw, type, ref textureOffset, stringsOffset, strTableOffsets);
+ }
+ long basePropOffset = propertiesOffset;//subtract by current prop offset to make inner offset
+ for(int i = 0; i < Properties.Count; i++)
+ {
+ Properties[i].Export(bw, type, ref propHeaderOffset, ref propertiesOffset, basePropOffset, stringsOffset, strTableOffsets);
+ }
+ //SILVER: Write GPUBuffers
+
+ for (int i = 0; i < GPUBuffersList.Count; i++)
+ {
+ bw.BaseStream.Seek(GPBFOffset + i*GetGPBFSize(), SeekOrigin.Begin);
+ GPUBuffer buffer = GPUBuffersList[i];
+ bw.Write(stringsOffset + strTableOffsets[buffer.NameOffsetIndex]);
+ bw.Write(buffer.GPBFNameUTF16Hash);
+ bw.Write(buffer.GPBFNameASCIIHash);
+ //bw.Write(Encoding.Unicode.GetBytes(buffer.GPUBufferName));
+ }
+ if ((basePropOffset + propSize) != propertiesOffset)
+ {
+ //Int64 diff = basePropOffset + propSize - propertiesOffset;
+ //propertiesOffset += diff;
+ propertiesOffset = basePropOffset + largestPropsSize;
+ }
+ long endPos = bw.BaseStream.Position;
+ bw.BaseStream.Seek(pos, SeekOrigin.Begin);
+ bw.Write((int)(largestPropsSize));
+ bw.BaseStream.Seek(endPos, SeekOrigin.Begin);
+ }
+ }
+}
diff --git a/MDF-Manager/Classes/TextureBinding.cs b/MDF-Manager/Classes/TextureBinding.cs
index 136c887..a131209 100644
--- a/MDF-Manager/Classes/TextureBinding.cs
+++ b/MDF-Manager/Classes/TextureBinding.cs
@@ -1,51 +1,51 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace MDF_Manager.Classes
-{
- public class TextureBinding
- {
- public int NameOffsetIndex;
- public int PathOffsetIndex;
- public string name { get; set; }
- public string path { get; set; }
- public int GetSize(MDFTypes type)
- {
- if (type >= MDFTypes.RE3)
- {
- return 32;
- }
- else
- {
- return 24;
- }
- }
- public TextureBinding()//this should never be used, but needed for JSON iirc
- {
- name = "BaseMetalMap";
- path = "systems/rendering/nullblack.tex";
- }
- public TextureBinding(string pName, string pPath)
- {
- name = pName;
- path = pPath;
- }
-
- public void Export(BinaryWriter bw, MDFTypes type, ref long offset, long stringTableOffset, List strTableOffs)
- {
- bw.BaseStream.Seek(offset,SeekOrigin.Begin);
- bw.Write(stringTableOffset + strTableOffs[NameOffsetIndex]);
- bw.Write(HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(name)));
- bw.Write(HelperFunctions.Murmur3Hash(Encoding.ASCII.GetBytes(name)));//potentially UTF8 rather than ASCII, but further testing would be required
- bw.Write(stringTableOffset + strTableOffs[PathOffsetIndex]);
- if(type >= MDFTypes.RE3)
- {
- bw.Write((long)0);
- }
- offset += GetSize(type);
- }
-
- }
-}
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace MDF_Manager.Classes
+{
+ public class TextureBinding
+ {
+ public int NameOffsetIndex;
+ public int PathOffsetIndex;
+ public string name { get; set; }
+ public string path { get; set; }
+ public int GetSize(MDFTypes type)
+ {
+ if (type >= MDFTypes.RE3)
+ {
+ return 32;
+ }
+ else
+ {
+ return 24;
+ }
+ }
+ public TextureBinding()//this should never be used, but needed for JSON iirc
+ {
+ name = "BaseMetalMap";
+ path = "systems/rendering/nullblack.tex";
+ }
+ public TextureBinding(string pName, string pPath)
+ {
+ name = pName;
+ path = pPath;
+ }
+
+ public void Export(BinaryWriter bw, MDFTypes type, ref long offset, long stringTableOffset, List strTableOffs)
+ {
+ bw.BaseStream.Seek(offset,SeekOrigin.Begin);
+ bw.Write(stringTableOffset + strTableOffs[NameOffsetIndex]);
+ bw.Write(HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(name)));
+ bw.Write(HelperFunctions.Murmur3Hash(Encoding.ASCII.GetBytes(name)));//potentially UTF8 rather than ASCII, but further testing would be required
+ bw.Write(stringTableOffset + strTableOffs[PathOffsetIndex]);
+ if(type >= MDFTypes.RE3)
+ {
+ bw.Write((long)0);
+ }
+ offset += GetSize(type);
+ }
+
+ }
+}
diff --git a/MDF-Manager/Classes/VariableProperty.cs b/MDF-Manager/Classes/VariableProperty.cs
index 614eb83..0caa32b 100644
--- a/MDF-Manager/Classes/VariableProperty.cs
+++ b/MDF-Manager/Classes/VariableProperty.cs
@@ -1,188 +1,229 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Windows.Media;
-
-namespace MDF_Manager.Classes
-{
- public class Float
- {
- public float data { get; set; }
- public Float(float fData)
- {
- data = fData;
- }
- }
- public class Float4 : INotifyPropertyChanged
- {
- private Color _mColor;
- private Brush _Brush;
- private float _X;
- private float _Y;
- private float _Z;
- private float _W;
-
- public event PropertyChangedEventHandler PropertyChanged;
- protected void OnPropertyChanged([CallerMemberName] string name = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- }
-
- public void UpdateBrush()
- {
- byte[] hexArray = { _mColor.R, _mColor.G, _mColor.B };
- string hexBrush = "#" + BitConverter.ToString(hexArray).Replace("-", "");
- mBrush = HelperFunctions.GetBrushFromHex(hexBrush);
- OnPropertyChanged("mBrush");
- }
- public void UpdateColor()
- {
- _mColor.ScR = HelperFunctions.Clamp(x, 0, 1);
- _mColor.ScG = HelperFunctions.Clamp(y, 0, 1);
- _mColor.ScB = HelperFunctions.Clamp(z, 0, 1);
- _mColor.ScA = HelperFunctions.Clamp(w, 0, 1);
- UpdateBrush();
- }
- public float x { get => _X; set { _X = value; UpdateColor(); OnPropertyChanged("x"); } }
- public float y { get => _Y; set { _Y = value; UpdateColor(); OnPropertyChanged("y"); } }
- public float z { get => _Z; set { _Z = value; UpdateColor(); OnPropertyChanged("z"); } }
- public float w { get => _W; set { _W = value; UpdateColor(); OnPropertyChanged("w"); } }
- public Color mColor { get { return _mColor; } set { _mColor = value; UpdateBrush(); } }
- public Brush mBrush { get { return _Brush; } set { _Brush = value; } }
- public Float4(float fX, float fY, float fZ, float fW)
- {
- x = fX;
- y = fY;
- z = fZ;
- w = fW;
- }
-
- }
- public interface IVariableProp
- {
- int NameOffsetIndex { get; set; }
- int ValOffset { get; set; }
- string name { get; set; }
- object value { get; set; }
- int[] indexes { get; set; }
- int GetSize();
- int GetPropHeaderSize();
- void Export(BinaryWriter bw, MDFTypes type, ref long propHeadOff, ref long propOff, long basePropOff, long stringTableOff, List strTableOffs);
- }
- public class FloatProperty : IVariableProp
- {
- public int NameOffsetIndex { get; set; }
- public int ValOffset { get; set; }
- private string _Name;
- private Float _Default;
- public string name { get => _Name; set => _Name = value; }
- public object value { get => _Default; set => _Default = (Float)value; }
- public int[] indexes { get; set;}
- public FloatProperty(string Name, Float Value,int matIndex, int propIndex)
- {
- indexes = new int[2];
- name = Name;
- value = Value;
- indexes[0] = matIndex;
- indexes[1] = propIndex;
- }
- public int GetSize()
- {
- return 4;
- }
- public int GetPropHeaderSize()
- {
- return 24;
- }
-
- public void Export(BinaryWriter bw, MDFTypes type, ref long propHeadOff, ref long propOff, long basePropOff, long stringTableOff, List strTableOffs)
- {
- uint innerPropOff = (uint)(propOff - basePropOff);
- bw.BaseStream.Seek(propHeadOff, SeekOrigin.Begin);
- bw.Write(stringTableOff + strTableOffs[NameOffsetIndex]);
- bw.Write(HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(name)));
- bw.Write(HelperFunctions.Murmur3Hash(Encoding.ASCII.GetBytes(name)));//potentially UTF8 rather than ASCII, but further testing would be required
- if(type >= MDFTypes.RE3)
- {
- bw.Write(innerPropOff);
- bw.Write(1);
- }
- else
- {
- bw.Write(1);
- bw.Write(innerPropOff);
- }
- //update propHeadOff then write value to floatarr
- propHeadOff += GetPropHeaderSize();
-
- bw.BaseStream.Seek(propOff, SeekOrigin.Begin);
- bw.Write(_Default.data);
- propOff += GetSize();
- }
- }
- public class Float4Property : IVariableProp, INotifyPropertyChanged
- {
- public int NameOffsetIndex { get; set; }
- public int ValOffset { get; set; }
- private string _Name;
- private Float4 _Default;
-
- public event PropertyChangedEventHandler PropertyChanged;
- protected void OnPropertyChanged([CallerMemberName] string name = null)
- {
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
- }
-
- public string name { get => _Name; set => _Name = value; }
- public object value { get => _Default; set { _Default = (Float4)value; OnPropertyChanged("value"); _Default.UpdateColor(); } }
- public int[] indexes { get; set; }
-
- public Float4Property(string Name, Float4 Value, int matIndex, int propIndex)
- {
- indexes = new int[2];
- name = Name;
- value = Value;
- indexes[0] = matIndex;
- indexes[1] = propIndex;
- }
- public int GetPropHeaderSize()
- {
- return 24;
- }
- public int GetSize()
- {
- return 16;
- }
-
- public void Export(BinaryWriter bw, MDFTypes type, ref long propHeadOff, ref long propOff, long basePropOff, long stringTableOff, List strTableOffs)
- {
- uint innerPropOff = (uint)(propOff - basePropOff);
- bw.BaseStream.Seek(propHeadOff, SeekOrigin.Begin);
- bw.Write(stringTableOff + strTableOffs[NameOffsetIndex]);
- bw.Write(HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(name)));
- bw.Write(HelperFunctions.Murmur3Hash(Encoding.ASCII.GetBytes(name)));//potentially UTF8 rather than ASCII, but further testing would be required
- if (type >= MDFTypes.RE3)
- {
- bw.Write(innerPropOff);
- bw.Write(4);
- }
- else
- {
- bw.Write(4);
- bw.Write(innerPropOff);
- }
- //update propHeadOff then write value to floatarr
- propHeadOff += GetPropHeaderSize();
-
- bw.BaseStream.Seek(propOff, SeekOrigin.Begin);
- bw.Write(_Default.x);
- bw.Write(_Default.y);
- bw.Write(_Default.z);
- bw.Write(_Default.w);
- propOff += GetSize();
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Windows.Media;
+
+namespace MDF_Manager.Classes
+{
+ public class Float
+ {
+ public float data { get; set; }
+ public Float(float fData)
+ {
+ data = fData;
+ }
+ }
+ public class Float4 : INotifyPropertyChanged
+ {
+ private Color _mColor;
+ private Brush _Brush;
+ private float _X;
+ private float _Y;
+ private float _Z;
+ private float _W;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ protected void OnPropertyChanged([CallerMemberName] string name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public void UpdateBrush()
+ {
+ byte[] hexArray = { _mColor.R, _mColor.G, _mColor.B };
+ string hexBrush = "#" + BitConverter.ToString(hexArray).Replace("-", "");
+ mBrush = HelperFunctions.GetBrushFromHex(hexBrush);
+ OnPropertyChanged("mBrush");
+ }
+ public void UpdateColor()
+ {
+ _mColor.ScR = HelperFunctions.Clamp(x, 0, 1);
+ _mColor.ScG = HelperFunctions.Clamp(y, 0, 1);
+ _mColor.ScB = HelperFunctions.Clamp(z, 0, 1);
+ _mColor.ScA = HelperFunctions.Clamp(w, 0, 1);
+ UpdateBrush();
+ }
+ public float x { get => _X; set { _X = value; UpdateColor(); OnPropertyChanged("x"); } }
+ public float y { get => _Y; set { _Y = value; UpdateColor(); OnPropertyChanged("y"); } }
+ public float z { get => _Z; set { _Z = value; UpdateColor(); OnPropertyChanged("z"); } }
+ public float w { get => _W; set { _W = value; UpdateColor(); OnPropertyChanged("w"); } }
+ public Color mColor { get { return _mColor; } set { _mColor = value; UpdateBrush(); } }
+ public Brush mBrush { get { return _Brush; } set { _Brush = value; } }
+ public Float4(float fX, float fY, float fZ, float fW)
+ {
+ x = fX;
+ y = fY;
+ z = fZ;
+ w = fW;
+ }
+
+ }
+ public interface IVariableProp
+ {
+ int NameOffsetIndex { get; set; }
+ int ValOffset { get; set; }
+ string name { get; set; }
+ Material mat { get; set; }
+ object value { get; set; }
+ int[] indexes { get; set; }
+ int GetSize();
+ int GetPropHeaderSize();
+ int dataStartOffs { get; set; }
+ void Export(BinaryWriter bw, MDFTypes type, ref long propHeadOff, ref long propOff, long basePropOff, long stringTableOff, List strTableOffs);
+ }
+ public class FloatProperty : IVariableProp
+ {
+ public int NameOffsetIndex { get; set; }
+ public int ValOffset { get; set; }
+ private string _Name;
+ private Material _Mat;
+ private Float _Default;
+ private uint _GapSize;
+ public string name { get => _Name; set => _Name = value; }
+ public Material mat { get => _Mat; set => _Mat = value; }
+ public object value { get => _Default; set => _Default = (Float)value; }
+ public int[] indexes { get; set;}
+ public int dataStartOffs { get; set; }
+ public uint gapSize { get => _GapSize; set { _GapSize = value; } }
+ public FloatProperty(string Name, Float Value,int matIndex, int propIndex, long GapSize, int start, Material owner)
+ {
+ indexes = new int[2];
+ name = Name;
+ mat = owner;
+ value = Value;
+ indexes[0] = matIndex;
+ indexes[1] = propIndex;
+ gapSize = (uint)GapSize;
+ dataStartOffs = start;
+ }
+ public int GetSize()
+ {
+ return 4 + (int)_GapSize; ;
+ }
+ public int GetPropHeaderSize()
+ {
+ return 24;
+ }
+
+ public void Export(BinaryWriter bw, MDFTypes type, ref long propHeadOff, ref long propOff, long basePropOff, long stringTableOff, List strTableOffs)
+ {
+ uint innerPropOff = (uint)(propOff - basePropOff);
+ bw.BaseStream.Seek(propHeadOff, SeekOrigin.Begin);
+ bw.Write(stringTableOff + strTableOffs[NameOffsetIndex]);
+ bw.Write(HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(name)));
+ bw.Write(HelperFunctions.Murmur3Hash(Encoding.ASCII.GetBytes(name)));//potentially UTF8 rather than ASCII, but further testing would be required
+ if(type >= MDFTypes.RE3)
+ {
+ bw.Write(innerPropOff + _GapSize);
+ bw.Write(1);
+ }
+ else
+ {
+ bw.Write(1);
+ bw.Write(innerPropOff);
+ }
+ //update propHeadOff then write value to floatarr
+ propHeadOff += GetPropHeaderSize();
+
+ bw.BaseStream.Seek(propOff, SeekOrigin.Begin);
+ if (gapSize > 0)
+ for (int i = 0; i < gapSize / 4; i++)
+ bw.Write(0);
+
+ bw.Write(_Default.data);
+ propOff += GetSize();
+ }
+ }
+ public class Float4Property : IVariableProp, INotifyPropertyChanged
+ {
+ public int NameOffsetIndex { get; set; }
+ public int ValOffset { get; set; }
+ private string _Name;
+ private Material _Mat;
+ private Float4 _Default;
+ private uint _GapSize;
+ private uint _UIGapSize;
+ public int dataStartOffs { get; set; }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ protected void OnPropertyChanged([CallerMemberName] string name = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+ }
+
+ public string name { get => _Name; set => _Name = value; }
+ public Material mat { get => _Mat; set => _Mat = value; }
+ public object value { get => _Default; set { _Default = (Float4)value; OnPropertyChanged("value"); _Default.UpdateColor(); } }
+ public int[] indexes { get; set; }
+ public uint gapSize { get => _GapSize; set { _GapSize = value; } }
+ public uint UIGapSize
+ {
+ get => _GapSize;
+ set
+ {
+ uint oldSize = gapSize;
+ gapSize = value;
+ if ((gapSize - oldSize) > 0)
+ mat.MatSize += (int)(gapSize - oldSize); //unused
+ }
+ }
+
+ public Float4Property(string Name, Float4 Value, int matIndex, int propIndex, long GapSize, int start, Material owner)
+ {
+
+ indexes = new int[2];
+ name = Name;
+ mat = owner;
+ value = Value;
+ indexes[0] = matIndex;
+ indexes[1] = propIndex;
+ gapSize = (uint)GapSize;
+ dataStartOffs = start;
+ }
+ public int GetPropHeaderSize()
+ {
+ return 24;
+ }
+ public int GetSize()
+ {
+ return 16 + (int)_GapSize;
+ }
+
+ public void Export(BinaryWriter bw, MDFTypes type, ref long propHeadOff, ref long propOff, long basePropOff, long stringTableOff, List strTableOffs)
+ {
+ dataStartOffs = (int)(propOff + basePropOff);
+ uint innerPropOff = (uint)(propOff - basePropOff);
+ bw.BaseStream.Seek(propHeadOff, SeekOrigin.Begin);
+ bw.Write(stringTableOff + strTableOffs[NameOffsetIndex]);
+ bw.Write(HelperFunctions.Murmur3Hash(Encoding.Unicode.GetBytes(name)));
+ bw.Write(HelperFunctions.Murmur3Hash(Encoding.ASCII.GetBytes(name)));//potentially UTF8 rather than ASCII, but further testing would be required
+ if (type >= MDFTypes.RE3)
+ {
+ bw.Write(innerPropOff + _GapSize);
+ bw.Write(4);
+ }
+ else
+ {
+ bw.Write(4);
+ bw.Write(innerPropOff);
+ }
+ //update propHeadOff then write value to floatarr
+ propHeadOff += GetPropHeaderSize();
+
+ bw.BaseStream.Seek(propOff, SeekOrigin.Begin);
+
+ if (gapSize > 0)
+ for (int i = 0; i < gapSize / 4; i++)
+ bw.Write(0);
+
+ bw.Write(_Default.x);
+ bw.Write(_Default.y);
+ bw.Write(_Default.z);
+ bw.Write(_Default.w);
+ propOff += GetSize();
+ }
+ }
+}
diff --git a/MDF-Manager/ColorCanvas.xaml b/MDF-Manager/ColorCanvas.xaml
index 7a2fa7b..83fcb49 100644
--- a/MDF-Manager/ColorCanvas.xaml
+++ b/MDF-Manager/ColorCanvas.xaml
@@ -1,12 +1,12 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/MDF-Manager/ColorCanvas.xaml.cs b/MDF-Manager/ColorCanvas.xaml.cs
index 8612abf..5d835d3 100644
--- a/MDF-Manager/ColorCanvas.xaml.cs
+++ b/MDF-Manager/ColorCanvas.xaml.cs
@@ -1,36 +1,36 @@
-using System.Windows;
-using System.Drawing;
-
-namespace MDF_Manager
-{
- ///
- /// Interaction logic for Window1.xaml
- ///
- public partial class ColorCanvas : Window
- {
-
- public ColorCanvas()
- {
- InitializeComponent();
-
- }
-
- public void Confirm(object sender, RoutedEventArgs e)
- {
- DialogResult = true;
- Close();
- }
-
- private void ApplyColor(object sender, RoutedEventArgs e)
- {
- try
- {
- colorCanvas.HexadecimalString = ColorEntry.Text;
- }
- catch (System.IO.InvalidDataException)
- {
- MessageBox.Show("Invalid color!");
- }
- }
- }
-}
+using System.Windows;
+using System.Drawing;
+
+namespace MDF_Manager
+{
+ ///
+ /// Interaction logic for Window1.xaml
+ ///
+ public partial class ColorCanvas : Window
+ {
+
+ public ColorCanvas()
+ {
+ InitializeComponent();
+
+ }
+
+ public void Confirm(object sender, RoutedEventArgs e)
+ {
+ DialogResult = true;
+ Close();
+ }
+
+ private void ApplyColor(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+ colorCanvas.HexadecimalString = ColorEntry.Text;
+ }
+ catch (System.IO.InvalidDataException)
+ {
+ MessageBox.Show("Invalid color!");
+ }
+ }
+ }
+}
diff --git a/MDF-Manager/HelperFunctions.cs b/MDF-Manager/HelperFunctions.cs
index 710f7db..041ffa1 100644
--- a/MDF-Manager/HelperFunctions.cs
+++ b/MDF-Manager/HelperFunctions.cs
@@ -1,149 +1,149 @@
-using Murmur;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Security.Cryptography;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Windows;
-using System.Windows.Media;
-
-namespace MDF_Manager
-{
- class HelperFunctions
- {
- public static HashAlgorithm mm3h = MurmurHash.Create32(seed:0xFFFFFFFF);
- public static string ReadUniNullTerminatedString(BinaryReader br)
- {
-
- List stringC = new List();
- char newByte = br.ReadChar();
- while (newByte != 0)
- {
- stringC.Add(newByte);
- newByte = br.ReadChar();
- }
- return new string(stringC.ToArray());
- }
-
- public static void WriteUniNullTerminatedString(BinaryWriter bw, string str)
- {
- bw.Write(Encoding.Unicode.GetBytes(str.ToCharArray()));
- bw.Write((Int16)0);
- }
-
- public static Brush GetBrushFromHex(string hexColor)
- {
- BrushConverter bc = new BrushConverter();
- Brush newBrush = (Brush)bc.ConvertFrom(hexColor);
- return newBrush;
- }
-
- public static Brush GetBrushFromColor(Color c)
- {
- BrushConverter bc = new BrushConverter();
- Brush nb = (Brush)bc.ConvertFrom(c.ToString());
- return nb;
- }
-
- public static byte[] Combine(byte[] first, byte[] second)
- {
- byte[] bytes = new byte[first.Length + second.Length];
- Buffer.BlockCopy(first, 0, bytes, 0, first.Length);
- Buffer.BlockCopy(second, 0, bytes, first.Length, second.Length);
- return bytes;
- }
-
- public static uint Murmur3Hash(byte[] str)
- {
- return BitConverter.ToUInt32(mm3h.ComputeHash(str),0);
- }
-
- public static float Clamp(float input, float min, float max)
- {
- if (input > max)
- {
- return max;
- }
- else
- {
- if(input < min)
- {
- return min;
- }
- else
- {
- return input;
- }
- }
- }
- public static void Swap(IList list, int indexA, int indexB)
- {
- T tmp = list[indexA];
- list[indexA] = list[indexB];
- list[indexB] = tmp;
- }
-
- public static BinaryReader OpenFileR(string filename, Encoding encoding = null, FileMode mode = FileMode.Open)//surprised it doesn't get too mad at me here
- {
- if (encoding is null)
- {
- encoding = Encoding.ASCII;
- }
-
- try
- {
- BinaryReader br = new BinaryReader(new FileStream(filename, mode), encoding);
- return br;
- }
- catch (IOException)
- {
- MessageBox.Show("File could not be opened, likely because it is being used by another process.");
- return null;
- }
-
- }
-
- public static BinaryWriter OpenFileW(string filename, Encoding encoding = null, FileMode mode = FileMode.Create)
- {
- if (encoding is null)
- {
- encoding = Encoding.ASCII;
- }
-
- try
- {
- BinaryWriter bw = new BinaryWriter(new FileStream(filename, mode), encoding);
- return bw;
- }
- catch (IOException)
- {
- MessageBox.Show("File could not be opened, likely because it is being used by another process.");
- return null;
- }
-
- }
-
- public static FileStream OpenFileStream(string filename, FileMode mode = FileMode.Create)
- {
- try
- {
- FileStream fs = new FileStream(filename, mode);
- return fs;
- }
- catch (IOException)
- {
- MessageBox.Show("File could not be opened, likely because it is being used by another process.");
- return null;
- }
- }
- }
- static public class StringExtensions
- {
- static public string ReplaceInsensitive(this string str, string from, string to)
- {
- str = Regex.Replace(str, from, to, RegexOptions.IgnoreCase);
- return str;
- }
- }
-}
+using Murmur;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows;
+using System.Windows.Media;
+
+namespace MDF_Manager
+{
+ class HelperFunctions
+ {
+ public static HashAlgorithm mm3h = MurmurHash.Create32(seed:0xFFFFFFFF);
+ public static string ReadUniNullTerminatedString(BinaryReader br)
+ {
+
+ List stringC = new List();
+ char newByte = br.ReadChar();
+ while (newByte != 0)
+ {
+ stringC.Add(newByte);
+ newByte = br.ReadChar();
+ }
+ return new string(stringC.ToArray());
+ }
+
+ public static void WriteUniNullTerminatedString(BinaryWriter bw, string str)
+ {
+ bw.Write(Encoding.Unicode.GetBytes(str.ToCharArray()));
+ bw.Write((Int16)0);
+ }
+
+ public static Brush GetBrushFromHex(string hexColor)
+ {
+ BrushConverter bc = new BrushConverter();
+ Brush newBrush = (Brush)bc.ConvertFrom(hexColor);
+ return newBrush;
+ }
+
+ public static Brush GetBrushFromColor(Color c)
+ {
+ BrushConverter bc = new BrushConverter();
+ Brush nb = (Brush)bc.ConvertFrom(c.ToString());
+ return nb;
+ }
+
+ public static byte[] Combine(byte[] first, byte[] second)
+ {
+ byte[] bytes = new byte[first.Length + second.Length];
+ Buffer.BlockCopy(first, 0, bytes, 0, first.Length);
+ Buffer.BlockCopy(second, 0, bytes, first.Length, second.Length);
+ return bytes;
+ }
+
+ public static uint Murmur3Hash(byte[] str)
+ {
+ return BitConverter.ToUInt32(mm3h.ComputeHash(str),0);
+ }
+
+ public static float Clamp(float input, float min, float max)
+ {
+ if (input > max)
+ {
+ return max;
+ }
+ else
+ {
+ if(input < min)
+ {
+ return min;
+ }
+ else
+ {
+ return input;
+ }
+ }
+ }
+ public static void Swap(IList list, int indexA, int indexB)
+ {
+ T tmp = list[indexA];
+ list[indexA] = list[indexB];
+ list[indexB] = tmp;
+ }
+
+ public static BinaryReader OpenFileR(string filename, Encoding encoding = null, FileMode mode = FileMode.Open)//surprised it doesn't get too mad at me here
+ {
+ if (encoding is null)
+ {
+ encoding = Encoding.ASCII;
+ }
+
+ try
+ {
+ BinaryReader br = new BinaryReader(new FileStream(filename, mode), encoding);
+ return br;
+ }
+ catch (IOException)
+ {
+ MessageBox.Show("File could not be opened, likely because it is being used by another process.");
+ return null;
+ }
+
+ }
+
+ public static BinaryWriter OpenFileW(string filename, Encoding encoding = null, FileMode mode = FileMode.Create)
+ {
+ if (encoding is null)
+ {
+ encoding = Encoding.ASCII;
+ }
+
+ try
+ {
+ BinaryWriter bw = new BinaryWriter(new FileStream(filename, mode), encoding);
+ return bw;
+ }
+ catch (IOException)
+ {
+ MessageBox.Show("File could not be opened, likely because it is being used by another process.");
+ return null;
+ }
+
+ }
+
+ public static FileStream OpenFileStream(string filename, FileMode mode = FileMode.Create)
+ {
+ try
+ {
+ FileStream fs = new FileStream(filename, mode);
+ return fs;
+ }
+ catch (IOException)
+ {
+ MessageBox.Show("File could not be opened, likely because it is being used by another process.");
+ return null;
+ }
+ }
+ }
+ static public class StringExtensions
+ {
+ static public string ReplaceInsensitive(this string str, string from, string to)
+ {
+ str = Regex.Replace(str, from, to, RegexOptions.IgnoreCase);
+ return str;
+ }
+ }
+}
diff --git a/MDF-Manager/MDF-Manager.csproj b/MDF-Manager/MDF-Manager.csproj
index f8d3db3..2ea5389 100644
--- a/MDF-Manager/MDF-Manager.csproj
+++ b/MDF-Manager/MDF-Manager.csproj
@@ -1,26 +1,38 @@
-
-
-
- WinExe
- net5.0-windows
- MDF_Manager
- true
- ValIcon.ico
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ WinExe
+ net8.0-windows10.0.22000.0
+ MDF_Manager
+ true
+ MDF-Manager_Icon.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MDF-Manager/MDF-Manager.sln b/MDF-Manager/MDF-Manager.sln
index b782f68..3f4fa7d 100644
--- a/MDF-Manager/MDF-Manager.sln
+++ b/MDF-Manager/MDF-Manager.sln
@@ -1,25 +1,25 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.32106.194
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MDF-Manager", "MDF-Manager.csproj", "{FABA9052-5795-46F0-BB37-7B28BD22F906}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {FABA9052-5795-46F0-BB37-7B28BD22F906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {FABA9052-5795-46F0-BB37-7B28BD22F906}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {FABA9052-5795-46F0-BB37-7B28BD22F906}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {FABA9052-5795-46F0-BB37-7B28BD22F906}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {70EE8172-744F-483C-93E6-40729B873BE1}
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.32106.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MDF-Manager", "MDF-Manager.csproj", "{FABA9052-5795-46F0-BB37-7B28BD22F906}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FABA9052-5795-46F0-BB37-7B28BD22F906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FABA9052-5795-46F0-BB37-7B28BD22F906}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FABA9052-5795-46F0-BB37-7B28BD22F906}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FABA9052-5795-46F0-BB37-7B28BD22F906}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {70EE8172-744F-483C-93E6-40729B873BE1}
+ EndGlobalSection
+EndGlobal
diff --git a/MDF-Manager/MDF-Manager_Icon.ico b/MDF-Manager/MDF-Manager_Icon.ico
new file mode 100644
index 0000000..b7836c4
Binary files /dev/null and b/MDF-Manager/MDF-Manager_Icon.ico differ
diff --git a/MDF-Manager/MainWindow.xaml b/MDF-Manager/MainWindow.xaml
index d6117f6..741a7ad 100644
--- a/MDF-Manager/MainWindow.xaml
+++ b/MDF-Manager/MainWindow.xaml
@@ -1,323 +1,397 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MDF-Manager/MainWindow.xaml.cs b/MDF-Manager/MainWindow.xaml.cs
index 0eb5d3f..681ef90 100644
--- a/MDF-Manager/MainWindow.xaml.cs
+++ b/MDF-Manager/MainWindow.xaml.cs
@@ -1,861 +1,870 @@
-using MDF_Manager.Classes;
-using Microsoft.Win32;
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
-using System.Text.Json;
-using System.ComponentModel;
-using System.Runtime.CompilerServices;
-
-namespace MDF_Manager
-{
- ///
- /// Interaction logic for MainWindow.xaml
- ///
- public partial class MainWindow : Window
- {
- public static string MDFFilter = "All readable files (*.mdf2)|*.mdf2.6*;*.mdf2.10*;*.mdf2.13*;*.mdf2.19*;*.mdf2.21*;*.mdf2.23*;*.mdf2.31*|" +
- "RE7 Material file (*.mdf2.6)|*.mdf2.6*|" +
- "RE2/DMC5 Material file (*.mdf2.10)|*.mdf2.10*|" +
- "RE3 Material file (*.mdf2.13)|*.mdf2.13*|" +
- "RE8/MHRiseRE8 Material file (*.mdf2.19)|*.mdf2.19*|" +
- "RE2/3/7 RT-Update Material file (*.mdf2.21)|*.mdf2.21*|" +
- "MH Rise Sunbreak Material file (*.mdf2.23)|*.mdf2.23*|" +
- "Street Fighter 6 Material file (*.mdf2.31)|*.mdf2.31*";
- public ObservableCollection MDFs { get; set; }
- public Defs defs { get; set; }
- public Library lib { get; set; }
- public Compendium compendium { get; set; }
- public bool LibraryChanged = false;
- public bool CompendiumChanged = false;
- public SolidColorBrush BackgroundColor { get; set; }
- public SolidColorBrush ForegroundColor { get; set; }
- public SolidColorBrush WindowsColor { get; set; }
- public SolidColorBrush ButtonsColor { get; set; }
- public SolidColorBrush TextColor { get; set; }
-
- bool IsDragging;
-
- public MainWindow()
- {
- lib = new Library();
- compendium = new Compendium();
- if (File.Exists("defs.json"))
- {
- string jsontxt = File.ReadAllText("defs.json");
- defs = JsonSerializer.Deserialize(jsontxt);
- }
- else
- {
- defs = new Defs();
- }
- if(defs.lastOpenLib != "")
- {
- string jsontxt = File.ReadAllText(defs.lastOpenLib);
- Library nlib = JsonSerializer.Deserialize(jsontxt);
- lib.SetEntries(nlib.entries);
- }
- if(defs.lastOpenComp != "")
- {
- string jsontxt = File.ReadAllText(defs.lastOpenComp);
- Compendium comp = JsonSerializer.Deserialize(jsontxt);
- compendium.SetEntries(comp.entries);
- }
- MDFs = new ObservableCollection();
- if(defs.lastOpenFiles.Count > 0)
- {
- for(int i = 0; i < defs.lastOpenFiles.Count; i++)
- {
- if (File.Exists(defs.lastOpenFiles[i]))
- {
- BinaryReader readFile = HelperFunctions.OpenFileR(defs.lastOpenFiles[i], Encoding.Unicode);
- if(readFile != null)
- {
- try
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(defs.lastOpenFiles[i]).Replace(".", ""));
- MDFs.Add(new MDFFile(defs.lastOpenFiles[i], readFile, type));
- readFile.Close();
- }
- catch(Exception ex)
- {
- MessageBox.Show($"Unable to open file {defs.lastOpenFiles[i]} due to an exception: {ex}");
- defs.lastOpenFiles[i] = "";
- }
- }
- }
-
- }
- }
- InitializeBrushes(defs);
- InitializeComponent();
- MaterialView.DataContext = this;
- LibraryView.DataContext = this;
- CompendiumView.DataContext = this;
- UpdateWindowBrushes();
- if (MDFs.Count > 0)
- {
- MaterialView.SelectedItem = MDFs[0];
- }
- }
-
- void InitializeBrushes(Defs def)
- {
- BackgroundColor = new SolidColorBrush(defs.background);
- ForegroundColor = new SolidColorBrush(defs.foreground);
- ButtonsColor = new SolidColorBrush(defs.buttons);
- WindowsColor = new SolidColorBrush(defs.windows);
- TextColor = new SolidColorBrush(defs.text);
- }
- void UpdateMaterials()
- {
- for (int i = 0; i < MDFs[MaterialView.SelectedIndex].Materials.Count; i++)
- {
- MDFs[MaterialView.SelectedIndex].Materials[i].UpdateMaterialIndex(i);
- }
- }
-
- bool CheckMaterialNames(int mdfIndex)
- {
- List currentNames = new List();
- for(int i = 0; i < MDFs[mdfIndex].Materials.Count; i++)
- {
- if (currentNames.Contains(MDFs[mdfIndex].Materials[i].Name))
- {
- return false;
- }
- else
- {
- currentNames.Add(MDFs[mdfIndex].Materials[i].Name);
- }
- }
- return true;
- }
-
- private void OpenMDFFile(object sender, RoutedEventArgs e)
- {
- OpenFileDialog importFile = new OpenFileDialog();
- importFile.Multiselect = false;
- importFile.Filter = MDFFilter;
- if (importFile.ShowDialog() == true)
- {
- BinaryReader readFile = HelperFunctions.OpenFileR(importFile.FileName, Encoding.Unicode);
- if(readFile != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(importFile.FileName).Replace(".", ""));
- MDFs.Add(new MDFFile(importFile.FileName, readFile, type));
- readFile.Close();
- }
-
- }
- }
- private void Save(object sender, RoutedEventArgs e)
- {
- if(MDFs.Count > 0)
- {
- if (!CheckMaterialNames(MaterialView.SelectedIndex))
- {
- MessageBox.Show("Material names cannot be identical!");
- }
- else
- {
- BinaryWriter bw = HelperFunctions.OpenFileW(MDFs[MaterialView.SelectedIndex].Header, Encoding.Unicode);
- if(bw != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(MDFs[MaterialView.SelectedIndex].Header).Replace(".", ""));
- MDFs[MaterialView.SelectedIndex].Export(bw, type);
- bw.Close();
- }
- }
- }
-
-
- }
- private void SaveAs(object sender, RoutedEventArgs e)
- {
- if(MDFs.Count > 0)
- {
- if (!CheckMaterialNames(MaterialView.SelectedIndex))
- {
- MessageBox.Show("Material names cannot be identical!");
- }
- else
- {
- SaveFileDialog saveFile = new SaveFileDialog();
- saveFile.Filter = MDFFilter;
- saveFile.FileName = System.IO.Path.GetFileName(MDFs[MaterialView.SelectedIndex].Header);
- if (saveFile.ShowDialog() == true)
- {
- BinaryWriter bw = HelperFunctions.OpenFileW(saveFile.FileName, Encoding.Unicode);
- if(bw != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(saveFile.FileName).Replace(".", ""));
- MDFs[MaterialView.SelectedIndex].Export(bw, type);
- bw.Close();
- MDFs[MaterialView.SelectedIndex].Header = saveFile.FileName;
- }
- }
- }
- }
-
-
- }
-
- private void SaveAll(object sender, RoutedEventArgs e)
- {
- //this one doesn't actually need a check, since the for loop will just immediately end if MDFs.Count = 0
- for(int i = 0; i < MDFs.Count; i++)
- {
- if (!CheckMaterialNames(i))
- {
- MessageBox.Show("Material names cannot be identical!");
- }
- else
- {
- BinaryWriter bw = HelperFunctions.OpenFileW(MDFs[i].Header, Encoding.Unicode);
- if(bw != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(MDFs[i].Header).Replace(".", ""));
- MDFs[i].Export(bw, type);
- bw.Close();
- }
-
- }
-
- }
- }
- void treeView_MouseMove(object sender, MouseEventArgs e)
- {
- if (!IsDragging && e.LeftButton == MouseButtonState.Pressed)
- {
- if(LibraryView.SelectedItem != null && LibraryView.SelectedItem is LibraryEntry && MDFs.Count > 0)
- {
- IsDragging = true;
- LibraryEntry entry = (LibraryEntry)LibraryView.SelectedItem;
- DragDrop.DoDragDrop(LibraryView, LibraryView.SelectedValue,
- DragDropEffects.Copy);
- IsDragging = false;
- }
- }
- }
- void treeView_DragOver(object sender, DragEventArgs e)
- {
- if (!e.Data.GetDataPresent(typeof(LibraryEntry)) && !e.Data.GetDataPresent(typeof(CompendiumEntry)) && !e.Data.GetDataPresent(DataFormats.FileDrop))
- {
- e.Effects = DragDropEffects.None;
- }
- }
- private void TabControl_Drop(object sender, DragEventArgs e)
- {
- //library dropping
- if (e.Data.GetDataPresent(typeof(LibraryEntry)))
- {
- if(MDFs.Count > 0)
- {
- LibraryEntry entry = (LibraryEntry)e.Data.GetData(typeof(LibraryEntry));
- BinaryReader readFile = HelperFunctions.OpenFileR(entry.MDFPath,Encoding.Unicode);
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(entry.MDFPath).Replace(".", ""));
- if(readFile != null)
- {
- MDFFile donor = new MDFFile(entry.MDFPath, readFile, type);
- readFile.Close();
- Material newMat = null;
- for (int i = 0; i < donor.Materials.Count; i++)
- {
- //the only flaw of ObvservableCollection is lack of Find(), which is fine since we can get around it
- if (donor.Materials[i].Name == entry.MaterialName)
- {
- newMat = donor.Materials[i];
- }
- }
- if (newMat != null)
- {
- MDFs[MaterialView.SelectedIndex].Materials.Add(newMat);
- UpdateMaterials();
- }
- }
-
- }
-
- }
- else if (e.Data.GetDataPresent(typeof(CompendiumEntry)))
- {
- CompendiumEntry entry = (CompendiumEntry)e.Data.GetData(typeof(CompendiumEntry));
- BinaryReader readFile = HelperFunctions.OpenFileR(entry.MDFPath, Encoding.Unicode);
- if (readFile != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(entry.MDFPath).Replace(".", ""));
- MDFs.Add(new MDFFile(entry.MDFPath, readFile, type));
- readFile.Close();
- }
- }
- else if (e.Data.GetDataPresent(DataFormats.FileDrop))
- {
- string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
- for(int i = 0; i < files.Length; i++)
- {
- if (files[i].Contains(".6") || files[i].Contains(".10") || files[i].Contains(".13") || files[i].Contains(".19") || files[i].Contains(".21") || files[i].Contains(".23"))
- {
- BinaryReader readFile = HelperFunctions.OpenFileR(files[i], Encoding.Unicode);
- if(readFile != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(files[i]).Replace(".", ""));
- MDFs.Add(new MDFFile(files[i], readFile, type));
- readFile.Close();
- }
- }
- }
-
- }
-
- }
-
- private void ChangeColor(object sender, MouseButtonEventArgs e)
- {
- Rectangle send = (Rectangle)sender;
- Float4Property prop = (Float4Property)send.DataContext;
- Float4 propVal = (Float4)prop.value;
- ColorCanvas cCanvas = new ColorCanvas();
- cCanvas.colorCanvas.SelectedColor = propVal.mColor;
- if(cCanvas.ShowDialog() == true)
- {
- Color newColor = (Color)cCanvas.colorCanvas.SelectedColor;
- Float4 nFloat4 = new Float4(newColor.ScR, newColor.ScG, newColor.ScB, newColor.ScA);
- MDFs[MaterialView.SelectedIndex].Materials[prop.indexes[0]].Properties[prop.indexes[1]].value = nFloat4;
- }
- }
-
- private void DeleteMaterial(object sender, RoutedEventArgs e)
- {
- MenuItem mi = (MenuItem)sender;
- ContextMenu cm = (ContextMenu)mi.Parent;
- ListBoxItem lbi = (ListBoxItem)cm.PlacementTarget;
- Material mat = (Material)lbi.DataContext; //what a chain to get this going
- MDFs[MaterialView.SelectedIndex].Materials.RemoveAt(mat.materialIndex);
- UpdateMaterials();
-
- }
-
- private void AddToLibrary(object sender, RoutedEventArgs e)
- {
- OpenFileDialog importFile = new OpenFileDialog();
- importFile.Multiselect = false;
- importFile.Filter = MDFFilter;
- if (importFile.ShowDialog() == true)
- {
- BinaryReader readFile = HelperFunctions.OpenFileR(importFile.FileName, Encoding.Unicode);
- if(readFile != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(importFile.FileName).Replace(".", ""));
- MDFFile ibmdf = new MDFFile(importFile.FileName, readFile, type);
- LibraryEntryHeader libHead = new LibraryEntryHeader(importFile.FileName);
- for (int i = 0; i < ibmdf.Materials.Count; i++)
- {
- LibraryEntry le = new LibraryEntry(ibmdf.Materials[i].Name, importFile.FileName);
- //le.Foreground = HelperFunctions.GetBrushFromHex("#000000");
- libHead.Items.Add(le);
- }
- lib.entries.Add(libHead);
- readFile.Close();
- LibraryChanged = true;
- }
-
- }
- }
- private void RemoveFromLibrary(object sender, RoutedEventArgs e)
- {
- if(LibraryView.SelectedItem is LibraryEntryHeader)
- {
- lib.entries.Remove((LibraryEntryHeader)LibraryView.SelectedItem);
- LibraryChanged = true;
- }
-
- }
-
- private void NewLibrary(object sender, RoutedEventArgs e)
- {
- lib = new Library();
- defs.lastOpenLib = "";
- LibraryChanged = false;
- }
- private void OpenLibrary(object sender, RoutedEventArgs e)
- {
- OpenFileDialog openFile = new OpenFileDialog();
- openFile.Filter = "MDF Material Library (*.mdflib)|*.mdflib";
- if(openFile.ShowDialog() == true)
- {
- string jsontxt = File.ReadAllText(openFile.FileName);
- Library nlib = JsonSerializer.Deserialize(jsontxt);
- lib.SetEntries(nlib.entries);
- defs.lastOpenLib = openFile.FileName;
- LibraryChanged = false;
- }
- }
- private void SaveLibrary(object sender, RoutedEventArgs e)
- {
- string jsontxt = JsonSerializer.Serialize(lib);
- File.WriteAllText(defs.lastOpenLib, jsontxt);
- LibraryChanged = false;
- }
- private void SaveLibraryAs(object sender, RoutedEventArgs e)
- {
- string jsontxt = JsonSerializer.Serialize(lib);
- SaveFileDialog saveFile = new SaveFileDialog();
- saveFile.Filter = "MDF Material Library (*.mdflib)|*.mdflib";
- if(saveFile.ShowDialog() == true)
- {
- File.WriteAllText(saveFile.FileName, jsontxt);
- defs.lastOpenLib = saveFile.FileName;
- LibraryChanged = false;
- }
-
- }
- private void DefsSetColor()
- {
- defs.background = BackgroundColor.Color;
- defs.foreground = ForegroundColor.Color;
- defs.buttons = ButtonsColor.Color;
- defs.windows = WindowsColor.Color;
- defs.text = TextColor.Color;
- }
- private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
- {
- DefsSetColor();
- if (LibraryChanged)
- {
- if(MessageBox.Show("Save changes to the library?","",MessageBoxButton.YesNo) == MessageBoxResult.Yes)
- {
- if(defs.lastOpenLib == "")
- {
- SaveLibraryAs(sender, new RoutedEventArgs());
- }
- else
- {
- SaveLibrary(sender, new RoutedEventArgs());
- }
- }
- }
- if (CompendiumChanged)
- {
- if (MessageBox.Show("Save changes to the compendium?", "", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
- {
- SaveCompendium(sender, new RoutedEventArgs());
- }
- }
- defs.lastOpenFiles.Clear();
- for(int i = 0; i < MDFs.Count; i++)
- {
- defs.lastOpenFiles.Add(MDFs[i].FileName);
- }
-
- JsonSerializerOptions options = new JsonSerializerOptions();
- options.WriteIndented = true;
- string jsontxt = JsonSerializer.Serialize(defs,options);
- File.WriteAllText("defs.json",jsontxt);
- }
-
- private void MoveMatUp(object sender, RoutedEventArgs e)
- {
- Button send = sender as Button;
- ListBox senderBox = send.DataContext as ListBox;
- //this approach is weird but I'm surprised it works
- if (senderBox != null)
- {
- Material senderMat = (Material)senderBox.SelectedItem;
- if(senderMat != null)
- {
- int oldIndex = senderMat.materialIndex;
- if (oldIndex > 0)
- {
- //obviously cannot go past first index
- HelperFunctions.Swap(MDFs[MaterialView.SelectedIndex].Materials, oldIndex - 1, oldIndex);
- senderBox.SelectedIndex = oldIndex - 1;
- send.DataContext = senderBox;
- }
-
- }
-
- }
- UpdateMaterials();
- }
- private void MoveMatDown(object sender, RoutedEventArgs e)
- {
- Button send = sender as Button;
- ListBox senderBox = send.DataContext as ListBox;
- //this approach is weird but I'm surprised it works
- if(senderBox != null)
- {
- Material senderMat = (Material)senderBox.SelectedItem;
- if(senderMat != null)
- {
- int oldIndex = senderMat.materialIndex;
- if (oldIndex < MDFs[MaterialView.SelectedIndex].Materials.Count - 1)
- {
- //obviously cannot go past last index
- HelperFunctions.Swap(MDFs[MaterialView.SelectedIndex].Materials, oldIndex + 1, oldIndex);
- senderBox.SelectedIndex = oldIndex + 1;
- send.DataContext = senderBox;
- }
-
- }
-
- }
- UpdateMaterials();
-
- }
- public void UpdateWindowBrushes()
- {
- Resources["BackgroundColor"] = BackgroundColor;
- Resources["ForegroundColor"] = ForegroundColor;
- Resources["WindowsColor"] = WindowsColor;
- Resources["ButtonColor"] = ButtonsColor;
- Resources["TextColor"] = TextColor;
- }
-
- private void ThemeOpen(object sender, RoutedEventArgs e)
- {
- ThemeManager themeManager = new ThemeManager();
- themeManager.BackgroundColor = BackgroundColor;
- themeManager.ForegroundColor = ForegroundColor;
- themeManager.ButtonColor = ButtonsColor;
- themeManager.WindowsColor = WindowsColor;
- themeManager.TextColor = TextColor;
- if(themeManager.ShowDialog() == true)
- {
- BackgroundColor = themeManager.BackgroundColor;
- ForegroundColor = themeManager.ForegroundColor;
- WindowsColor = themeManager.WindowsColor;
- ButtonsColor = themeManager.ButtonColor;
- TextColor = themeManager.TextColor;
- UpdateWindowBrushes();
- }
- }
- private void btnDelete_Click(object sender, RoutedEventArgs e)
- {
- string tabName = (sender as Button).CommandParameter.ToString();
-
- var item = MaterialView.Items.Cast().Where(i => i.Header.Equals(tabName)).SingleOrDefault();
-
- MDFFile tab = item as MDFFile;
-
- if (tab != null)
- {
- // get selected tab
- MDFFile selectedTab = MaterialView.SelectedItem as MDFFile;
-
- if (MessageBox.Show(string.Format("Would you like to save before closing?", tab.Header.ToString()),
- "Remove Tab", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
- {
- BinaryWriter bw = HelperFunctions.OpenFileW(tab.Header, Encoding.Unicode);
- if(bw != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(tab.Header).Replace(".", ""));
- tab.Export(bw, type);
- bw.Close();
- }
-
- }
-
-
- MDFs.Remove(tab);
-
- // select previously selected tab. if that is removed then select first tab
- if ((selectedTab == null || selectedTab.Equals(tab)) && (MDFs.Count > 0))
- {
- selectedTab = MDFs[0];
- }
- MaterialView.SelectedItem = selectedTab;
- }
- }
-
- private void ExtendCompendium(OpenFileDialog dialog)
- {
- //set some error info up here for reference if crash
- string lastMDF = " ";
- MDFTypes lastType = MDFTypes.RE2DMC5;
- if (dialog.ShowDialog() == true)
- {
- try
- {
- string fullPath = dialog.FileName;
- string searchPath = System.IO.Path.GetDirectoryName(fullPath);
- EnumerationOptions enops = new EnumerationOptions();
- enops.RecurseSubdirectories = true;
- string[] mdfs = System.IO.Directory.GetFiles(searchPath, "*.mdf2.*", enops);//brilliant
- foreach (string mdf in mdfs)
- {
- //gonna abuse the fact everything is by reference
- string sType = System.IO.Path.GetExtension(mdf.ReplaceInsensitive(".stm", "").ReplaceInsensitive(".x64", "")).Replace(".","");
- MDFTypes type = (MDFTypes)Convert.ToInt32(sType);
- lastMDF = mdf;
- lastType = type;
- CompendiumTopLevel parent = null;
- switch (type)
- {
- case MDFTypes.RE7:
- parent = compendium.RE7;
- break;
- case MDFTypes.RE2DMC5:
- parent = compendium.RE2DMC5;
- break;
- case MDFTypes.RE3:
- parent = compendium.RE3;
- break;
- case MDFTypes.MHRiseRE8:
- parent = compendium.MHRiseRE8;
- break;
- case MDFTypes.RERT:
- parent = compendium.RERT;
- break;
- case MDFTypes.Sunbreak:
- parent = compendium.Sunbreak;
- break;
- default:
- break;
- }
- if (parent != null)
- {
- BinaryReader br = HelperFunctions.OpenFileR(mdf, Encoding.Unicode);
- if (br != null)
- {
- MDFFile file = new MDFFile(mdf, br, type);
- foreach (Material mat in file.Materials)
- {
- CompendiumEntryHeader mParent = null;
- mParent = parent.FindItem(x => x.MMTRName == System.IO.Path.GetFileNameWithoutExtension(mat.MasterMaterial));
- if (mParent == null)
- {
- mParent = new CompendiumEntryHeader(System.IO.Path.GetFileNameWithoutExtension(mat.MasterMaterial));
- parent.AddChild(mParent);
- }
- int check = mParent.FindEntry(mdf);
- if (check == -1)
- {
- CompendiumEntry ce = new CompendiumEntry(mdf);
- mParent.Items.Add(ce);
- }
- }
- }
- }
- }
- CompendiumChanged = true;
- compendium.Sort();
- }
- catch(Exception ex)
- {
- MessageBox.Show($"An error occurred during reading compendium entries:{ex}\n\n" +
- $"Diagnostic Information: MDF:{lastMDF} Version:{lastType}");
- }
- }
- }
- private void RebaseCompendium(object sender, RoutedEventArgs e)
- {
- compendium.ClearList();
- OpenFileDialog dialog = new OpenFileDialog();
- dialog.CheckFileExists = false;
- dialog.FileName = "Rebase Compendium here";
- ExtendCompendium(dialog);
- }
- private void ExpandCompendium(object sender, RoutedEventArgs e)
- {
- OpenFileDialog dialog = new OpenFileDialog();
- dialog.CheckFileExists = false;
- dialog.FileName = "Expand Compendium here";
- ExtendCompendium(dialog);
- }
- private void OpenCompendium(object sender, RoutedEventArgs e)
- {
- OpenFileDialog openFile = new OpenFileDialog();
- openFile.Filter = "MDF Material Compendium (*.mdfcomp)|*.mdfcomp";
- if (openFile.ShowDialog() == true)
- {
- string jsontxt = File.ReadAllText(openFile.FileName);
- Compendium nlib = JsonSerializer.Deserialize(jsontxt);
- compendium.SetEntries(nlib.entries);
- defs.lastOpenComp = openFile.FileName;
- CompendiumChanged = false;
- }
- }
- private void SaveCompendium(object sender, RoutedEventArgs e)
- {
- if (defs.lastOpenComp == "")
- {
- SaveCompendiumAs(sender, e);
- }
- string jsontxt = JsonSerializer.Serialize(compendium);
- File.WriteAllText(defs.lastOpenComp, jsontxt);
- CompendiumChanged = false;
- }
- private void SaveCompendiumAs(object sender, RoutedEventArgs e)
- {
- string jsontxt = JsonSerializer.Serialize(compendium);
- SaveFileDialog saveFile = new SaveFileDialog();
- saveFile.Filter = "MDF Material Compendium (*.mdfcomp)|*.mdfcomp";
- if (saveFile.ShowDialog() == true)
- {
- File.WriteAllText(saveFile.FileName, jsontxt);
- defs.lastOpenComp = saveFile.FileName;
- CompendiumChanged = false;
- }
-
- }
-
- private void CompendiumView_MouseMove(object sender, MouseEventArgs e)
- {
- if (!IsDragging && e.LeftButton == MouseButtonState.Pressed)
- {
- if (CompendiumView.SelectedItem != null && CompendiumView.SelectedItem is CompendiumEntry)
- {
- IsDragging = true;
- CompendiumEntry entry = (CompendiumEntry)CompendiumView.SelectedItem;
- DragDrop.DoDragDrop(CompendiumView, CompendiumView.SelectedValue,
- DragDropEffects.Copy);
- IsDragging = false;
- }
- }
- }
-
- private void LibraryView_Drop(object sender, DragEventArgs e)
- {
- if (e.Data.GetDataPresent(typeof(CompendiumEntry)))
- {
- CompendiumEntry entry = (CompendiumEntry)e.Data.GetData(typeof(CompendiumEntry));
- BinaryReader readFile = HelperFunctions.OpenFileR(entry.MDFPath, Encoding.Unicode);
- if (readFile != null)
- {
- MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(entry.MDFPath).Replace(".", ""));
- MDFFile ibmdf = new MDFFile(entry.MDFPath, readFile, type);
- LibraryEntryHeader libHead = new LibraryEntryHeader(entry.MDFPath);
- for (int i = 0; i < ibmdf.Materials.Count; i++)
- {
- LibraryEntry le = new LibraryEntry(ibmdf.Materials[i].Name, entry.MDFPath);
- //le.Foreground = HelperFunctions.GetBrushFromHex("#000000");
- libHead.Items.Add(le);
- }
- lib.entries.Add(libHead);
- readFile.Close();
- LibraryChanged = true;
- }
- }
- }
-
- private void LibraryView_DragOver(object sender, DragEventArgs e)
- {
- if (!e.Data.GetDataPresent(typeof(CompendiumEntry)))
- {
- e.Effects = DragDropEffects.None;
- }
- }
-
- private void MaterialView_SelectionChanged(object sender, SelectionChangedEventArgs e)
- {
-
- }
-
- private void BatchConvert(object sender, RoutedEventArgs e)
- {
- BatchConverter batch = new BatchConverter();
- batch.Show();
- }
- }
- public class PropertySelect : DataTemplateSelector
- {
- public DataTemplate FloatTemplate { get; set; }
- public DataTemplate Float4Template { get; set; }
- public override DataTemplate SelectTemplate(object item, DependencyObject container)
- {
- if (item != null)
- {
- if (item is FloatProperty)
- {
- return FloatTemplate;
- }
- else if (item is Float4Property)
- {
- return Float4Template;
- }
- else
- {
- return null;
- }
- }
- else
- {
- return null;
- }
- }
- }
- public class LibSelect : DataTemplateSelector
- {
- public DataTemplate LibEntry { get; set; }
- public DataTemplate LibEntryHead { get; set; }
- public override DataTemplate SelectTemplate(object item, DependencyObject container)
- {
- if (item != null)
- {
- if (item is LibraryEntry)
- {
- return LibEntry;
- }
- else if (item is LibraryEntryHeader)
- {
- return LibEntryHead;
- }
- else
- {
- return null;
- }
- }
- else
- {
- return null;
- }
- }
- }
- public class CompSelect : DataTemplateSelector
- {
- public DataTemplate CompEntry { get; set; }
- public DataTemplate CompEntryHead { get; set; }
- public DataTemplate CompTopLevel { get; set; }
- public override DataTemplate SelectTemplate(object item, DependencyObject container)
- {
- if (item != null)
- {
- if (item is CompendiumEntry)
- {
- return CompEntry;
- }
- else if (item is CompendiumEntryHeader)
- {
- return CompEntryHead;
- }
- else if(item is CompendiumTopLevel)
- {
- return CompTopLevel;
- }
- else
- {
- return null;
- }
- }
- else
- {
- return null;
- }
- }
- }
-
-}
+using MDF_Manager.Classes;
+using Microsoft.Win32;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Text.Json;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace MDF_Manager
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ public static string MDFFilter = "All readable files (*.mdf2)|*.mdf2.6*;*.mdf2.10*;*.mdf2.13*;*.mdf2.19*;*.mdf2.21*;*.mdf2.23*;*.mdf2.31*;*.mdf2.32*;*.mdf2.40*;*.mdf2.45*|" +
+ "RE7 Material file (*.mdf2.6)|*.mdf2.6*|" +
+ "RE2/DMC5 Material file (*.mdf2.10)|*.mdf2.10*|" +
+ "RE3 Material file (*.mdf2.13)|*.mdf2.13*|" +
+ "RE8/MHRiseRE8 Material file (*.mdf2.19)|*.mdf2.19*|" +
+ "RE2/3/7 RT-Update Material file (*.mdf2.21)|*.mdf2.21*|" +
+ "MH Rise Sunbreak Material file (*.mdf2.23)|*.mdf2.23*|" +
+ "Street Fighter 6 Material file (*.mdf2.31)|*.mdf2.31*|" +
+ "RE4 Material file (*.mdf2.32)|*.mdf2.32*|" +
+ "Dragon's Dogma 2 Material file (*.mdf2.40)|*.mdf2.40*|" +
+ "Monster Hunter Wilds Material file (*.mdf2.45)|*.mdf2.45*";
+ public ObservableCollection MDFs { get; set; }
+ public Defs defs { get; set; }
+ public Library lib { get; set; }
+ public Compendium compendium { get; set; }
+ public bool LibraryChanged = false;
+ public bool CompendiumChanged = false;
+ public SolidColorBrush BackgroundColor { get; set; }
+ public SolidColorBrush ForegroundColor { get; set; }
+ public SolidColorBrush WindowsColor { get; set; }
+ public SolidColorBrush ButtonsColor { get; set; }
+ public SolidColorBrush TextColor { get; set; }
+
+ bool IsDragging;
+
+ public MainWindow()
+ {
+ lib = new Library();
+ compendium = new Compendium();
+ if (File.Exists("defs.json"))
+ {
+ string jsontxt = File.ReadAllText("defs.json");
+ defs = JsonSerializer.Deserialize(jsontxt);
+ }
+ else
+ {
+ defs = new Defs();
+ }
+ if(defs.lastOpenLib != "")
+ {
+ string jsontxt = File.ReadAllText(defs.lastOpenLib);
+ Library nlib = JsonSerializer.Deserialize(jsontxt);
+ lib.SetEntries(nlib.entries);
+ }
+ if(defs.lastOpenComp != "")
+ {
+ string jsontxt = File.ReadAllText(defs.lastOpenComp);
+ Compendium comp = JsonSerializer.Deserialize(jsontxt);
+ compendium.SetEntries(comp.entries);
+ }
+ MDFs = new ObservableCollection();
+ if(defs.lastOpenFiles.Count > 0)
+ {
+ for(int i = 0; i < defs.lastOpenFiles.Count; i++)
+ {
+ if (File.Exists(defs.lastOpenFiles[i]))
+ {
+ BinaryReader readFile = HelperFunctions.OpenFileR(defs.lastOpenFiles[i], Encoding.Unicode);
+ if(readFile != null)
+ {
+ try
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(defs.lastOpenFiles[i]).Replace(".", ""));
+ MDFs.Add(new MDFFile(defs.lastOpenFiles[i], readFile, type));
+ readFile.Close();
+ }
+ catch(Exception ex)
+ {
+ MessageBox.Show($"Unable to open file {defs.lastOpenFiles[i]} due to an exception: {ex}");
+ defs.lastOpenFiles[i] = "";
+ }
+ }
+ }
+
+ }
+ }
+ InitializeBrushes(defs);
+ InitializeComponent();
+ MaterialView.DataContext = this;
+ LibraryView.DataContext = this;
+ CompendiumView.DataContext = this;
+ UpdateWindowBrushes();
+ if (MDFs.Count > 0)
+ {
+ MaterialView.SelectedItem = MDFs[0];
+ }
+ }
+
+ void InitializeBrushes(Defs def)
+ {
+ BackgroundColor = new SolidColorBrush(defs.background);
+ ForegroundColor = new SolidColorBrush(defs.foreground);
+ ButtonsColor = new SolidColorBrush(defs.buttons);
+ WindowsColor = new SolidColorBrush(defs.windows);
+ TextColor = new SolidColorBrush(defs.text);
+ }
+ void UpdateMaterials()
+ {
+ for (int i = 0; i < MDFs[MaterialView.SelectedIndex].Materials.Count; i++)
+ {
+ MDFs[MaterialView.SelectedIndex].Materials[i].UpdateMaterialIndex(i);
+ }
+ }
+
+ bool CheckMaterialNames(int mdfIndex)
+ {
+ List currentNames = new List();
+ for(int i = 0; i < MDFs[mdfIndex].Materials.Count; i++)
+ {
+ if (currentNames.Contains(MDFs[mdfIndex].Materials[i].Name))
+ {
+ return false;
+ }
+ else
+ {
+ currentNames.Add(MDFs[mdfIndex].Materials[i].Name);
+ }
+ }
+ return true;
+ }
+
+ private void OpenMDFFile(object sender, RoutedEventArgs e)
+ {
+ OpenFileDialog importFile = new OpenFileDialog();
+ importFile.Multiselect = false;
+ importFile.Filter = MDFFilter;
+ if (importFile.ShowDialog() == true)
+ {
+ BinaryReader readFile = HelperFunctions.OpenFileR(importFile.FileName, Encoding.Unicode);
+ if(readFile != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(importFile.FileName).Replace(".", ""));
+ MDFs.Add(new MDFFile(importFile.FileName, readFile, type));
+ readFile.Close();
+ }
+
+ }
+ }
+ private void Save(object sender, RoutedEventArgs e)
+ {
+ if(MDFs.Count > 0)
+ {
+ if (!CheckMaterialNames(MaterialView.SelectedIndex))
+ {
+ MessageBox.Show("Material names cannot be identical!");
+ }
+ else
+ {
+ BinaryWriter bw = HelperFunctions.OpenFileW(MDFs[MaterialView.SelectedIndex].Header, Encoding.Unicode);
+ if(bw != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(MDFs[MaterialView.SelectedIndex].Header).Replace(".", ""));
+ MDFs[MaterialView.SelectedIndex].Export(bw, type);
+ bw.Close();
+ }
+ }
+ }
+
+
+ }
+ private void SaveAs(object sender, RoutedEventArgs e)
+ {
+ if(MDFs.Count > 0)
+ {
+ if (!CheckMaterialNames(MaterialView.SelectedIndex))
+ {
+ MessageBox.Show("Material names cannot be identical!");
+ }
+ else
+ {
+ SaveFileDialog saveFile = new SaveFileDialog();
+ saveFile.Filter = MDFFilter;
+ saveFile.FileName = System.IO.Path.GetFileName(MDFs[MaterialView.SelectedIndex].Header);
+ if (saveFile.ShowDialog() == true)
+ {
+ BinaryWriter bw = HelperFunctions.OpenFileW(saveFile.FileName, Encoding.Unicode);
+ if(bw != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(saveFile.FileName).Replace(".", ""));
+ MDFs[MaterialView.SelectedIndex].Export(bw, type);
+ bw.Close();
+ MDFs[MaterialView.SelectedIndex].Header = saveFile.FileName;
+ }
+ }
+ }
+ }
+
+
+ }
+
+ private void SaveAll(object sender, RoutedEventArgs e)
+ {
+ //this one doesn't actually need a check, since the for loop will just immediately end if MDFs.Count = 0
+ for(int i = 0; i < MDFs.Count; i++)
+ {
+ if (!CheckMaterialNames(i))
+ {
+ MessageBox.Show("Material names cannot be identical!");
+ }
+ else
+ {
+ BinaryWriter bw = HelperFunctions.OpenFileW(MDFs[i].Header, Encoding.Unicode);
+ if(bw != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(MDFs[i].Header).Replace(".", ""));
+ MDFs[i].Export(bw, type);
+ bw.Close();
+ }
+
+ }
+
+ }
+ }
+ void treeView_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (!IsDragging && e.LeftButton == MouseButtonState.Pressed)
+ {
+ if(LibraryView.SelectedItem != null && LibraryView.SelectedItem is LibraryEntry && MDFs.Count > 0)
+ {
+ IsDragging = true;
+ LibraryEntry entry = (LibraryEntry)LibraryView.SelectedItem;
+ DragDrop.DoDragDrop(LibraryView, LibraryView.SelectedValue,
+ DragDropEffects.Copy);
+ IsDragging = false;
+ }
+ }
+ }
+ void treeView_DragOver(object sender, DragEventArgs e)
+ {
+ if (!e.Data.GetDataPresent(typeof(LibraryEntry)) && !e.Data.GetDataPresent(typeof(CompendiumEntry)) && !e.Data.GetDataPresent(DataFormats.FileDrop))
+ {
+ e.Effects = DragDropEffects.None;
+ }
+ }
+ private void TabControl_Drop(object sender, DragEventArgs e)
+ {
+ //library dropping
+ if (e.Data.GetDataPresent(typeof(LibraryEntry)))
+ {
+ if(MDFs.Count > 0)
+ {
+ LibraryEntry entry = (LibraryEntry)e.Data.GetData(typeof(LibraryEntry));
+ BinaryReader readFile = HelperFunctions.OpenFileR(entry.MDFPath,Encoding.Unicode);
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(entry.MDFPath).Replace(".", ""));
+ if(readFile != null)
+ {
+ MDFFile donor = new MDFFile(entry.MDFPath, readFile, type);
+ readFile.Close();
+ Material newMat = null;
+ for (int i = 0; i < donor.Materials.Count; i++)
+ {
+ //the only flaw of ObvservableCollection is lack of Find(), which is fine since we can get around it
+ if (donor.Materials[i].Name == entry.MaterialName)
+ {
+ newMat = donor.Materials[i];
+ }
+ }
+ if (newMat != null)
+ {
+ MDFs[MaterialView.SelectedIndex].Materials.Add(newMat);
+ UpdateMaterials();
+ }
+ }
+
+ }
+
+ }
+ else if (e.Data.GetDataPresent(typeof(CompendiumEntry)))
+ {
+ CompendiumEntry entry = (CompendiumEntry)e.Data.GetData(typeof(CompendiumEntry));
+ BinaryReader readFile = HelperFunctions.OpenFileR(entry.MDFPath, Encoding.Unicode);
+ if (readFile != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(entry.MDFPath).Replace(".", ""));
+ MDFs.Add(new MDFFile(entry.MDFPath, readFile, type));
+ readFile.Close();
+ }
+ }
+ else if (e.Data.GetDataPresent(DataFormats.FileDrop))
+ {
+ string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
+ for(int i = 0; i < files.Length; i++)
+ {
+ if (files[i].Contains(".6") || files[i].Contains(".10") || files[i].Contains(".13") || files[i].Contains(".19") || files[i].Contains(".21") || files[i].Contains(".23") || files[i].Contains(".31") || files[i].Contains(".32") || files[i].Contains(".40") || files[i].Contains(".45"))
+ {
+ BinaryReader readFile = HelperFunctions.OpenFileR(files[i], Encoding.Unicode);
+ if(readFile != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(files[i]).Replace(".", ""));
+ MDFs.Add(new MDFFile(files[i], readFile, type));
+ readFile.Close();
+ }
+ }
+ }
+
+ }
+
+ }
+
+ private void ChangeColor(object sender, MouseButtonEventArgs e)
+ {
+ Rectangle send = (Rectangle)sender;
+ Float4Property prop = (Float4Property)send.DataContext;
+ Float4 propVal = (Float4)prop.value;
+ ColorCanvas cCanvas = new ColorCanvas();
+ cCanvas.colorCanvas.SelectedColor = propVal.mColor;
+ if(cCanvas.ShowDialog() == true)
+ {
+ Color newColor = (Color)cCanvas.colorCanvas.SelectedColor;
+ Float4 nFloat4 = new Float4(newColor.ScR, newColor.ScG, newColor.ScB, newColor.ScA);
+ MDFs[MaterialView.SelectedIndex].Materials[prop.indexes[0]].Properties[prop.indexes[1]].value = nFloat4;
+ }
+ }
+
+ private void DeleteMaterial(object sender, RoutedEventArgs e)
+ {
+ MenuItem mi = (MenuItem)sender;
+ ContextMenu cm = (ContextMenu)mi.Parent;
+ ListBoxItem lbi = (ListBoxItem)cm.PlacementTarget;
+ Material mat = (Material)lbi.DataContext; //what a chain to get this going
+ MDFs[MaterialView.SelectedIndex].Materials.RemoveAt(mat.materialIndex);
+ UpdateMaterials();
+
+ }
+
+ private void AddToLibrary(object sender, RoutedEventArgs e)
+ {
+ OpenFileDialog importFile = new OpenFileDialog();
+ importFile.Multiselect = false;
+ importFile.Filter = MDFFilter;
+ if (importFile.ShowDialog() == true)
+ {
+ BinaryReader readFile = HelperFunctions.OpenFileR(importFile.FileName, Encoding.Unicode);
+ if(readFile != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(importFile.FileName).Replace(".", ""));
+ MDFFile ibmdf = new MDFFile(importFile.FileName, readFile, type);
+ LibraryEntryHeader libHead = new LibraryEntryHeader(importFile.FileName);
+ for (int i = 0; i < ibmdf.Materials.Count; i++)
+ {
+ LibraryEntry le = new LibraryEntry(ibmdf.Materials[i].Name, importFile.FileName);
+ //le.Foreground = HelperFunctions.GetBrushFromHex("#000000");
+ libHead.Items.Add(le);
+ }
+ lib.entries.Add(libHead);
+ readFile.Close();
+ LibraryChanged = true;
+ }
+
+ }
+ }
+ private void RemoveFromLibrary(object sender, RoutedEventArgs e)
+ {
+ if(LibraryView.SelectedItem is LibraryEntryHeader)
+ {
+ lib.entries.Remove((LibraryEntryHeader)LibraryView.SelectedItem);
+ LibraryChanged = true;
+ }
+
+ }
+
+ private void NewLibrary(object sender, RoutedEventArgs e)
+ {
+ lib = new Library();
+ defs.lastOpenLib = "";
+ LibraryChanged = false;
+ }
+ private void OpenLibrary(object sender, RoutedEventArgs e)
+ {
+ OpenFileDialog openFile = new OpenFileDialog();
+ openFile.Filter = "MDF Material Library (*.mdflib)|*.mdflib";
+ if(openFile.ShowDialog() == true)
+ {
+ string jsontxt = File.ReadAllText(openFile.FileName);
+ Library nlib = JsonSerializer.Deserialize(jsontxt);
+ lib.SetEntries(nlib.entries);
+ defs.lastOpenLib = openFile.FileName;
+ LibraryChanged = false;
+ }
+ }
+ private void SaveLibrary(object sender, RoutedEventArgs e)
+ {
+ string jsontxt = JsonSerializer.Serialize(lib);
+ File.WriteAllText(defs.lastOpenLib, jsontxt);
+ LibraryChanged = false;
+ }
+ private void SaveLibraryAs(object sender, RoutedEventArgs e)
+ {
+ string jsontxt = JsonSerializer.Serialize(lib);
+ SaveFileDialog saveFile = new SaveFileDialog();
+ saveFile.Filter = "MDF Material Library (*.mdflib)|*.mdflib";
+ if(saveFile.ShowDialog() == true)
+ {
+ File.WriteAllText(saveFile.FileName, jsontxt);
+ defs.lastOpenLib = saveFile.FileName;
+ LibraryChanged = false;
+ }
+
+ }
+ private void DefsSetColor()
+ {
+ defs.background = BackgroundColor.Color;
+ defs.foreground = ForegroundColor.Color;
+ defs.buttons = ButtonsColor.Color;
+ defs.windows = WindowsColor.Color;
+ defs.text = TextColor.Color;
+ }
+ private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+ {
+ DefsSetColor();
+ if (LibraryChanged)
+ {
+ if(MessageBox.Show("Save changes to the library?","",MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ {
+ if(defs.lastOpenLib == "")
+ {
+ SaveLibraryAs(sender, new RoutedEventArgs());
+ }
+ else
+ {
+ SaveLibrary(sender, new RoutedEventArgs());
+ }
+ }
+ }
+ if (CompendiumChanged)
+ {
+ if (MessageBox.Show("Save changes to the compendium?", "", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ {
+ SaveCompendium(sender, new RoutedEventArgs());
+ }
+ }
+ defs.lastOpenFiles.Clear();
+ for(int i = 0; i < MDFs.Count; i++)
+ {
+ defs.lastOpenFiles.Add(MDFs[i].FileName);
+ }
+
+ JsonSerializerOptions options = new JsonSerializerOptions();
+ options.WriteIndented = true;
+ string jsontxt = JsonSerializer.Serialize(defs,options);
+ File.WriteAllText("defs.json",jsontxt);
+ }
+
+ private void MoveMatUp(object sender, RoutedEventArgs e)
+ {
+ Button send = sender as Button;
+ ListBox senderBox = send.DataContext as ListBox;
+ //this approach is weird but I'm surprised it works
+ if (senderBox != null)
+ {
+ Material senderMat = (Material)senderBox.SelectedItem;
+ if(senderMat != null)
+ {
+ int oldIndex = senderMat.materialIndex;
+ if (oldIndex > 0)
+ {
+ //obviously cannot go past first index
+ HelperFunctions.Swap(MDFs[MaterialView.SelectedIndex].Materials, oldIndex - 1, oldIndex);
+ senderBox.SelectedIndex = oldIndex - 1;
+ send.DataContext = senderBox;
+ }
+
+ }
+
+ }
+ UpdateMaterials();
+ }
+ private void MoveMatDown(object sender, RoutedEventArgs e)
+ {
+ Button send = sender as Button;
+ ListBox senderBox = send.DataContext as ListBox;
+ //this approach is weird but I'm surprised it works
+ if(senderBox != null)
+ {
+ Material senderMat = (Material)senderBox.SelectedItem;
+ if(senderMat != null)
+ {
+ int oldIndex = senderMat.materialIndex;
+ if (oldIndex < MDFs[MaterialView.SelectedIndex].Materials.Count - 1)
+ {
+ //obviously cannot go past last index
+ HelperFunctions.Swap(MDFs[MaterialView.SelectedIndex].Materials, oldIndex + 1, oldIndex);
+ senderBox.SelectedIndex = oldIndex + 1;
+ send.DataContext = senderBox;
+ }
+
+ }
+
+ }
+ UpdateMaterials();
+
+ }
+ public void UpdateWindowBrushes()
+ {
+ Resources["BackgroundColor"] = BackgroundColor;
+ Resources["ForegroundColor"] = ForegroundColor;
+ Resources["WindowsColor"] = WindowsColor;
+ Resources["ButtonColor"] = ButtonsColor;
+ Resources["TextColor"] = TextColor;
+ }
+
+ private void ThemeOpen(object sender, RoutedEventArgs e)
+ {
+ ThemeManager themeManager = new ThemeManager();
+ themeManager.BackgroundColor = BackgroundColor;
+ themeManager.ForegroundColor = ForegroundColor;
+ themeManager.ButtonColor = ButtonsColor;
+ themeManager.WindowsColor = WindowsColor;
+ themeManager.TextColor = TextColor;
+ if(themeManager.ShowDialog() == true)
+ {
+ BackgroundColor = themeManager.BackgroundColor;
+ ForegroundColor = themeManager.ForegroundColor;
+ WindowsColor = themeManager.WindowsColor;
+ ButtonsColor = themeManager.ButtonColor;
+ TextColor = themeManager.TextColor;
+ UpdateWindowBrushes();
+ }
+ }
+ private void btnDelete_Click(object sender, RoutedEventArgs e)
+ {
+ string tabName = (sender as Button).CommandParameter.ToString();
+
+ var item = MaterialView.Items.Cast().Where(i => i.Header.Equals(tabName)).SingleOrDefault();
+
+ MDFFile tab = item as MDFFile;
+
+ if (tab != null)
+ {
+ // get selected tab
+ MDFFile selectedTab = MaterialView.SelectedItem as MDFFile;
+
+ if (MessageBox.Show(string.Format("Would you like to save before closing?", tab.Header.ToString()),
+ "Remove Tab", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
+ {
+ BinaryWriter bw = HelperFunctions.OpenFileW(tab.Header, Encoding.Unicode);
+ if(bw != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(tab.Header).Replace(".", ""));
+ tab.Export(bw, type);
+ bw.Close();
+ }
+
+ }
+
+
+ MDFs.Remove(tab);
+
+ // select previously selected tab. if that is removed then select first tab
+ if ((selectedTab == null || selectedTab.Equals(tab)) && (MDFs.Count > 0))
+ {
+ selectedTab = MDFs[0];
+ }
+ MaterialView.SelectedItem = selectedTab;
+ }
+ }
+
+ private void ExtendCompendium(OpenFileDialog dialog)
+ {
+ //set some error info up here for reference if crash
+ string lastMDF = " ";
+ MDFTypes lastType = MDFTypes.RE2DMC5;
+ if (dialog.ShowDialog() == true)
+ {
+ try
+ {
+ string fullPath = dialog.FileName;
+ string searchPath = System.IO.Path.GetDirectoryName(fullPath);
+ EnumerationOptions enops = new EnumerationOptions();
+ enops.RecurseSubdirectories = true;
+ string[] mdfs = System.IO.Directory.GetFiles(searchPath, "*.mdf2.*", enops);//brilliant
+ foreach (string mdf in mdfs)
+ {
+ //gonna abuse the fact everything is by reference
+ string sType = System.IO.Path.GetExtension(mdf.ReplaceInsensitive(".stm", "").ReplaceInsensitive(".x64", "")).Replace(".","");
+ MDFTypes type = (MDFTypes)Convert.ToInt32(sType);
+ lastMDF = mdf;
+ lastType = type;
+ CompendiumTopLevel parent = null;
+ switch (type)
+ {
+ case MDFTypes.RE7:
+ parent = compendium.RE7;
+ break;
+ case MDFTypes.RE2DMC5:
+ parent = compendium.RE2DMC5;
+ break;
+ case MDFTypes.RE3:
+ parent = compendium.RE3;
+ break;
+ case MDFTypes.MHRiseRE8:
+ parent = compendium.MHRiseRE8;
+ break;
+ case MDFTypes.RERT:
+ parent = compendium.RERT;
+ break;
+ case MDFTypes.Sunbreak:
+ parent = compendium.Sunbreak;
+ break;
+ case MDFTypes.DD2:
+ parent = compendium.DD2;
+ break;
+ case MDFTypes.MHWilds:
+ parent = compendium.MHWilds;
+ break;
+ default:
+ break;
+ }
+ if (parent != null)
+ {
+ BinaryReader br = HelperFunctions.OpenFileR(mdf, Encoding.Unicode);
+ if (br != null)
+ {
+ MDFFile file = new MDFFile(mdf, br, type);
+ foreach (Material mat in file.Materials)
+ {
+ CompendiumEntryHeader mParent = null;
+ mParent = parent.FindItem(x => x.MMTRName == System.IO.Path.GetFileNameWithoutExtension(mat.MasterMaterial));
+ if (mParent == null)
+ {
+ mParent = new CompendiumEntryHeader(System.IO.Path.GetFileNameWithoutExtension(mat.MasterMaterial));
+ parent.AddChild(mParent);
+ }
+ int check = mParent.FindEntry(mdf);
+ if (check == -1)
+ {
+ CompendiumEntry ce = new CompendiumEntry(mdf);
+ mParent.Items.Add(ce);
+ }
+ }
+ }
+ }
+ }
+ CompendiumChanged = true;
+ compendium.Sort();
+ }
+ catch(Exception ex)
+ {
+ MessageBox.Show($"An error occurred during reading compendium entries:{ex}\n\n" +
+ $"Diagnostic Information: MDF:{lastMDF} Version:{lastType}");
+ }
+ }
+ }
+ private void RebaseCompendium(object sender, RoutedEventArgs e)
+ {
+ compendium.ClearList();
+ OpenFileDialog dialog = new OpenFileDialog();
+ dialog.CheckFileExists = false;
+ dialog.FileName = "Rebase Compendium here";
+ ExtendCompendium(dialog);
+ }
+ private void ExpandCompendium(object sender, RoutedEventArgs e)
+ {
+ OpenFileDialog dialog = new OpenFileDialog();
+ dialog.CheckFileExists = false;
+ dialog.FileName = "Expand Compendium here";
+ ExtendCompendium(dialog);
+ }
+ private void OpenCompendium(object sender, RoutedEventArgs e)
+ {
+ OpenFileDialog openFile = new OpenFileDialog();
+ openFile.Filter = "MDF Material Compendium (*.mdfcomp)|*.mdfcomp";
+ if (openFile.ShowDialog() == true)
+ {
+ string jsontxt = File.ReadAllText(openFile.FileName);
+ Compendium nlib = JsonSerializer.Deserialize(jsontxt);
+ compendium.SetEntries(nlib.entries);
+ defs.lastOpenComp = openFile.FileName;
+ CompendiumChanged = false;
+ }
+ }
+ private void SaveCompendium(object sender, RoutedEventArgs e)
+ {
+ if (defs.lastOpenComp == "")
+ {
+ SaveCompendiumAs(sender, e);
+ }
+ string jsontxt = JsonSerializer.Serialize(compendium);
+ File.WriteAllText(defs.lastOpenComp, jsontxt);
+ CompendiumChanged = false;
+ }
+ private void SaveCompendiumAs(object sender, RoutedEventArgs e)
+ {
+ string jsontxt = JsonSerializer.Serialize(compendium);
+ SaveFileDialog saveFile = new SaveFileDialog();
+ saveFile.Filter = "MDF Material Compendium (*.mdfcomp)|*.mdfcomp";
+ if (saveFile.ShowDialog() == true)
+ {
+ File.WriteAllText(saveFile.FileName, jsontxt);
+ defs.lastOpenComp = saveFile.FileName;
+ CompendiumChanged = false;
+ }
+
+ }
+
+ private void CompendiumView_MouseMove(object sender, MouseEventArgs e)
+ {
+ if (!IsDragging && e.LeftButton == MouseButtonState.Pressed)
+ {
+ if (CompendiumView.SelectedItem != null && CompendiumView.SelectedItem is CompendiumEntry)
+ {
+ IsDragging = true;
+ CompendiumEntry entry = (CompendiumEntry)CompendiumView.SelectedItem;
+ DragDrop.DoDragDrop(CompendiumView, CompendiumView.SelectedValue,
+ DragDropEffects.Copy);
+ IsDragging = false;
+ }
+ }
+ }
+
+ private void LibraryView_Drop(object sender, DragEventArgs e)
+ {
+ if (e.Data.GetDataPresent(typeof(CompendiumEntry)))
+ {
+ CompendiumEntry entry = (CompendiumEntry)e.Data.GetData(typeof(CompendiumEntry));
+ BinaryReader readFile = HelperFunctions.OpenFileR(entry.MDFPath, Encoding.Unicode);
+ if (readFile != null)
+ {
+ MDFTypes type = (MDFTypes)Convert.ToInt32(System.IO.Path.GetExtension(entry.MDFPath).Replace(".", ""));
+ MDFFile ibmdf = new MDFFile(entry.MDFPath, readFile, type);
+ LibraryEntryHeader libHead = new LibraryEntryHeader(entry.MDFPath);
+ for (int i = 0; i < ibmdf.Materials.Count; i++)
+ {
+ LibraryEntry le = new LibraryEntry(ibmdf.Materials[i].Name, entry.MDFPath);
+ //le.Foreground = HelperFunctions.GetBrushFromHex("#000000");
+ libHead.Items.Add(le);
+ }
+ lib.entries.Add(libHead);
+ readFile.Close();
+ LibraryChanged = true;
+ }
+ }
+ }
+
+ private void LibraryView_DragOver(object sender, DragEventArgs e)
+ {
+ if (!e.Data.GetDataPresent(typeof(CompendiumEntry)))
+ {
+ e.Effects = DragDropEffects.None;
+ }
+ }
+
+ private void MaterialView_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+
+ }
+
+ private void BatchConvert(object sender, RoutedEventArgs e)
+ {
+ BatchConverter batch = new BatchConverter();
+ batch.Show();
+ }
+ }
+ public class PropertySelect : DataTemplateSelector
+ {
+ public DataTemplate FloatTemplate { get; set; }
+ public DataTemplate Float4Template { get; set; }
+ public override DataTemplate SelectTemplate(object item, DependencyObject container)
+ {
+ if (item != null)
+ {
+ if (item is FloatProperty)
+ {
+ return FloatTemplate;
+ }
+ else if (item is Float4Property)
+ {
+ return Float4Template;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+ public class LibSelect : DataTemplateSelector
+ {
+ public DataTemplate LibEntry { get; set; }
+ public DataTemplate LibEntryHead { get; set; }
+ public override DataTemplate SelectTemplate(object item, DependencyObject container)
+ {
+ if (item != null)
+ {
+ if (item is LibraryEntry)
+ {
+ return LibEntry;
+ }
+ else if (item is LibraryEntryHeader)
+ {
+ return LibEntryHead;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+ public class CompSelect : DataTemplateSelector
+ {
+ public DataTemplate CompEntry { get; set; }
+ public DataTemplate CompEntryHead { get; set; }
+ public DataTemplate CompTopLevel { get; set; }
+ public override DataTemplate SelectTemplate(object item, DependencyObject container)
+ {
+ if (item != null)
+ {
+ if (item is CompendiumEntry)
+ {
+ return CompEntry;
+ }
+ else if (item is CompendiumEntryHeader)
+ {
+ return CompEntryHead;
+ }
+ else if(item is CompendiumTopLevel)
+ {
+ return CompTopLevel;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+}
diff --git a/MDF-Manager/Resources/MDF-Manager_Icon.ico b/MDF-Manager/Resources/MDF-Manager_Icon.ico
new file mode 100644
index 0000000..b7836c4
Binary files /dev/null and b/MDF-Manager/Resources/MDF-Manager_Icon.ico differ
diff --git a/MDF-Manager/Resources/_downarrow.png b/MDF-Manager/Resources/_downarrow.png
new file mode 100644
index 0000000..f8fe55c
Binary files /dev/null and b/MDF-Manager/Resources/_downarrow.png differ
diff --git a/MDF-Manager/Resources/_uparrow.png b/MDF-Manager/Resources/_uparrow.png
new file mode 100644
index 0000000..07ef27f
Binary files /dev/null and b/MDF-Manager/Resources/_uparrow.png differ
diff --git a/MDF-Manager/Resources/downarrow.png b/MDF-Manager/Resources/downarrow.png
index f8fe55c..47c024f 100644
Binary files a/MDF-Manager/Resources/downarrow.png and b/MDF-Manager/Resources/downarrow.png differ
diff --git a/MDF-Manager/Resources/icons/icon_batch.png b/MDF-Manager/Resources/icons/icon_batch.png
new file mode 100644
index 0000000..80851cc
Binary files /dev/null and b/MDF-Manager/Resources/icons/icon_batch.png differ
diff --git a/MDF-Manager/Resources/icons/icon_open.png b/MDF-Manager/Resources/icons/icon_open.png
new file mode 100644
index 0000000..f0062eb
Binary files /dev/null and b/MDF-Manager/Resources/icons/icon_open.png differ
diff --git a/MDF-Manager/Resources/icons/icon_save.png b/MDF-Manager/Resources/icons/icon_save.png
new file mode 100644
index 0000000..845b84b
Binary files /dev/null and b/MDF-Manager/Resources/icons/icon_save.png differ
diff --git a/MDF-Manager/Resources/icons/icon_saveall.png b/MDF-Manager/Resources/icons/icon_saveall.png
new file mode 100644
index 0000000..38acdca
Binary files /dev/null and b/MDF-Manager/Resources/icons/icon_saveall.png differ
diff --git a/MDF-Manager/Resources/icons/icon_saveas.png b/MDF-Manager/Resources/icons/icon_saveas.png
new file mode 100644
index 0000000..4b77172
Binary files /dev/null and b/MDF-Manager/Resources/icons/icon_saveas.png differ
diff --git a/MDF-Manager/Resources/uparrow.png b/MDF-Manager/Resources/uparrow.png
index 07ef27f..5150d50 100644
Binary files a/MDF-Manager/Resources/uparrow.png and b/MDF-Manager/Resources/uparrow.png differ
diff --git a/MDF-Manager/ThemeManager.xaml b/MDF-Manager/ThemeManager.xaml
index b641138..3d54ee4 100644
--- a/MDF-Manager/ThemeManager.xaml
+++ b/MDF-Manager/ThemeManager.xaml
@@ -1,34 +1,34 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MDF-Manager/ThemeManager.xaml.cs b/MDF-Manager/ThemeManager.xaml.cs
index 289c20e..ac6d3b0 100644
--- a/MDF-Manager/ThemeManager.xaml.cs
+++ b/MDF-Manager/ThemeManager.xaml.cs
@@ -1,110 +1,110 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Shapes;
-
-namespace MDF_Manager
-{
- ///
- /// Interaction logic for ThemeManager.xaml
- ///
- public partial class ThemeManager : Window
- {
-
- private Color _Background = new Color { R = 226, G = 226, B = 226, A = 255 };
- private Color _Foreground = new Color { R = 255, G = 255, B = 255, A = 255 };
- private Color _Windows = new Color { R = 255, G = 255, B = 255, A = 255 };
- private Color _Button = new Color { R = 226, G = 226, B = 226, A = 255 };
- private Color _Text = new Color { R = 0, G = 0, B = 0, A = 255 };
-
- public SolidColorBrush BackgroundColor
- { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Background); set { _Background = value.Color; UpdateRects(); } }
- public SolidColorBrush ForegroundColor
- { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Foreground); set { _Foreground = value.Color; UpdateRects(); } }
- public SolidColorBrush WindowsColor
- { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Windows); set { _Windows = value.Color; UpdateRects(); } }
- public SolidColorBrush ButtonColor
- { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Button); set { _Button = value.Color; UpdateRects(); } }
- public SolidColorBrush TextColor
- { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Text); set { _Text = value.Color; UpdateRects(); } }
- public ThemeManager()
- {
- InitializeComponent();
- UpdateRects();
- }
-
- public void UpdateRects()
- {
- Background.Fill = BackgroundColor;
- Foreground.Fill = ForegroundColor;
- Windows.Fill = WindowsColor;
- Buttons.Fill = ButtonColor;
- Text.Fill = TextColor;
- }
- private void SetBackground(object sender, MouseButtonEventArgs e)
- {
- ColorCanvas cc = new ColorCanvas();
- cc.colorCanvas.SelectedColor = _Background;
- if (cc.ShowDialog() == true)
- {
- _Background = (Color)cc.colorCanvas.SelectedColor;
- }
- UpdateRects();
- }
- private void SetForeground(object sender, MouseButtonEventArgs e)
- {
- ColorCanvas cc = new ColorCanvas();
- cc.colorCanvas.SelectedColor = _Foreground;
- if (cc.ShowDialog() == true)
- {
- _Foreground = (Color)cc.colorCanvas.SelectedColor;
- }
- UpdateRects();
- }
- private void SetWindows(object sender, MouseButtonEventArgs e)
- {
- ColorCanvas cc = new ColorCanvas();
- cc.colorCanvas.SelectedColor = _Windows;
- if (cc.ShowDialog() == true)
- {
- _Windows = (Color)cc.colorCanvas.SelectedColor;
- }
- UpdateRects();
- }
- private void SetButton(object sender, MouseButtonEventArgs e)
- {
- ColorCanvas cc = new ColorCanvas();
- cc.colorCanvas.SelectedColor = _Button;
- if (cc.ShowDialog() == true)
- {
- _Button = (Color)cc.colorCanvas.SelectedColor;
- }
- UpdateRects();
- }
- private void SetText(object sender, MouseButtonEventArgs e)
- {
- ColorCanvas cc = new ColorCanvas();
- cc.colorCanvas.SelectedColor = _Text;
- if (cc.ShowDialog() == true)
- {
- _Text = (Color)cc.colorCanvas.SelectedColor;
- }
- UpdateRects();
- }
-
- private void Confirm(object sender, RoutedEventArgs e)
- {
- DialogResult = true;
- Close();
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace MDF_Manager
+{
+ ///
+ /// Interaction logic for ThemeManager.xaml
+ ///
+ public partial class ThemeManager : Window
+ {
+
+ private Color _Background = new Color { R = 226, G = 226, B = 226, A = 255 };
+ private Color _Foreground = new Color { R = 255, G = 255, B = 255, A = 255 };
+ private Color _Windows = new Color { R = 255, G = 255, B = 255, A = 255 };
+ private Color _Button = new Color { R = 226, G = 226, B = 226, A = 255 };
+ private Color _Text = new Color { R = 0, G = 0, B = 0, A = 255 };
+
+ public SolidColorBrush BackgroundColor
+ { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Background); set { _Background = value.Color; UpdateRects(); } }
+ public SolidColorBrush ForegroundColor
+ { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Foreground); set { _Foreground = value.Color; UpdateRects(); } }
+ public SolidColorBrush WindowsColor
+ { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Windows); set { _Windows = value.Color; UpdateRects(); } }
+ public SolidColorBrush ButtonColor
+ { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Button); set { _Button = value.Color; UpdateRects(); } }
+ public SolidColorBrush TextColor
+ { get => (SolidColorBrush)HelperFunctions.GetBrushFromColor(_Text); set { _Text = value.Color; UpdateRects(); } }
+ public ThemeManager()
+ {
+ InitializeComponent();
+ UpdateRects();
+ }
+
+ public void UpdateRects()
+ {
+ Background.Fill = BackgroundColor;
+ Foreground.Fill = ForegroundColor;
+ Windows.Fill = WindowsColor;
+ Buttons.Fill = ButtonColor;
+ Text.Fill = TextColor;
+ }
+ private void SetBackground(object sender, MouseButtonEventArgs e)
+ {
+ ColorCanvas cc = new ColorCanvas();
+ cc.colorCanvas.SelectedColor = _Background;
+ if (cc.ShowDialog() == true)
+ {
+ _Background = (Color)cc.colorCanvas.SelectedColor;
+ }
+ UpdateRects();
+ }
+ private void SetForeground(object sender, MouseButtonEventArgs e)
+ {
+ ColorCanvas cc = new ColorCanvas();
+ cc.colorCanvas.SelectedColor = _Foreground;
+ if (cc.ShowDialog() == true)
+ {
+ _Foreground = (Color)cc.colorCanvas.SelectedColor;
+ }
+ UpdateRects();
+ }
+ private void SetWindows(object sender, MouseButtonEventArgs e)
+ {
+ ColorCanvas cc = new ColorCanvas();
+ cc.colorCanvas.SelectedColor = _Windows;
+ if (cc.ShowDialog() == true)
+ {
+ _Windows = (Color)cc.colorCanvas.SelectedColor;
+ }
+ UpdateRects();
+ }
+ private void SetButton(object sender, MouseButtonEventArgs e)
+ {
+ ColorCanvas cc = new ColorCanvas();
+ cc.colorCanvas.SelectedColor = _Button;
+ if (cc.ShowDialog() == true)
+ {
+ _Button = (Color)cc.colorCanvas.SelectedColor;
+ }
+ UpdateRects();
+ }
+ private void SetText(object sender, MouseButtonEventArgs e)
+ {
+ ColorCanvas cc = new ColorCanvas();
+ cc.colorCanvas.SelectedColor = _Text;
+ if (cc.ShowDialog() == true)
+ {
+ _Text = (Color)cc.colorCanvas.SelectedColor;
+ }
+ UpdateRects();
+ }
+
+ private void Confirm(object sender, RoutedEventArgs e)
+ {
+ DialogResult = true;
+ Close();
+ }
+ }
+}
diff --git a/README.md b/README.md
index 42606db..b1c645e 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,9 @@
+# Software is EOL use [REE-Content-Editor](https://github.com/kagenocookie/REE-Content-Editor) instead!
+
# MDF-Manager
A C# WPF GUI application to edit RE Engine material files (*.mdf2)
-# Usage
+# Usage:
Open a compatible mdf file by clicking File -> Open, or by simply dropping the file onto the program. You can save the currently selected mdf by pressing File -> Save,
or File -> Save As to save it under a different name.
@@ -17,10 +19,13 @@ knowledge of shader coding.
The color of certain UI elements can be changed by clicking Theme at the top of the program.
-# Installation
+# Installation:
+### Prerequisite: [.NET5 SDK 5.0.408](https://dotnet.microsoft.com/en-us/download/dotnet/5.0) or [.NET SDK 8.0.300](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
+
Just download the most recent release from the sidebar to the right. If you would like to build the project, open the solution in Visual Studio, right click on the
MDF-Manager project and select "Restore NuGet Packages", then build the project.
-# Credits
+# Credits:
+* **Silvris** - for creating the original version of the tool.
* **Che, Darkness, and alphaZomega** - for MDF structure documentation
* **AsteriskAmpersand** - his mrl3 editor served as a general inspiration for the layout and library/compendium functionality