/// <summary>
        ///
        /// </summary>
        private void SaveFighterAnimationFile()
        {
            // rendering files not loaded
            if (string.IsNullOrEmpty(AJFilePath))
            {
                return;
            }

            // make sure okay to overwrite
            if (MessageBox.Show($"Is it okay to overwrite {AJFilePath}?", "Save Animation File Changes?", MessageBoxButtons.YesNoCancel) != DialogResult.Yes)
            {
                return;
            }

            // collect used symbols from all actions
            var usedSymbols = AllActions.Select(e => e.Symbol);

            // generate new aj file
            Dictionary <string, Tuple <int, int> > animOffsets = new Dictionary <string, Tuple <int, int> >();

            using (MemoryStream ajBuffer = new MemoryStream())
                using (BinaryWriterExt w = new BinaryWriterExt(ajBuffer))
                {
                    // collect used symbols
                    foreach (var sym in usedSymbols)
                    {
                        if (sym != null)
                        {
                            if (SymbolToAnimation.ContainsKey(sym) && !animOffsets.ContainsKey(sym))
                            {
                                // write animation
                                var anim = SymbolToAnimation[sym];
                                animOffsets.Add(sym, new Tuple <int, int>((int)ajBuffer.Position, anim.Length));
                                w.Write(anim);
                                w.Align(0x20, 0xFF);
                            }
                            else
                            if (!animOffsets.ContainsKey(sym))
                            {
                                // animation not found
                                MessageBox.Show($"\"{sym}\" animation not found", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                animOffsets.Add(sym, new Tuple <int, int>(0, 0));
                            }
                        }
                    }

                    // dump to file
                    File.WriteAllBytes(AJFilePath, ajBuffer.ToArray());
                }


            int index = 0;

            foreach (var a in AllActions)
            {
                // don't write subroutines
                if (a.Subroutine)
                {
                    continue;
                }

                // get embedded script
                var ftcmd = new SBM_FighterCommand();
                ftcmd._s = _node.Accessor._s.GetEmbeddedStruct(0x18 * index, ftcmd.TrimmedSize);

                // update symbol name
                ftcmd.Name = a.Symbol;

                if (a.Symbol == null)
                {
                    continue;
                }

                // offset
                var ofst = animOffsets[a.Symbol];

                // update action offset and size
                a.AnimOffset = ofst.Item1;
                a.AnimSize   = ofst.Item2;

                // update file offset and size
                ftcmd.AnimationOffset = a.AnimOffset;
                ftcmd.AnimationSize   = a.AnimSize;

                // resize if needed
                if (_node.Accessor._s.Length <= 0x18 * index + 0x18)
                {
                    _node.Accessor._s.Resize(0x18 * index + 0x18);
                }

                // update script
                _node.Accessor._s.SetEmbededStruct(0x18 * index, ftcmd._s);
                index++;
            }

            MainForm.Instance.SaveDAT();
        }
Exemple #2
0
        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_FighterCommand> SubActions = new List <SBM_FighterCommand>();
                    Dictionary <SBM_FighterCommand, string> subActionToScript = new Dictionary <SBM_FighterCommand, 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_FighterCommand subaction = new SBM_FighterCommand();
                            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.FighterCommandTable = new SBM_FighterCommandTable();

                    ActionCompiler.LinkStructs();

                    ftData.FighterCommandTable.Commands = SubActions.ToArray();

                    Console.WriteLine("recompiled count " + ftData.FighterCommandTable._s.GetSubStructs().Count);
                }
            }

            file.Save(filepath);
        }