/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void CopyMoveLogic(object sender, EventArgs args) { if (fighterListBox.SelectedItem is MEXFighter fighter) { var moveLogic = fighter.Functions.MoveLogic; if (moveLogic == null) { MessageBox.Show("This MxDt file does not contains move logic", "Nothing to copy", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } var ftDataFile = MEX.ImageResource.GetFile(fighter.FighterDataPath); SBM_FighterData fighterData = null; if (ftDataFile != null) { fighterData = new HSDRawFile(ftDataFile).Roots[0].Data as SBM_FighterData; } StringBuilder table = new StringBuilder(); int index = 341; foreach (var m in moveLogic) { table.AppendLine($"\t// State: {index} - " + (fighterData != null && m.AnimationID != -1 && fighterData.FighterCommandTable.Commands[m.AnimationID].Name != null ? System.Text.RegularExpressions.Regex.Replace(fighterData.FighterCommandTable.Commands[m.AnimationID].Name.Replace("_figatree", ""), @"Ply.*_Share_ACTION_", "") : "Animation: " + m.AnimationID.ToString("X"))); index++; table.AppendLine(string.Format( "\t{{" + "\n\t\t{0, -12}// AnimationID" + "\n\t\t0x{1, -10}// StateFlags" + "\n\t\t0x{2, -10}// AttackID" + "\n\t\t0x{3, -10}// BitFlags" + "\n\t\t0x{4, -10}// AnimationCallback" + "\n\t\t0x{5, -10}// IASACallback" + "\n\t\t0x{6, -10}// PhysicsCallback" + "\n\t\t0x{7, -10}// CollisionCallback" + "\n\t\t0x{8, -10}// CameraCallback" + "\n\t}},", m.AnimationID + ",", m.StateFlags.ToString("X") + ",", m.AttackID.ToString("X") + ",", m.BitFlags.ToString("X") + ",", m.AnimationCallBack.ToString("X") + ",", m.IASACallBack.ToString("X") + ",", m.PhysicsCallback.ToString("X") + ",", m.CollisionCallback.ToString("X") + ",", m.CameraCallback.ToString("X") + "," )); } Clipboard.SetText( @"__attribute__((used)) static struct MoveLogic move_logic[] = { " + table.ToString() + @"}; "); MessageBox.Show("Move Logic Struct Copied to Clipboard", "Move Logic Copy"); } }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void openPldatToolStripMenuItem_Click(object sender, EventArgs e) { var f = Tools.FileIO.OpenFile("Player DAT (Pl**.dat)|*.dat"); if (f != null) { ResultAnimations.Clear(); FightingAnimations.Clear(); PlayerFile = null; PlayerData = null; AJLoaded = false; ResultLoaded = false; var file = new HSDRawFile(f); foreach (var root in file.Roots) { if (root.Data is SBM_FighterData plData) { ftDataPath = f; PlayerFile = file; PlayerData = plData; FighterName = root.Name.Replace("ftData", ""); Text = "AJ Split - " + FighterName; buttonLoadAnims.Enabled = true; buttonLoadResult.Enabled = true; exportDATsToolStripMenuItem.Enabled = true; } } } }
/// <summary> /// Takes a fighter file and converts it for easier use with mex with optional rename /// 1. Renames strings to new fighter names /// TODO: 2. Replace ids with personal ids in subactions /// 3. /// </summary> public static void ConvertToMEXFighter(SBM_FighterData fighterData, string oldName, string newName, string AJPath, string RstPath) { byte[] ajdata = File.ReadAllBytes(AJPath); var rstFile = new HSDRawFile(RstPath).Roots[0].Data; var sa = fighterData.FighterCommandTable.Commands; foreach (var v in sa) { v.Name = v.Name.Replace(oldName, newName); } fighterData.FighterCommandTable.Commands = sa; var wsa = fighterData.WinCommandTable.Commands; foreach (var v in wsa) { v.Name = v.Name.Replace(oldName, newName); } fighterData.WinCommandTable.Commands = wsa; }
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> /// /// </summary> /// <param name="args"></param> /// <returns></returns> public bool DoIt(string[] args) { // Parse Args List <Tuple <int, List <string> > > itemInputs = new List <Tuple <int, List <string> > >(); List <string> inputs = new List <string>(); LinkFile linkFile = new LinkFile(); string output = ""; string symbolName = ""; string datFile = null; string[] fightFuncTable = null; string buildPath = null; bool quiet = true; bool yesOverwrite = false; bool disableWarnings = true; bool clean = false; bool debug = false; int opLevel = 2; List <string> includes = new List <string>(); for (int i = 0; i < args.Length; i++) { if (args[i] == "-i") { for (int j = i + 1; j < args.Length; j++) { if (File.Exists(args[j])) { inputs.Add(Path.GetFullPath(args[j])); } else { break; } } } if (args[i] == "-inc") { for (int j = i + 1; j < args.Length; j++) { if (Directory.Exists(args[j])) { includes.Add(Path.GetFullPath(args[j])); } else { break; } } } if (args[i] == "-item" && i + 2 < args.Length) { List <string> itemRefList = new List <string>(); for (int j = i + 2; j < args.Length; j++) { if (args[j] != "-item" && File.Exists(args[j])) { itemRefList.Add(Path.GetFullPath(args[j])); } else { break; } } itemInputs.Add(new Tuple <int, List <string> >(int.Parse(args[i + 1]), itemRefList)); } if (args[i] == "-op" && i + 1 < args.Length) { opLevel = int.Parse(args[i + 1]); } if (args[i] == "-o" && i + 1 < args.Length) { output = Path.GetFullPath(args[i + 1]); } if (args[i] == "-dat" && i + 1 < args.Length) { datFile = Path.GetFullPath(args[i + 1]); } if (args[i] == "-s" && i + 1 < args.Length) { symbolName = args[i + 1]; } if (args[i] == "-ow") { yesOverwrite = true; } if (args[i] == "-w") { disableWarnings = false; } if (args[i] == "-d") { debug = true; } if (args[i] == "-t" && i + 1 < args.Length) { fightFuncTable = File.ReadAllLines(args[i + 1]); } if (args[i] == "-v") { quiet = false; } if (args[i] == "-b" && i + 1 < args.Length) { buildPath = Path.GetFullPath(args[i + 1]); } if (args[i] == "-l" && i + 1 < args.Length) { linkFile.LoadLinkFile(args[i + 1]); } } // if (string.IsNullOrEmpty(symbolName)) { Console.WriteLine("Error: Symbol Required; please specify a symbol Ex:\"-s ftFunction\""); return(false); } // if output is null set the name to the symbol name if (string.IsNullOrEmpty(datFile) && string.IsNullOrEmpty(output) && !string.IsNullOrEmpty(symbolName)) { output = symbolName + ".dat"; } var symbolPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, symbolName + ".txt"); // if function table not specified attempt to get it from symbol name if (fightFuncTable == null && !string.IsNullOrEmpty(symbolName) && File.Exists(symbolPath)) { fightFuncTable = File.ReadAllLines(symbolPath); } // load link file in mex directory foreach (var f in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory)) { if (Path.GetExtension(f).ToLower().Equals(".link")) { linkFile.LoadLinkFile(f); } } // don't allow both item tables and normal tables if (inputs.Count > 0 && itemInputs.Count > 0) { Console.WriteLine("Only -i or -ii can be used at once, not both"); return(false); } // print instruction and exit if no input if ((inputs.Count == 0 && itemInputs.Count == 0) || args.Length == 0) { Console.WriteLine("No input files were given"); return(false); } // check if symbol name is given if (string.IsNullOrEmpty(symbolName)) { symbolName = "ftFunction"; Console.WriteLine("No symbol name given, defaulting to \"ftFunction\""); } // create output path if one isn't entered if (string.IsNullOrEmpty(output) && string.IsNullOrEmpty(datFile)) { output = Path.Combine(Path.GetDirectoryName(inputs[0]), Path.GetFileName(inputs[0]).Replace(Path.GetExtension(inputs[0]), ".dat")); } // check if output already exists if (File.Exists(output) && !yesOverwrite) { Console.WriteLine(output + " already exists, overwrite? (y/n)"); if (Console.ReadLine().Trim().ToLower() != "y") { return(false); } } // compile functions HSDAccessor function = null; // create file HSDRawFile newfile = null; HSDRawFile injectfile = null; SBM_FighterData ftData = null; // create new file if (!string.IsNullOrEmpty(output)) { newfile = new HSDRawFile(); } // inject existing dat file (or create new one if not found) if (!string.IsNullOrEmpty(datFile)) { injectfile = File.Exists(datFile) ? new HSDRawFile(datFile) : new HSDRawFile(); } // find fighter data if it exists if (injectfile != null && injectfile.Roots.Count > 0 && injectfile.Roots[0].Data is SBM_FighterData ftdata) { ftData = ftdata; } // static param table var param_table = new string[] { "param_ext" }; // single table compile if (itemInputs.Count == 0) { var elfs = CompileElfs(inputs.ToArray(), disableWarnings, clean, opLevel, includes.ToArray(), buildPath, debug, quiet); //foreach (var f in Directory.GetFiles(@"C:\devkitPro\libogc\lib\cube")) //foreach (var f in Directory.GetFiles(@"C:\devkitPro\devkitPPC\powerpc-eabi\lib")) //{ // if (Path.GetExtension(f).Equals(".a")) // elfs.AddRange(FighterFunction.LibArchive.GetElfs(f)); // if (Path.GetExtension(f).Equals(".o")) // elfs.Add(new RelocELF(File.ReadAllBytes(f))); //} //elfs.AddRange(FighterFunction.LibArchive.GetElfs(@"C:\devkitPro\devkitPPC\lib\gcc\powerpc-eabi\10.2.0\libgcc.a")); //elfs.AddRange(FighterFunction.LibArchive.GetElfs(@"C:\Users\ploaj\Desktop\Modlee\libgc\MemCardDemo\libogc.a")); var lelf = GenerateLinkedElf(elfs, fightFuncTable, linkFile, quiet); // check for special attribute symbol if (ftData != null) { foreach (var elf in elfs) { if (elf.SymbolEnumerator.Any(e => e.Symbol.Equals("param_ext"))) { var special_attr = CmdGenerateDatFile.BuildDatFile(elf, param_table); if (special_attr != null && special_attr.Roots.Count > 0 && special_attr["param_ext"] != null) { // Console.WriteLine("Found Param_Ext... adding to fighter data..."); ftData.Attributes2 = special_attr["param_ext"].Data; break; } } } } function = GenerateFunctionData(lelf, linkFile, fightFuncTable, quiet, debug); } else { // item table compile function = new HSDAccessor() { _s = new HSDStruct(4) }; int count = 0; foreach (var f in itemInputs) { count = Math.Max(count, f.Item1 + 1); if (4 + 4 * (f.Item1 + 1) > function._s.Length) { function._s.Resize(4 + 4 * (f.Item1 + 1)); } var elfs = CompileElfs(f.Item2.ToArray(), disableWarnings, clean, opLevel, includes.ToArray(), buildPath, debug, quiet); var lelf = GenerateLinkedElf(elfs, fightFuncTable, linkFile, quiet); // check for special attribute symbol if (ftData != null) { foreach (var elf in elfs) { if (elf.SymbolEnumerator.Any(e => e.Symbol.Equals("param_ext"))) { var special_attr = CmdGenerateDatFile.BuildDatFile(elf, param_table); if (special_attr != null && special_attr.Roots.Count > 0 && special_attr["param_ext"] != null) { // Console.WriteLine("Found Param_Ext... adding to fighter data..."); ftData.Articles.Articles[f.Item1].ParametersExt = special_attr["param_ext"].Data; break; } } } } var relocFunc = GenerateFunctionData(lelf, linkFile, fightFuncTable, quiet, debug); function._s.SetReference(4 + 0x04 * f.Item1, relocFunc); } function._s.SetInt32(0x00, count); } // inject symbol to dat file and save if (function != null) { if (newfile != null) { DatTools.InjectSymbolIntoDat(newfile, symbolName, function); newfile.Save(output); Console.WriteLine("saving " + output + "..."); } if (injectfile != null) { DatTools.InjectSymbolIntoDat(injectfile, symbolName, function); injectfile.Save(datFile); Console.WriteLine("saving " + datFile + "..."); } // We did it boys Console.WriteLine(); Console.WriteLine("Sucessfully Compiled and Converted to DAT!"); return(true); } return(false); }