/// <summary> /// The get motion. /// </summary> /// <param name="motion"> /// The motion. /// </param> /// <returns> /// The <see cref="InputItemViewModel"/>. /// </returns> /// <remarks>For some reason 360's and 720's won't work with this. They have no "motion" in the bcm.</remarks> private static InputItemViewModel GetMotion(InputMotionEntry motion) { switch (motion.DirectionName) { case "DOWN": return(new InputItemViewModel { Direction = InputCommandModel.DirectionStateEnum.Down }); case "FORWARD": return(new InputItemViewModel { Direction = InputCommandModel.DirectionStateEnum.Forward }); case "BACK": return(new InputItemViewModel { Direction = InputCommandModel.DirectionStateEnum.Back }); case "UP": return(new InputItemViewModel { Direction = InputCommandModel.DirectionStateEnum.Up }); case "DOWN, BACK": return(new InputItemViewModel { Direction = InputCommandModel.DirectionStateEnum.DownBack }); case "DOWN, FORWARD": return(new InputItemViewModel { Direction = InputCommandModel.DirectionStateEnum.DownForward }); case "UP, FORWARD": return(new InputItemViewModel { Direction = InputCommandModel.DirectionStateEnum.UpForward }); case "UP, BACK": return(new InputItemViewModel { Direction = InputCommandModel.DirectionStateEnum.UpBack }); case "NEUTRAL": return(new InputItemViewModel { Direction = InputCommandModel.DirectionStateEnum.Neutral }); default: return(null); } }
public static BCMFile FromFilename(string filename) { using (var fs = File.OpenRead(filename)) using (var tracker = new TrackingStream(fs)) using (var inFile = new BinaryReader(tracker)) { AELogger.Log(AELogger.O_SEPARATOR, false); var bcm = new BCMFile(); tracker.SetLabel("Header"); var s = new string(inFile.ReadChars(4)); //Console.WriteLine("{0} - {1:X} bytes",s,inFile.BaseStream.Length); if (s != "#BCM") { throw new Exception("This is not a valid BCM File!"); } tracker.IgnoreBytes(12); inFile.BaseStream.Seek(16); var ChargeCount = inFile.ReadUInt16(); var InputCount = inFile.ReadUInt16(); var MoveCount = inFile.ReadUInt16(); var CancelListCount = inFile.ReadUInt16(); for (int i = 0; i < CancelListCount; i++) { bcm.CancelLists.Add(new CancelList()); } var ChargeOffset = inFile.ReadUInt32(); var ChargeNamesOffset = inFile.ReadUInt32(); var InputOffset = inFile.ReadUInt32(); var InputNamesOffset = inFile.ReadUInt32(); var MoveOffset = inFile.ReadUInt32(); var MoveNamesOffset = inFile.ReadUInt32(); var CancelListOffset = inFile.ReadUInt32(); var CancelListNamesOffset = inFile.ReadUInt32(); #region Read Charges AELogger.Log("Header done, reading charges"); tracker.SetLabel("Charges"); for (int i = 0; i < ChargeCount; i++) { var charge = new Charge(); inFile.BaseStream.Seek(ChargeNamesOffset + i * 4); inFile.BaseStream.Seek(inFile.ReadUInt32()); charge.Name = inFile.ReadCString(); inFile.BaseStream.Seek(ChargeOffset + i * 16); charge.Input = (Input)inFile.ReadUInt16(); Util.LogUnkEnumFlags(charge.Input, "charge", charge.Name); charge.Unknown1 = inFile.ReadUInt16(); charge.MoveFlags = (MoveFlags)inFile.ReadUInt16(); Util.LogUnkEnumFlags(charge.MoveFlags, "charge", charge.Name); charge.Frames = inFile.ReadUInt32(); charge.Unknown3 = inFile.ReadUInt16(); charge.StorageIndex = inFile.ReadUInt32(); //Console.WriteLine(charge); bcm.Charges.Add(charge); } #endregion #region Read Inputs AELogger.Log("charges done, reading motions"); tracker.SetLabel("Inputs"); bcm.InputMotions.Add(InputMotion.NONE); for (int i = 0; i < InputCount; i++) { var inputMotion = new InputMotion("tmp"); inFile.BaseStream.Seek(InputNamesOffset + i * 4); inFile.BaseStream.Seek(inFile.ReadUInt32()); inputMotion.Name = inFile.ReadCString(); //Console.WriteLine(inputMotion.Name); inFile.BaseStream.Seek(InputOffset + i * 0xC4); var cnt = inFile.ReadUInt32(); for (int j = 0; j < cnt; j++) { var entry = new InputMotionEntry(); entry.Type = (InputType)inFile.ReadUInt16(); Util.LogUnkEnum(entry.Type, "motion", inputMotion.Name, j); entry.Buffer = inFile.ReadUInt16(); System.UInt16 a = inFile.ReadUInt16(); if (entry.Type == InputType.CHARGE) { entry.Charge = bcm.Charges[a]; } entry.Input = (Input)a; Util.LogUnkEnum(entry.Input, "motion", inputMotion.Name, j); entry.MoveFlags = (MoveFlags)inFile.ReadUInt16(); Util.LogUnkEnumFlags(entry.MoveFlags, "motion", inputMotion.Name, j); entry.Flags = (InputReqType)inFile.ReadUInt16(); Util.LogUnkEnum(entry.Flags, "motion", inputMotion.Name, j); entry.Requirement = inFile.ReadUInt16(); inputMotion.Entries.Add(entry); //Console.WriteLine(entry); } tracker.IgnoreBytes(12 * (16 - cnt)); bcm.InputMotions.Add(inputMotion); } #endregion #region Read Moves AELogger.Log("motions done, reading moves"); tracker.SetLabel("Moves"); for (int i = 0; i < MoveCount; i++) { var move = new Move(); inFile.BaseStream.Seek(MoveNamesOffset + i * 4); inFile.BaseStream.Seek(inFile.ReadUInt32()); move.Name = inFile.ReadCString(); //Console.WriteLine(move.Name); inFile.BaseStream.Seek(MoveOffset + i * 0x54); move.Input = (Input)inFile.ReadUInt16(); Util.LogUnkEnumFlags(move.Input, "move", move.Name); move.MoveFlags = (MoveFlags)inFile.ReadUInt16(); Util.LogUnkEnumFlags(move.MoveFlags, "move", move.Name); move.PositionRestriction = (PositionRestriction)inFile.ReadUInt16(); Util.LogUnkEnum(move.PositionRestriction, "move", move.Name); move.Restriction = (MoveRestriction)inFile.ReadUInt16(); Util.LogUnkEnumFlags(move.MoveFlags, "move", move.Name); move.Unk1 = inFile.ReadUInt16(); move.StateRestriction = (Move.MoveStateRestriction)inFile.ReadUInt16(); Util.LogUnkEnum(move.StateRestriction, "move", move.Name); move.MiscRestriction = (Move.MoveMiscRestriction)inFile.ReadUInt32(); Util.LogUnkEnum(move.MiscRestriction, "move", move.Name); move.UltraRestriction = (Move.MoveUltraRestriction)inFile.ReadUInt32(); Util.LogUnkEnum(move.UltraRestriction, "move", move.Name); move.PositionRestrictionDistance = inFile.ReadSingle(); move.EXRequirement = inFile.ReadInt16(); move.EXCost = inFile.ReadInt16(); move.UltraRequirement = inFile.ReadInt16(); move.UltraCost = inFile.ReadInt16(); var index = inFile.ReadInt32(); if (index != -1 && index < bcm.InputMotions.Count) { move.InputMotion = bcm.InputMotions[index + 1]; } else { move.InputMotion = InputMotion.NONE; } move.ScriptIndex = inFile.ReadInt32(); /* AI data */ move.Features = (MoveFeatureFlags)inFile.ReadUInt32(); Util.LogUnkEnumFlags(move.Features, "move", move.Name); move.CpuMinRange = inFile.ReadSingle(); move.CpuMaxRange = inFile.ReadSingle(); move.Unk2 = inFile.ReadUInt32(); move.Unk3 = inFile.ReadUInt16(); move.CpuPassiveMove = inFile.ReadUInt16(); move.CpuCounterMove = inFile.ReadUInt16(); move.CpuVsStand = inFile.ReadUInt16(); move.CpuVsCrouch = inFile.ReadUInt16(); move.CpuVsAir = inFile.ReadUInt16(); move.CpuVsDown = inFile.ReadUInt16(); move.CpuVsStunned = inFile.ReadUInt16(); move.CpuProbeMove = inFile.ReadUInt16(); move.CpuVsVeryClose = inFile.ReadUInt16(); move.CpuVsClose = inFile.ReadUInt16(); move.CpuVsMidRange = inFile.ReadUInt16(); move.CpuVsFar = inFile.ReadUInt16(); move.CpuVsVeryFar = inFile.ReadUInt16(); bcm.Moves.Add(move); } #endregion #region ReadCancels AELogger.Log("moves done, reading cancels"); tracker.SetLabel("Cancels"); for (int i = 0; i < CancelListCount; i++) { var cl = bcm.CancelLists[i]; inFile.BaseStream.Seek(CancelListNamesOffset + i * 4); inFile.BaseStream.Seek(inFile.ReadUInt32()); cl.Name = inFile.ReadCString(); //Console.WriteLine(cl.Name); inFile.BaseStream.Seek(CancelListOffset + i * 0x8); var count = inFile.ReadUInt32(); var off = inFile.ReadUInt32(); inFile.BaseStream.Seek(off - 8, SeekOrigin.Current); for (int j = 0; j < count; j++) { var x = inFile.ReadInt16(); //Console.WriteLine(x); if (x == -1) { cl.Moves.Add(Move.NULL); } else if (x < bcm.Moves.Count) { cl.Moves.Add(bcm.Moves[x]); } else { AELogger.Log("WARNING: Out of range move detected!!!!"); } } } AELogger.Log("cancels done"); #endregion ////Console.WriteLine(tracker.Report()); AELogger.Log(AELogger.O_SEPARATOR, false); return(bcm); } }