/// <summary> /// /// </summary> /// <param name="data"></param> private List <Command> GetCommands(HSDStruct str, HashSet <HSDStruct> references = null) { if (references == null) { references = new HashSet <HSDStruct>(); } if (references.Contains(str)) { return(new List <Command>()); } var data = str.GetData(); references.Add(str); var Commands = new List <Command>(); for (int i = 0; i < data.Length;) { var sa = SubactionManager.GetSubaction((byte)(data[i] >> 2)); var cmd = new Command(); foreach (var r in str.References) { if (r.Key >= i && r.Key < i + sa.ByteSize) { if (cmd.Reference != null) { throw new NotSupportedException("Multiple References not supported"); } else { cmd.Reference = r.Value; cmd.ReferenceCommands = GetCommands(cmd.Reference, references); } } } var sub = new byte[sa.ByteSize]; for (int j = 0; j < sub.Length; j++) { sub[j] = data[i + j]; } cmd.Parameters = sa.GetParameters(sub); cmd.Action = sa; Commands.Add(cmd); i += sa.ByteSize; } return(Commands); }
/// <summary> /// /// </summary> /// <param name="output"></param> /// <param name="name"></param> /// <param name="datas"></param> /// <param name="structToFunctionName"></param> private void DecompileGroup(StringBuilder output, string name, HSDStruct datas) { if (structToFunctionName.ContainsKey(datas)) { return; } structToFunctionName.Add(datas, name); output.AppendLine(name); output.AppendLine("{"); using (BinaryReaderExt r = new BinaryReaderExt(new MemoryStream(datas.GetData()))) { byte flag = (byte)(r.ReadByte() >> 2); var cmd = ActionCommon.GetMeleeCMDAction(flag); while (flag != 0) { r.BaseStream.Position -= 1; var size = cmd.ByteSize; var command = r.GetSection(r.Position, size); r.Skip((uint)size); if (flag == 5 || flag == 7) //goto { var re = datas.GetReference <HSDAccessor>((int)r.BaseStream.Position - 4); if (re != null) { if (!tempStructToName.ContainsKey(re._s)) { if (structToFunctionName.ContainsKey(re._s)) { tempStructToName.Add(re._s, structToFunctionName[re._s]); } else { tempStructToName.Add(re._s, name + "_" + ((int)r.BaseStream.Position - 4).ToString("X4")); } } var funcname = tempStructToName[re._s]; output.AppendLine("\t" + (flag == 5 ? "Goto" : "Subroutine") + "(" + funcname + ");"); } } else { output.AppendLine("\t" + DecompileCommand(command)); } if (r.BaseStream.Position >= r.BaseStream.Length) { break; } flag = (byte)(r.ReadByte() >> 2); cmd = ActionCommon.GetMeleeCMDAction(flag); } } output.AppendLine("}"); foreach (var re in datas.References) { DecompileGroup(output, name + "_" + re.Key.ToString("X4"), re.Value); } }
/// <summary> /// /// </summary> /// <param name="data"></param> private List <Command> GetCommands(HSDStruct str, SubactionGroup subGroup, Dictionary <HSDStruct, List <Command> > structToComman = null) { if (subGroup != SubactionGroup.Fighter) { return(new List <Command>()); } if (structToComman == null) { structToComman = new Dictionary <HSDStruct, List <Command> >(); } if (structToComman.ContainsKey(str)) { return(structToComman[str]); } var data = str.GetData(); var Commands = new List <Command>(); structToComman.Add(str, Commands); for (int i = 0; i < data.Length;) { var sa = SubactionManager.GetSubaction(data[i], subGroup); var cmd = new Command(); foreach (var r in str.References) { if (r.Key >= i && r.Key < i + sa.ByteSize) { if (cmd.Reference != null) { throw new NotSupportedException("Multiple References not supported"); } else { if (r.Value != str) // prevent self reference { cmd.Reference = r.Value; cmd.ReferenceCommands = GetCommands(cmd.Reference, subGroup, structToComman); } } } } var sub = new byte[sa.ByteSize]; if (i + sub.Length > data.Length) { break; } for (int j = 0; j < sub.Length; j++) { sub[j] = data[i + j]; } cmd.Parameters = sa.GetParameters(sub); cmd.Action = sa; Commands.Add(cmd); i += sa.ByteSize; if (sa.Code == 0) { break; } } return(Commands); }