public bool ValidateDimensions(TreeTexInfo tex = null) { bool power = UsefulThings.General.IsPowerOfTwo(Height) && UsefulThings.General.IsPowerOfTwo(Width); if (tex != null) { // KFreon: Set dimensions from tree tex. I don't like this method. The ratio should just be set during tree creation and saved in the tree, but back compatibility and such. try { string pathBioGame = null; switch (GameVersion) { case 1: pathBioGame = ME1Directory.BioGamePath; break; case 2: pathBioGame = ME2Directory.BioGamePath; break; case 3: pathBioGame = ME3Directory.BIOGamePath; break; } if (pathBioGame != null) { var pcc = PCCObjects.Creation.CreatePCCObject(tex.Files[0], GameVersion); var tex2D = pcc.CreateTexture2D(tex.ExpIDs[0], pathBioGame); var img = tex2D.imgList.Where(t => t.offset != -1).FirstOrDefault(); if (img != null) { OrigHeight = (int)img.imgSize.height; OrigWidth = (int)img.imgSize.width; } } } catch (Exception e) { DebugOutput.PrintLn($"Failed to get dimensions of original texture: {e.Message}"); } } IncorrectRatio = !((OrigHeight * 1.0 / OrigWidth * 1.0) == (Height * 1.0 / Width * 1.0)); return(power); }
public void Update(TreeTexInfo tex, string pathBIOGame) { Update(tex.Files, tex.ExpIDs, tex.Hash, tex.NumMips, tex.Textures, pathBIOGame); }
public bool ReadFromFile(string TreeName, string mainpath, string thumbpath, out int status, Form invokeObject = null) { status = 0; if (!File.Exists(TreeName)) return false; TreePath = TreeName; try { using (FileStream fs = new FileStream(TreeName, FileMode.Open, FileAccess.Read)) { using (BinaryReader bin = new BinaryReader(fs)) { int numthings = bin.ReadInt32(); if (numthings == 1991) { AdvancedFeatures = true; numthings = bin.ReadInt32(); Debugging.DebugOutput.PrintLn("Advanced ME" + GameVersion + " Tree features detected."); } else Debugging.DebugOutput.PrintLn("Advanced ME" + GameVersion + " Tree features disabled."); for (int i = 0; i < numthings; i++) { TreeTexInfo tempStruct = new TreeTexInfo(); int temp = bin.ReadInt32(); char[] tempChar = bin.ReadChars(temp); tempStruct.TexName = new string(tempChar); tempStruct.Hash = bin.ReadUInt32(); tempChar = bin.ReadChars(bin.ReadInt32()); tempStruct.FullPackage = new string(tempChar); tempChar = bin.ReadChars(bin.ReadInt32()); if (AdvancedFeatures) { string thum = new string(tempChar); tempStruct.ThumbnailPath = thum != null ? Path.Combine(thumbpath, thum) : null; } tempStruct.NumMips = bin.ReadInt32(); tempStruct.Format = ""; int formatlen = bin.ReadInt32(); tempChar = bin.ReadChars(formatlen); tempStruct.Format = new string(tempChar); int numFiles = bin.ReadInt32(); tempStruct.Files = new List<string>(); for (int j = 0; j < numFiles; j++) { tempChar = bin.ReadChars(bin.ReadInt32()); string tempStr = new string(tempChar); tempStruct.Files.Add(Path.Combine(mainpath, tempStr)); } tempStruct.ExpIDs = new List<int>(); tempStruct.TriedThumbUpdate = false; for (int j = 0; j < numFiles; j++) tempStruct.ExpIDs.Add(bin.ReadInt32()); tempStruct.OriginalFiles = new List<string>(tempStruct.Files); tempStruct.OriginalExpIDs = new List<int>(tempStruct.ExpIDs); BlindAddTex(tempStruct); } } } } catch { if (invokeObject != null) { int temp = status; invokeObject.Invoke(new Action(() => { if (MessageBox.Show("Tree is corrupted or wrong tree loaded :(" + Environment.NewLine + "Do you want to build a new tree?", "Mission Failure.", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == System.Windows.Forms.DialogResult.Yes) { File.Delete(TreeName); temp = 1; } else temp = 2; })); status = temp; } else status = 2; return false; } return true; }
/// <summary> /// Adds texture to tree with duplicate checks /// </summary> /// <param name="tex">Texture to add</param> public void AddTex(TreeTexInfo tex, string PackName, string filename) { lock (Sync) { List<object> tmp = new List<object>(); tmp.Add(tex); tmp.Add(PackName); tmp.Add(filename); TreeTempTexes.Add(tmp); // KFreon: Start again if finished if (TreeAddTask.Status == TaskStatus.RanToCompletion) { TreeAddTask = null; TreeAddTask = new Task(() => PerformTreeComparison()); TreeAddTask.Start(); } else if (TreeAddTask.Status == TaskStatus.Created) // KFreon: Start if never started before TreeAddTask.Start(); } }
public void BlindAddTex(TreeTexInfo tex) { lock (Sync) { tex.TreeInd = TexCount; Texes.Add(tex); } }
private bool Compare(TreeTexInfo tex, int i, string PackName, string filename) { if (tex.TexName == Texes[i].TexName) if ((tex.Hash == 0 && tex.tfcOffset == Texes[i].tfcOffset) || (tex.Hash != 0 && tex.Hash == Texes[i].Hash)) { if (tex.GameVersion == 1 && (tex.Package.ToLowerInvariant() == PackName.ToLowerInvariant() || Path.GetFileNameWithoutExtension(filename).ToLowerInvariant().Contains(tex.Package.ToLowerInvariant()))) return true; else if (tex.GameVersion != 1) return true; else return false; } return false; }
private void UpdatePCCList(bool SelectAll, TreeTexInfo current) { if (SelectAll) for (int i = 0; i < PCCsCheckedListBox.Items.Count; i++) PCCsCheckedListBox.SetItemChecked(i, PCCsCheckedListBox.GetItemChecked(0)); else PCCsCheckedListBox.SetItemChecked(0, false); List<string> newlist = new List<string>(); List<int> newlist2 = new List<int>(); foreach (string item in PCCsCheckedListBox.CheckedItems) { var bits = item.Split('@'); if (bits.Length == 1) continue; newlist.Add(bits[0].Trim()); newlist2.Add(Convert.ToInt32(bits[1])); } current.Files = new List<string>(newlist); current.ExpIDs = new List<int>(newlist2); Tree.ReplaceTex(GetSelectedTexInd(), current); }
private bool DeepScanPCC(string filename) { try { using (PCCObjects.IPCCObject temppcc = PCCObjects.Creation.CreatePCCObject(filename, WhichGame)) { // KFreon: Search the exports list for viable texture types for (int i = 0; i < temppcc.Exports.Count; i++) { //TreeTexInfo tex = KFreonFormsLib.Miscextra.GenerateTexStruct(temppcc, i, WhichGame, pathBIOGame, ExecFolder, allpccs); bool result; TreeTexInfo tex = new TreeTexInfo(temppcc, i, WhichGame, pathBIOGame, ExecFolder, out result); if (result) Tree.AddTex(tex, (WhichGame == 1) ? temppcc.Exports[i].Package : "", filename); } } } catch(Exception e) { DebugOutput.PrintLn("Scanning PCC: " + filename + " failed. Reason: " + e.ToString()); return false; } return true; }
private void RegenerateThumbnail(TreeTexInfo tex, int index, bool FromFile) { // KFreon: Try to delete old thumbnail for (int i = 0; i < 10; i++) { try { if (File.Exists(tex.ThumbnailPath)) { File.Delete(tex.ThumbnailPath); DebugOutput.PrintLn("Deleted old thumbnail successfully at: " + tex.ThumbnailPath); } break; } catch { this.Invoke(new Action(() => ListViewImageList.Images.Clear())); System.Threading.Thread.Sleep(200); } } // KFreon: Update tex details if necessary Textures.ITexture2D tex2D = null; UpdateTexDetails(index, out tex, out tex2D); string thumbpath = tex.ThumbnailPath ?? Path.Combine(ThumbnailPath, tex.ThumbName); if (FromFile) Textures.Creation.GenerateThumbnail(tex.Files[0], WhichGame, tex.ExpIDs[0], pathBIOGame, thumbpath, ExecFolder); else using (MemoryStream ms = new MemoryStream(tex2D.GetImageData())) ImageEngine.GenerateThumbnailToFile(ms, thumbpath, 128); Tree.ReplaceTex(index, tex); }
private void UpdateModifiedTex(Textures.ITexture2D tex2D, TreeTexInfo tex, int ind) { if (!tex2D.hasChanged) tex2D.hasChanged = true; tex.Textures[0] = tex2D; // KFreon: Change texture in tree if (!ChangedTextures.Contains(ind)) ChangedTextures.Add(ind); Tree.ReplaceTex(ind, tex); }
private void UpdateTexDetails(int index, out TreeTexInfo tex, out Textures.ITexture2D tex2D) { tex = Tree.GetTex(index); tex2D = tex.Textures[0]; //if (tex2D.imgList.Count == 0) if (!tex2D.hasChanged) { //Textures.ITexture2D newtex2D = KFreonFormsLib.Textures.Creation.CreateTexture2D(KFreonFormsLib.PCCObjects.Creation.CreatePCCObject(tex2D.allPccs[0], WhichGame), tex2D.expIDs[0], WhichGame, pathBIOGame, tex2D.Hash); tex2D = Textures.Creation.CreateTexture2D(tex2D, WhichGame, pathBIOGame); tex.Textures = new List<Textures.ITexture2D>(); tex.Textures.Add(tex2D); Tree.ReplaceTex(index, tex); } }
internal void AddToTree(string path, int exportID) { MessageBox.Show("THIS DOESN'T WORK YET! LET ME KNOW PLEASE."); return; BeginLoadingTree(true); using (PCCObjects.IPCCObject pcc = PCCObjects.Creation.CreatePCCObject(path, WhichGame)) { //TreeTexInfo tex = KFreonFormsLib.Miscextra.GenerateTexStruct(pcc, exportID, WhichGame, pathBIOGame, ExecFolder, Tree.GetPCCsAsList()); bool Success; TreeTexInfo tex = new TreeTexInfo(pcc, exportID, WhichGame, pathBIOGame, ExecFolder, out Success); Tree.AddTex(tex, "", ""); // not right - should be blind add? if (File.Exists(Tree.TreePath)) File.Delete(Tree.TreePath); Tree.WriteToFile(Tree.TreePath, Path.GetDirectoryName(pathBIOGame)); } }
private void UpdatePCCList(bool SelectAll, TreeTexInfo current) { if (SelectAll) for (int i = 0; i < PCCsCheckedListBox.Items.Count; i++) PCCsCheckedListBox.SetItemChecked(i, PCCsCheckedListBox.GetItemChecked(0)); else PCCsCheckedListBox.SetItemChecked(0, false); List<string> newlist = new List<string>(); foreach (string item in PCCsCheckedListBox.CheckedItems) newlist.Add(item.Split('@')[0].Trim()); current.Files = new List<string>(newlist); Tree.ReplaceTex(GetSelectedTexInd(), current); }
/// <summary> /// Updates current texture object from tree. /// </summary> /// <param name="treeInd">Index of texture in tree.</param> /// <param name="treetex">Tree texture object to get info from.</param> public void UpdateTex(int treeInd, TreeTexInfo treetex) { found = true; TreeInd = treeInd; TexName = treetex.TexName; // KFreon: Reorder files so DLC isn't first /*List<string> files = new List<string>(treetex.Files); List<int> ids = new List<int>(treetex.ExpIDs); int count = files.Count; int index = -1; if (files[0].Contains("DLC")) for (int i = 0; i < count; i++) if (!files[i].Contains("DLC")) { index = i; break; } if (index != -1) { string thing = files[index]; files.RemoveAt(index); files.Insert(0, thing); int thing2 = ids[index]; ids.RemoveAt(index); ids.Insert(0, thing2); } Files.AddRange(files); ExpIDs.AddRange(ids);*/ Files.AddRange(treetex.Files); ExpIDs.AddRange(treetex.ExpIDs); List<PCCExpID> things = new List<PCCExpID>(); for (int i = 0; i < Files.Count; i++) things.Add(new PCCExpID(Files[i], ExpIDs[i])); // KFreon: Reorder ME1 files if (GameVersion == 1) { things = things.OrderByDescending(t => t.file.Length).ToList(); Files.Clear(); ExpIDs.Clear(); foreach (var item in things) { Files.Add(item.file); ExpIDs.Add(item.expid); } } //ExpIDs.AddRange(treetex.ExpIDs); OriginalFiles = new List<string>(Files); OriginalExpIDs = new List<int>(ExpIDs); ExpectedMips = treetex.NumMips; ExpectedFormat = treetex.Format; // KFreon: File Dups List<TPFTexInfo> dups = new List<TPFTexInfo>(FileDuplicates); FileDuplicates.Clear(); foreach (TPFTexInfo tex in dups) { TPFTexInfo texn = tex; texn.found = true; texn.TreeInd = TreeInd; texn.TexName = treetex.TexName; texn.Files.AddRange(treetex.Files); texn.ExpIDs.AddRange(treetex.ExpIDs); texn.ExpectedFormat = treetex.Format; texn.ExpectedMips = treetex.NumMips; texn.OriginalExpIDs = new List<int>(ExpIDs); texn.OriginalFiles = new List<string>(Files); FileDuplicates.Add(texn); } ValidDimensions = ValidateDimensions(treetex); }
public bool ValidateDimensions(TreeTexInfo tex = null) { bool power = UsefulThings.General.IsPowerOfTwo(Height) && UsefulThings.General.IsPowerOfTwo(Width); if (tex != null) { // KFreon: Set dimensions from tree tex. I don't like this method. The ratio should just be set during tree creation and saved in the tree, but back compatibility and such. try { string pathBioGame = null; switch (GameVersion) { case 1: pathBioGame = ME1Directory.BioGamePath; break; case 2: pathBioGame = ME2Directory.BioGamePath; break; case 3: pathBioGame = ME3Directory.BIOGamePath; break; } if (pathBioGame != null) { var pcc = PCCObjects.Creation.CreatePCCObject(tex.Files[0], GameVersion); var tex2D = pcc.CreateTexture2D(tex.ExpIDs[0], pathBioGame); var img = tex2D.imgList.Where(t => t.offset != -1).FirstOrDefault(); if (img != null) { OrigHeight = (int)img.imgSize.height; OrigWidth = (int)img.imgSize.width; } } } catch (Exception e) { DebugOutput.PrintLn($"Failed to get dimensions of original texture: {e.Message}"); } } IncorrectRatio = !((OrigHeight * 1.0 / OrigWidth * 1.0) == (Height * 1.0 / Width * 1.0)); return power; }
public bool ReplaceTex(int index, TreeTexInfo tex) { lock (Sync) { if (index < 0 || index >= TexCount) return false; else { Texes[index] = tex; return true; } } }
/// <summary> /// Updates current texture object from tree. /// </summary> /// <param name="treeInd">Index of texture in tree.</param> /// <param name="treetex">Tree texture object to get info from.</param> public void UpdateTex(int treeInd, TreeTexInfo treetex) { found = true; TreeInd = treeInd; TexName = treetex.TexName; // KFreon: Reorder files so DLC isn't first /*List<string> files = new List<string>(treetex.Files); * List<int> ids = new List<int>(treetex.ExpIDs); * * int count = files.Count; * int index = -1; * * if (files[0].Contains("DLC")) * for (int i = 0; i < count; i++) * if (!files[i].Contains("DLC")) * { * index = i; * break; * } * * if (index != -1) * { * string thing = files[index]; * files.RemoveAt(index); * files.Insert(0, thing); * * int thing2 = ids[index]; * ids.RemoveAt(index); * ids.Insert(0, thing2); * } * * Files.AddRange(files); * ExpIDs.AddRange(ids);*/ Files.AddRange(treetex.Files); ExpIDs.AddRange(treetex.ExpIDs); List <PCCExpID> things = new List <PCCExpID>(); for (int i = 0; i < Files.Count; i++) { things.Add(new PCCExpID(Files[i], ExpIDs[i])); } // KFreon: Reorder ME1 files if (GameVersion == 1) { things = things.OrderByDescending(t => t.file.Length).ToList(); Files.Clear(); ExpIDs.Clear(); foreach (var item in things) { Files.Add(item.file); ExpIDs.Add(item.expid); } } //ExpIDs.AddRange(treetex.ExpIDs); OriginalFiles = new List <string>(Files); OriginalExpIDs = new List <int>(ExpIDs); ExpectedMips = treetex.NumMips; ExpectedFormat = treetex.Format.Replace("PF_", ""); if (ExpectedFormat.ToUpperInvariant().Contains("NORMALMAP")) { ExpectedFormat = "ATI2_3Dc"; } if (ExpectedFormat.ToUpperInvariant().Contains("A8R8G8B8")) { ExpectedFormat = "ARGB"; } // KFreon: File Dups List <TPFTexInfo> dups = new List <TPFTexInfo>(FileDuplicates); FileDuplicates.Clear(); foreach (TPFTexInfo tex in dups) { TPFTexInfo texn = tex; texn.found = true; texn.TreeInd = TreeInd; texn.TexName = treetex.TexName; texn.Files.AddRange(treetex.Files); texn.ExpIDs.AddRange(treetex.ExpIDs); texn.ExpectedFormat = treetex.Format; texn.ExpectedMips = treetex.NumMips; texn.OriginalExpIDs = new List <int>(ExpIDs); texn.OriginalFiles = new List <string>(Files); FileDuplicates.Add(texn); } ValidDimensions = ValidateDimensions(); }
private TreeTexInfo Contains(TreeTexInfo tex, string PackName, string filename) { for (int i = 0; i < TexCount; i++) if (Compare(tex, i, PackName, filename)) return Texes[i]; return null; }