/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void addRootFromFileToolStripMenuItem_Click(object sender, EventArgs e) { var f = Tools.FileIO.OpenFile("HSD (*.dat;*.txg)|*.dat;*.txg"); if (f != null) { if (f.ToLower().EndsWith(".dat")) { var file = new HSDRawFile(f); RawHSDFile.Roots.Add(file.Roots[0]); } if (f.ToLower().EndsWith(".txg")) { var str = new HSDStruct(); str.SetData(System.IO.File.ReadAllBytes(f)); RawHSDFile.Roots.Add(new HSDRootNode() { Name = "TextureGraphic", Data = new HSDRaw.Common.HSD_TEXGraphicBank() { _s = str } }); } RefreshTree(); } }
public static void Reconstruct(string filepath, string animPath, string directory, string rootName) { var path = Path.GetDirectoryName(directory); HSDRawFile file = new HSDRawFile(); HSDRootNode root = new HSDRootNode(); root.Name = rootName; var ftData = new SBM_FighterData(); root.Data = ftData; file.Roots.Add(root); var prop = root.Data.GetType().GetProperties().ToList(); foreach (var f in Directory.GetFiles(directory)) { if (f.EndsWith(".dat")) { HSDRawFile chunk = new HSDRawFile(f); Console.WriteLine(f + " " + chunk.Roots.Count); var property = prop.Find(e => e.Name == chunk.Roots[0].Name); if (property != null) { var newt = Activator.CreateInstance(property.PropertyType); { var dset = newt as HSDAccessor; if (dset != null) { dset._s = chunk.Roots[0].Data._s; } } property.SetValue(root.Data, newt); } } else if (f.EndsWith(".ini")) { SBM_CommonFighterAttributes attr = new SBM_CommonFighterAttributes(); using (StreamReader r = new StreamReader(new FileStream(f, FileMode.Open))) { foreach (var v in attr.GetType().GetProperties()) { if (v.Name.Equals("TrimmedSize")) { continue; } var line = r.ReadLine().Split('='); if (line.Length < 2 || line[0] != v.Name) { throw new InvalidDataException("Invalid Attribute " + string.Join("=", line)); } if (v.PropertyType == typeof(int)) { v.SetValue(attr, int.Parse(line[1].Trim())); } if (v.PropertyType == typeof(float)) { v.SetValue(attr, float.Parse(line[1].Trim())); } } } ftData.Attributes = attr; } else if (f.EndsWith(".txt")) { XmlSerializer writer = new XmlSerializer(typeof(ScriptFile)); var script = (ScriptFile)writer.Deserialize(new FileStream(f, FileMode.Open)); Dictionary <string, Tuple <int, int> > animationToOffset = new Dictionary <string, Tuple <int, int> >(); List <SBM_FighterAction> SubActions = new List <SBM_FighterAction>(); Dictionary <SBM_FighterAction, string> subActionToScript = new Dictionary <SBM_FighterAction, string>(); Dictionary <string, HSDStruct> stringToStruct = new Dictionary <string, HSDStruct>(); using (BinaryWriter w = new BinaryWriter(new FileStream(animPath, FileMode.Create))) { foreach (var s in script.Actions) { SBM_FighterAction subaction = new SBM_FighterAction(); subaction.Flags = (uint)s.flags; if (s.animation_name != null) { if (!stringToStruct.ContainsKey(s.animation_name)) { var namestruct = new HSDStruct(); byte[] data = new byte[s.animation_name.Length + 1]; var bytes = UTF8Encoding.UTF8.GetBytes(s.animation_name); for (int i = 0; i < s.animation_name.Length; i++) { data[i] = bytes[i]; } namestruct.SetData(data); stringToStruct.Add(s.animation_name, namestruct); } subaction._s.SetReferenceStruct(0, stringToStruct[s.animation_name]); //subaction.Name = s.animation_name; if (!animationToOffset.ContainsKey(s.animation_name)) { if (File.Exists(path + "\\Animations\\" + s.animation_name + ".dat")) { var data = File.ReadAllBytes(path + "\\Animations\\" + s.animation_name + ".dat"); animationToOffset.Add(s.animation_name, new Tuple <int, int>((int)w.BaseStream.Position, data.Length)); w.Write(data); if (w.BaseStream.Length % 0x20 != 0) { var padd = new byte[0x20 - (w.BaseStream.Position % 0x20)]; for (int i = 0; i < padd.Length; i++) { padd[i] = 0xFF; } w.Write(padd); } } else { throw new FileNotFoundException("Could not find animation " + path + "\\Animations\\" + s.animation_name + ".dat"); } } subaction.AnimationOffset = animationToOffset[s.animation_name].Item1; subaction.AnimationSize = animationToOffset[s.animation_name].Item2; } if (s.script != null) { ActionCompiler.Compile(s.script); subActionToScript.Add(subaction, s.script); } SubActions.Add(subaction); } } ftData.FighterActionTable = new SBM_FighterActionTable(); ActionCompiler.LinkStructs(); ftData.FighterActionTable.Commands = SubActions.ToArray(); Console.WriteLine("recompiled count " + ftData.FighterActionTable._s.GetSubStructs().Count); } } file.Save(filepath); }
/// <summary> /// Compiles script into subaction byte code /// </summary> public static void Compile(string script) { if (scriptToBinary.ContainsKey(script) || scriptToReference.ContainsKey(script)) { return; } HSDStruct main = null; var stream = Regex.Replace(script, @"\s+", string.Empty); if (script.StartsWith("ref:")) { var name = stream.Split(':')[1]; scriptToReference.Add(script, name); return; } var functions = Regex.Matches(stream, @"([^\{])*\{([^\}]*)\}"); foreach (Match g in functions) { var name = Regex.Match(g.Value, @".+?(?={)").Value; var code = Regex.Match(g.Value, @"(?<=\{).+?(?=\})").Value.Split(';'); if (nameToFunction.ContainsKey(name)) { continue; } HSDStruct s = new HSDStruct(); nameToFunction.Add(name, s); structToOffsetToFunction.Add(s, new Dictionary <int, string>()); if (main == null) { main = s; } List <byte> output = new List <byte>(); bool returned = false; foreach (var c in code) { var cname = Regex.Match(c, @".+?(?=\()").Value; var cparameters = Regex.Match(c, @"(?<=\().+?(?=\))").Value.Split(','); if (cname == "Return") { returned = true; } byte flag = ActionCommon.GetMeleeCMDAction(cname).Command; if (flag == 0x5 || flag == 0x7) //goto and subroutine { structToOffsetToFunction[s].Add(output.Count + 4, cparameters[0]); output.AddRange(new byte[] { (byte)(flag << 2), 0, 0, 0, 0, 0, 0, 0 }); } else { output.AddRange(CompileCommand(cname, cparameters)); } // padd if (output.Count % 4 != 0) { output.AddRange(new byte[4 - (output.Count % 4)]); } } if (true) { output.Add(0); if (output.Count % 4 != 0) { output.AddRange(new byte[4 - (output.Count % 4)]); } } s.SetData(output.ToArray()); } if (main == null) { main = new HSDStruct(4); } scriptToBinary.Add(script, main); }