コード例 #1
0
        public void ReadBCMData()
        {
            int off = 0x8;
            if (PlayerIndex == 1)
                off = 0xC;
            //06A7DF0
            var InputBufferOffset = (int)Util.Memory.ReadInt((int)Util.Memory.ReadInt(0x400000 + 0x6A7DEC) + off);
            int BCM = (int)Util.Memory.ReadInt(InputBufferOffset + 0x8);
            if (BCM != bcm_off && BCM != 0)
            {
                //Gotta load BCM
                var tmpfile = File.Create(System.IO.Path.GetTempPath() + "/tmp.bcm", 0x9000);
                var tmparr = Util.Memory.ReadAOB(BCM, 0x9000);
                tmpfile.Write(tmparr, 0, tmparr.Length);
                tmpfile.Close();
                bcm = BCMFile.FromFilename(System.IO.Path.GetTempPath() + "/tmp.bcm");
                bcm_off = BCM;
            }
            //Not in a match
            if (BCM == 0)
                return;
            var chargeStatus = (int)Util.Memory.ReadInt(InputBufferOffset + 0x1594);
            ActiveCancelLists.Clear();

            var InputBufferStart = (int)Util.Memory.ReadInt(0x400000 + 0x6A7DF0) + 0x48;
            var InputBufferCurrent = (int)Util.Memory.ReadInt(InputBufferStart + 0x400 * 0xC + 4);
            var InputBufferCurrentAlt = (int)Util.Memory.ReadInt(InputBufferStart - 0x1C) % 0x400;
            InputBufferCurrent = InputBufferCurrentAlt;
            var i = 0;
            while (i < 0x10)
            {
                var test = (int)Util.Memory.ReadInt(InputBufferOffset + 0x147C + i++ * 0x10);
                if (test != -1)
                    if (bcm.CancelLists.Count > test)
                        ActiveCancelLists.Add(bcm.CancelLists[test].Name);
                    else
                        ActiveCancelLists.Add(test.ToString());


            }

            //InputBuffer.Clear();
            if(InputBuffer.Count == 0x400)
            {
                InputBuffer.RemoveAt(0x400-1);
            }
            var inputsToRead = 0x400-InputBuffer.Count();

            var InputBufferIndex = (int)Util.Memory.ReadInt(InputBufferOffset + 0x1414);
            var tmp = Util.Memory.ReadInt(InputBufferStart + 0xC * InputBufferCurrent);
            InputBuffer.Insert(0,(FighterState.Input)tmp);
            
        }
コード例 #2
0
ファイル: BCMFile.cs プロジェクト: gaolijunGit/ssf4ae-tools
        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);
                    }
        }
コード例 #3
0
ファイル: BCMFile.cs プロジェクト: gaolijunGit/ssf4ae-tools
        public static void ToFilename(string filename, BCMFile bcm)
        {
            using (var ms = new MemoryStream())
                using (var inFile = new BinaryWriter(ms))
                {
                    //Header
                    inFile.Write(1296253475);
                    inFile.Write(2686974);
                    inFile.Write(65537);
                    inFile.Write(0);
                    inFile.Write((ushort)bcm.Charges.Count());
                    inFile.Write((ushort)(bcm.InputMotions.Count() - 1));
                    inFile.Write((ushort)bcm.Moves.Count());
                    inFile.Write((ushort)bcm.CancelLists.Count());
                    //TODO WRITE OFFSETS
                    int offsets = (int)inFile.BaseStream.Position;
                    inFile.Write(0);
                    inFile.Write(0);

                    inFile.Write(0);
                    inFile.Write(0);

                    inFile.Write(0);
                    inFile.Write(0);

                    inFile.Write(0);
                    inFile.Write(0);
                    int ChargeOffset = (int)inFile.BaseStream.Position;
                    if (bcm.Charges.Count == 0)
                    {
                        ChargeOffset = 0;
                    }
                    foreach (Charge c in bcm.Charges)
                    {
                        inFile.Write((ushort)c.Input);
                        inFile.Write(c.Unknown1);
                        inFile.Write((ushort)c.MoveFlags);
                        inFile.Write(c.Frames);
                        inFile.Write(c.Unknown3);
                        inFile.Write(c.StorageIndex);
                    }
                    int ChargeNamesOffset = (int)inFile.BaseStream.Position;
                    if (bcm.Charges.Count == 0)
                    {
                        ChargeNamesOffset = 0;
                    }
                    foreach (Charge c in bcm.Charges)
                    {
                        inFile.Write(0);
                    }
                    int InputOffset = (int)inFile.BaseStream.Position;
                    foreach (InputMotion i in bcm.InputMotions)
                    {
                        if (i == InputMotion.NONE)
                        {
                            continue;
                        }
                        inFile.Write(i.Entries.Count());
                        foreach (InputMotionEntry entry in i.Entries)
                        {
                            inFile.Write((ushort)entry.Type);
                            inFile.Write((ushort)entry.Buffer);
                            //if (entry.Type == InputType.CHARGE)
                            //    inFile.Write((ushort)bcm.Charges.IndexOf(entry.Charge));
                            inFile.Write((ushort)entry.Input);
                            inFile.Write((ushort)entry.MoveFlags);
                            inFile.Write((ushort)entry.Flags);
                            inFile.Write((ushort)entry.Requirement);
                        }
                        for (int j = i.Entries.Count; j < 16; j++)
                        {
                            inFile.Write(0);
                            inFile.Write(0);
                            inFile.Write(0);
                        }
                    }
                    int InputNamesOffset = (int)inFile.BaseStream.Position;
                    foreach (InputMotion c in bcm.InputMotions)
                    {
                        if (c == InputMotion.NONE)
                        {
                            continue;
                        }
                        inFile.Write(0);
                    }
                    int MoveOffset = (int)inFile.BaseStream.Position;
                    foreach (Move m in bcm.Moves)
                    {
                        inFile.Write((ushort)m.Input);
                        inFile.Write((ushort)m.MoveFlags);
                        inFile.Write((ushort)m.PositionRestriction);
                        inFile.Write((ushort)m.Restriction);
                        inFile.Write(m.Unk1);
                        inFile.Write((ushort)m.StateRestriction);
                        inFile.Write((uint)m.MiscRestriction);
                        inFile.Write((uint)m.UltraRestriction);
                        inFile.Write(m.PositionRestrictionDistance);
                        inFile.Write((short)m.EXRequirement);
                        inFile.Write((short)m.EXCost);
                        inFile.Write((short)m.UltraRequirement);
                        inFile.Write((short)m.UltraCost);
                        inFile.Write(bcm.InputMotions.IndexOf(m.InputMotion) - 1);
                        inFile.Write(m.Script.Index);

                        /* AI data */
                        inFile.Write((uint)m.Features);
                        inFile.Write(m.CpuMinRange);
                        inFile.Write(m.CpuMaxRange);
                        inFile.Write(m.Unk2);
                        inFile.Write(m.Unk3);
                        inFile.Write(m.CpuPassiveMove);
                        inFile.Write(m.CpuCounterMove);
                        inFile.Write(m.CpuVsStand);
                        inFile.Write(m.CpuVsCrouch);
                        inFile.Write(m.CpuVsAir);
                        inFile.Write(m.CpuVsDown);
                        inFile.Write(m.CpuVsStunned);
                        inFile.Write(m.CpuProbeMove);
                        inFile.Write(m.CpuVsVeryClose);
                        inFile.Write(m.CpuVsClose);
                        inFile.Write(m.CpuVsMidRange);
                        inFile.Write(m.CpuVsFar);
                        inFile.Write(m.CpuVsVeryFar);
                    }
                    int MovesNameOffset = (int)inFile.BaseStream.Position;
                    foreach (Move m in bcm.Moves)
                    {
                        inFile.Write(0);
                    }
                    int CancelListOffset = (int)inFile.BaseStream.Position;
                    int off = bcm.CancelLists.Count * 12;
                    foreach (CancelList cl in bcm.CancelLists)
                    {
                        inFile.Write(cl.Moves.Count);
                        inFile.Write(off);
                        off = off - 8 + cl.Moves.Count * 2;
                    }
                    int CancelListNameOffset = (int)inFile.BaseStream.Position;
                    foreach (CancelList cl in bcm.CancelLists)
                    {
                        inFile.Write(0);
                    }
                    foreach (CancelList cl in bcm.CancelLists)
                    {
                        foreach (Move m in cl.Moves)
                        {
                            inFile.Write((short)bcm.Moves.IndexOf(m));
                        }
                    }
                    //Names Time!
                    List <string> strings = new List <string>();
                    foreach (Charge tmp in bcm.Charges)
                    {
                        strings.Add(tmp.Name);
                    }
                    Util.writeStringTable(inFile, ChargeNamesOffset, strings);

                    strings.Clear();
                    foreach (InputMotion tmp in bcm.InputMotions)
                    {
                        if (tmp == InputMotion.NONE)
                        {
                            continue;
                        }
                        strings.Add(tmp.Name);
                    }
                    Util.writeStringTable(inFile, InputNamesOffset, strings);

                    strings.Clear();
                    foreach (Move tmp in bcm.Moves)
                    {
                        strings.Add(tmp.Name);
                    }
                    Util.writeStringTable(inFile, MovesNameOffset, strings);

                    strings.Clear();
                    foreach (CancelList tmp in bcm.CancelLists)
                    {
                        strings.Add(tmp.Name);
                    }
                    Util.writeStringTable(inFile, CancelListNameOffset, strings);

                    inFile.Seek((int)offsets, SeekOrigin.Begin);
                    inFile.Write(ChargeOffset);
                    inFile.Write(ChargeNamesOffset);

                    inFile.Write(InputOffset);
                    inFile.Write(InputNamesOffset);

                    inFile.Write(MoveOffset);
                    inFile.Write(MovesNameOffset);

                    inFile.Write(CancelListOffset);
                    inFile.Write(CancelListNameOffset);

                    using (var fs = File.Create(filename))
                    {
                        ms.WriteTo(fs);
                    }
                }
        }
コード例 #4
0
ファイル: BACFile.cs プロジェクト: dantarion/ssf4ae-tools
        private static void writeScript(BACFile bac, BCMFile bcm, BinaryWriter outFile, Script script)
        {
            outFile.Write(script.FirstHitboxFrame);
            outFile.Write(script.LastHitboxFrame);
            outFile.Write(script.IASAFrame);
            outFile.Write(script.TotalFrames);

            outFile.Write(script.UnknownFlags1);
            outFile.Write(script.UnknownFlags2);
            outFile.Write(script.UnknownFlags3);
            outFile.Write((ushort)script.CommandLists.Where(x => x.Count > 0).Count());
            outFile.Write(0x18);

            int baseOff = (int)outFile.BaseStream.Position;
            var clists = script.CommandLists.Where(x => x.Count > 0).ToList();
            for (int i = 0; i < clists.Count; i++)
            {
                dynamic cl = clists[i];
                outFile.Write((ushort)cl.Type);
                outFile.Write((ushort)cl.Count);
                outFile.Write(0);
                outFile.Write(0);
            }
            for (int i = 0; i < clists.Count; i++)
            {
                dynamic cl = clists[i];
                int frameoff = (int)outFile.BaseStream.Position - baseOff - 12 * i;
                outFile.Seek(0, SeekOrigin.End);
                foreach (BaseCommand cmd in cl)
                {
                    outFile.Write((ushort)cmd.StartFrame);
                    outFile.Write((ushort)cmd.EndFrame);
                }
                int dataoff = (int)outFile.BaseStream.Position - baseOff - 12 * i;
                outFile.BaseStream.Seek(baseOff + 12 * i + 4);
                outFile.Write(frameoff);
                outFile.Write(dataoff);
                outFile.Seek(0, SeekOrigin.End);
                foreach (BaseCommand cmd in cl)
                {
                    if (cmd is FlowCommand)
                    {
                        var flow = cmd as FlowCommand;
                        outFile.Write((short)flow.Type);
                        outFile.Write((ushort)flow.Input);
                        if (flow.TargetScript != null && flow.TargetScript != Script.NullScript)
                            outFile.Write((short)flow.TargetScript.Index);
                        else
                            outFile.Write((short)-1);
                        outFile.Write(flow.TargetFrame);
                    }
                    else if (cmd is AnimationCommand)
                    {
                        var animation = cmd as AnimationCommand;
                        outFile.Write(animation.Animation);
                        outFile.Write((byte)animation.Type);
                        outFile.Write((byte)animation.Flags);
                        outFile.Write(animation.FromFrame);
                        outFile.Write(animation.ToFrame);
                    }
                    else if (cmd is TransitionCommand)
                    {
                        var transition = (TransitionCommand)cmd;
                        outFile.Write(transition.Flag1);
                        outFile.Write(transition.Flag2);
                        outFile.Write(transition.Float1);
                        outFile.Write(transition.Float2);
                        outFile.Write(transition.Float3);
                        outFile.Write(transition.Float4);
                        outFile.Write(transition.Float5);
                        outFile.Write(transition.Float6);
                    }
                    else if (cmd is StateCommand)
                    {
                        var state = cmd as StateCommand;
                        outFile.Write((uint)state.Flags);
                        outFile.Write((uint)state.UnknownFlags2);
                    }
                    else if (cmd is SpeedCommand)
                    {
                        outFile.Write((cmd as SpeedCommand).Multiplier);
                    }
                    else if (cmd is PhysicsCommand)
                    {
                        var physics = cmd as PhysicsCommand;
                        outFile.Write(physics.VelX);
                        outFile.Write(physics.VelY);
                        outFile.Write((uint)physics.Unk01);
                        outFile.Write((uint)physics.PhysicsFlags);
                        outFile.Write(physics.AccX);
                        outFile.Write(physics.AccY);
                        outFile.Write((ulong)physics.Unk02);
                    }
                    else if (cmd is HurtNodeCommand)
                    {
                        /*
                         * case CommandListType.INVINC:
                            var invinc = cmd as HurtNodeCommand;
                            invinc.Flags = (HurtNodeCommand.VulnerabilityFlags)inFile.ReadUInt16();
                            invinc.Location = inFile.ReadUInt16();
                            invinc.Location = inFile.ReadUInt16();
                            invinc.Unk02 = inFile.ReadUInt16();
                            invinc.Unk03 = inFile.ReadUInt16();
                            invinc.Unk04 = inFile.ReadUInt16();
                            invinc.Unk05 = inFile.ReadUInt16();
                            invinc.Unk06 = inFile.ReadUInt16();
                            break;
                         */
                        var invinc = cmd as HurtNodeCommand;
                        outFile.Write((uint)invinc.Flags);
                        outFile.Write((uint)invinc.Location);
                        outFile.Write(invinc.Unk02);
                        outFile.Write(invinc.Unk03);
                        outFile.Write(invinc.Unk04);
                        outFile.Write(invinc.Unk05);
                    }
                    else if (cmd is CancelCommand)
                    {
                        var cancel = cmd as CancelCommand;
                        outFile.Write((int)cancel.Condition);
                        if (cancel.CancelList != null)
                            outFile.Write((int)bcm.CancelLists.IndexOf(cancel.CancelList));
                        else
                            outFile.Write(-1);
                    }
                    else if (cmd is HurtboxCommand)
                    {
                        var hurt = cmd as HurtboxCommand;
                        outFile.Write(hurt.X);
                        outFile.Write(hurt.Y);
                        outFile.Write(hurt.Rotation);
                        outFile.Write(hurt.Width);
                        outFile.Write(hurt.Height);
                        outFile.Write(hurt.FloatUnknown);
                        outFile.Write(hurt.Unknown1);
                        outFile.Write((ushort)hurt.Unused);
                        outFile.Write(hurt.Unknown4);
                        outFile.Write(hurt.Unknown5);
                    }
                    else if (cmd is EtcCommand)
                    {
                        var etc = cmd as EtcCommand;
                        outFile.Write((ushort)etc.Type);
                        outFile.Write((ushort)etc.ShortParam);
                        foreach (int s in etc.RawParams)
                            outFile.Write(s);
                    }
                    else if (cmd is HitboxCommand)
                    {
                        var hit = cmd as HitboxCommand;
                        outFile.Write(hit.X);
                        outFile.Write(hit.Y);
                        outFile.Write(hit.Rotation);
                        outFile.Write(hit.Width);
                        outFile.Write(hit.Height);
                        outFile.Write((Int32)hit.Unused);
                        outFile.Write(hit.ID);
                        outFile.Write(hit.Juggle);
                        outFile.Write((byte)hit.Type);
                        outFile.Write((byte)hit.HitLevel);
                        outFile.Write((ushort)hit.HitFlags);
                        outFile.Write(hit.UnknownByte1);
                        outFile.Write(hit.UnknownByte2);
                        outFile.Write(hit.Hits);
                        outFile.Write(hit.JugglePotential);
                        outFile.Write(hit.JuggleIncrement);
                        outFile.Write(hit.JuggleIncrementLimit);
                        outFile.Write(hit.HitboxEffect);
                        outFile.Write(hit.UnknownByte3);
                        outFile.Write((short)hit.Unused2);
                        outFile.Write((int)hit.HitboxDataSet.Index);
                    }
                    else if (cmd is TargetLockCommand)
                    {
                        var damageAnim = (TargetLockCommand)cmd;
                        outFile.Write((Int32)damageAnim.Type);
                        outFile.Write((Int32)damageAnim.DmgScript.Index);
                        outFile.Write(damageAnim.Unknown2);
                        outFile.Write(damageAnim.Unknown3);
                    }
                    else if (cmd is SfxCommand)
                    {
                        var sfx = (SfxCommand)cmd;
                        outFile.Write((UInt16)sfx.Type);
                        outFile.Write(sfx.Sound);
                        outFile.Write(sfx.Unknown1);
                        outFile.Write(sfx.Unknown2);
                        outFile.Write(sfx.Unknown3);
                    }
                    else
                    {
                        outFile.Write(cmd.Raw);
                    }
                }

            }
        }
コード例 #5
0
ファイル: BACFile.cs プロジェクト: dantarion/ssf4ae-tools
        public static BACFile FromFilename(string name, BCMFile bcm)
        {
            using (var fs = File.OpenRead(name))
            using (var tracker = new TrackingStream(fs))
            using (var inFile = new BinaryReader(tracker))
            {
                AELogger.Log(AELogger.O_SEPARATOR, false);
                tracker.SetLabel("Header");

                if (new String(inFile.ReadChars(4)) != "#BAC")
                    throw new IOException("Not a valid BAC file");
                tracker.IgnoreBytes(8);
                inFile.BaseStream.Seek(12);

                ushort ScriptCount = inFile.ReadUInt16();
                ushort VFXScriptCount = inFile.ReadUInt16();
                uint HitboxTableSize = inFile.ReadUInt32();
                int ScriptOffset = inFile.ReadInt32();
                int VFXScriptOffset = inFile.ReadInt32();
                int ScriptNameOffset = inFile.ReadInt32();
                int VFXScriptNameOffset = inFile.ReadInt32();
                int HitboxTableOffset = inFile.ReadInt32();

                AELogger.Log("Header done, reading floats");

                var bac = new BACFile();
                for (int i = 0; i < 0x1c; i++)
                {
                    var list = new ObservableCollection<float>();
                    for (int j = 0; j < 6; j++)
                    {
                        list.Add(inFile.ReadSingle());
                    }
                    bac.UnknownFloatData.Add(list);
                }
                AELogger.Log("floats done, reading scripts");

                for (int i = 0; i < ScriptCount; i++)
                    bac.Scripts.Add(new Script(i));
                for (int i = 0; i < VFXScriptCount; i++)
                    bac.VFXScripts.Add(new Script(i));
                for (int i = 0; i < HitboxTableSize; i++)
                    bac.HitboxTable.Add(new HitBoxDataset(i));

                //Link BCM
                if (bcm != null)
                {
                    foreach (BCM.Move move in bcm.Moves)
                        if (move.ScriptIndex != -1)
                            move.Script = bac.Scripts[move.ScriptIndex];
                }
                //Read Scripts
                readScripts(inFile, bac.Scripts, bcm, ScriptCount, ScriptOffset, ScriptNameOffset, bac);
                readScripts(inFile, bac.VFXScripts, bcm, VFXScriptCount, VFXScriptOffset, VFXScriptNameOffset, bac);
                AELogger.Log("scripts done, reading hitboxtable");
                //Read Hitbox Table
                for (int i = 0; i < HitboxTableSize; i++)
                {
                    tracker.SetLabel("HitboxTable#" + i.ToString());
                    inFile.BaseStream.Seek(HitboxTableOffset + i*4);
                    inFile.BaseStream.Seek(inFile.ReadUInt32());
                    if (inFile.BaseStream.Position == 0)
                    {
                        continue;
                    }
                    var dataset = bac.HitboxTable[i];
                    LoadedHitBoxCount = i;
                    for (int j = 0; j < 12; j++)
                    {
                        HitBoxData data = new HitBoxData(j);
                        dataset.Data.Add(data);
                        data.Damage = inFile.ReadInt16();
                        data.Stun = inFile.ReadInt16();
                        data.Effect = (HitBoxData.HitBoxEffect)inFile.ReadUInt16();
                        Util.LogUnkEnum(data.Effect, "Hitbox #" + dataset.Index, "hitboxdataset", j);

                        var index = inFile.ReadInt16() + HitBoxData.getIndexOffset(data.Effect);
                        if (index > -1)
                            data.OnHit = bac.Scripts.Where(x => x.Index == index).First();
                        else
                        {
                            data.OnHit = new Script(index);
                            if (index <= -1)
                            {
                                AELogger.Log("negative index " + index + " in hitboxdata #" + i);
                            }
                        }

                        data.SelfHitstop = inFile.ReadUInt16();
                        data.SelfShaking = inFile.ReadUInt16();
                        data.TgtHitstop = inFile.ReadUInt16();
                        data.TgtShaking = inFile.ReadUInt16();
                        data.HitGFX = inFile.ReadInt16();
                        data.Unknown1 = inFile.ReadInt32();
                        data.Unused = (Unused16)inFile.ReadInt16();
                        data.HitGFX2 = inFile.ReadInt16();
                        data.Unused2 = (Unused32)inFile.ReadInt32();
                        data.Unused3 = (Unused16)inFile.ReadInt16();
                        data.HitSFX = inFile.ReadInt16();
                        data.HitSFX2 = inFile.ReadInt16();
                        data.TgtSFX = inFile.ReadInt16();

                        data.ArcadeScore = inFile.ReadUInt16();
                        data.SelfMeter = inFile.ReadInt16();
                        data.TgtMeter = inFile.ReadInt16();
                        data.JuggleStart = inFile.ReadInt16();
                        data.TgtAnimTime = inFile.ReadInt16();
                        data.MiscFlag = (HitBoxData.MiscFlags)inFile.ReadInt32();
                        data.VelX = inFile.ReadSingle();
                        data.VelY = inFile.ReadSingle();

                        data.VelZ = inFile.ReadSingle();
                        data.PushbackDist = inFile.ReadSingle();
                        data.AccX = inFile.ReadSingle();
                        data.AccY = inFile.ReadSingle();
                        data.AccZ = inFile.ReadSingle();
                    }
                }
                AELogger.Log("hitbox done");
                List<HitBoxDataset> nullHitboxData = bac.HitboxTable.Where(x => x.Data.Count() == 0).ToList();
                foreach (HitBoxDataset tmp in nullHitboxData)
                    bac.HitboxTable.Remove(tmp);
                FilterScripts(bac.Scripts);
                FilterScripts(bac.VFXScripts);
                AELogger.Log(AELogger.O_SEPARATOR, false);

                return bac;
            }
        }
コード例 #6
0
ファイル: BACFile.cs プロジェクト: dantarion/ssf4ae-tools
        private static void readScripts(BinaryReader inFile, ObservableCollection<Script> list, BCMFile bcm, int Count, int Offset, int NameOffset, BACFile bac)
        {
            for (int i = 0; i < Count; i++)
            {
                (inFile.BaseStream as TrackingStream).SetLabel("Script#" + i.ToString());

                inFile.BaseStream.Seek(NameOffset + (i) * 4);
                var stringOffset = inFile.ReadUInt32();

                inFile.BaseStream.Seek(Offset + (i) * 4);
                var dataOffset = inFile.ReadUInt32();
                if (dataOffset == 0)
                    //This is a null entry in the table, we remove it later after reading all the Scripts
                    continue;

                //Read in the Name
                if (stringOffset != 0)
                {
                    inFile.BaseStream.Seek(stringOffset);
                    list[i].Name = inFile.ReadCString();
                }
                else
                    list[i].Name = "NULL";
                //Read in the script!
                inFile.BaseStream.Seek(dataOffset);
                readScript(inFile, list[i], bcm, bac);
            }
        }
コード例 #7
0
ファイル: BACFile.cs プロジェクト: dantarion/ssf4ae-tools
        private static void readScript(BinaryReader inFile, Script script, BCMFile bcm, BACFile bac)
        {
            script.FirstHitboxFrame = inFile.ReadUInt16();
            script.LastHitboxFrame = inFile.ReadUInt16();
            script.IASAFrame = inFile.ReadUInt16();
            script.TotalFrames = inFile.ReadUInt16();

            script.UnknownFlags1 = inFile.ReadUInt32();
            script.UnknownFlags2 = inFile.ReadUInt32();
            script.UnknownFlags3 = inFile.ReadUInt16();
            ushort CommandListCount = inFile.ReadUInt16();
            int HeaderSize = inFile.ReadInt32();
            var baseoff = inFile.BaseStream.Position;
            for (int j = 0; j < CommandListCount; j++)
            {
                inFile.BaseStream.Seek(baseoff + 12 * j);
                ushort type = inFile.ReadUInt16();
                var cl = CommandListFactory.ByType((CommandListType)type);
                cl.Type = (CommandListType)type;
                int cnt = inFile.ReadUInt16();
                for (int o = 0; o < cnt; o++)
                {
                    cl.Add(cl.GenerateCommand());
                }
                int frameoff = inFile.ReadInt32();
                int dataoff = inFile.ReadInt32();
                inFile.BaseStream.Seek(baseoff + frameoff + 12 * j);
                foreach (BaseCommand cmd in cl)
                {
                    cmd.StartFrame = inFile.ReadUInt16();
                    cmd.EndFrame = inFile.ReadUInt16();
                }
                inFile.BaseStream.Seek(baseoff + dataoff + 12 * j);
                foreach (BaseCommand cmd in cl)
                {
                    switch ((CommandListType)cl.Type)
                    {
                        case CommandListType.FLOW:
                            (cmd as FlowCommand).Type = (FlowCommand.FlowType)inFile.ReadInt16();
                            Util.LogUnkEnum((cmd as FlowCommand).Type, "script", script.Name);
                            (cmd as FlowCommand).Input = (Input)inFile.ReadUInt16();
                            Util.LogUnkEnum((cmd as FlowCommand).Input, "script", script.Name);
                            var index = inFile.ReadInt16();
                            if (index != -1)
                                (cmd as FlowCommand).TargetScript = bac.Scripts[index];
                            else
                                (cmd as FlowCommand).TargetScript = Script.NullScript;
                            (cmd as FlowCommand).TargetFrame = inFile.ReadInt16();
                            break;
                        case CommandListType.ANIMATION:
                            var ani = cmd as AnimationCommand;
                            ani.Animation = inFile.ReadInt16();
                            ani.Type = (AnimationCommand.AnimationType)inFile.ReadByte();
                            Util.LogUnkEnum(ani.Type, "script", script.Name);
                            ani.Flags = (AnimationCommand.AnimationFlags)inFile.ReadByte();
                            Util.LogUnkEnum(ani.Flags, "script", script.Name);
                            ani.FromFrame = inFile.ReadInt16();
                            ani.ToFrame = inFile.ReadInt16();
                            break;
                        case CommandListType.TRANSITION:
                            var transition = (TransitionCommand)cmd;
                            transition.Flag1 = inFile.ReadUInt16();
                            transition.Flag2 = inFile.ReadUInt16();
                            transition.Float1 = inFile.ReadSingle();
                            transition.Float2 = inFile.ReadSingle();
                            transition.Float3 = inFile.ReadSingle();
                            transition.Float4 = inFile.ReadSingle();
                            transition.Float5 = inFile.ReadSingle();
                            transition.Float6 = inFile.ReadSingle();
                            break;
                        case CommandListType.STATE:
                            var unk3 = cmd as StateCommand;
                            unk3.Flags = (StateCommand.StateFlags)inFile.ReadUInt32();
                            Util.LogUnkEnumFlags(unk3.Flags, "script", script.Name);
                            unk3.UnknownFlags2 = inFile.ReadUInt32();
                            break;
                        case CommandListType.SPEED:
                            (cmd as SpeedCommand).Multiplier = inFile.ReadSingle();
                            break;
                        case CommandListType.CANCELS:
                            (cmd as CancelCommand).Condition = (CancelCommand.CancelConditions)inFile.ReadUInt32();
                            Util.LogUnkEnumFlags((cmd as CancelCommand).Condition, "script", script.Name);
                            var d = inFile.ReadInt32();
                            if (d != -1 && d < bcm.CancelLists.Count)
                                (cmd as CancelCommand).CancelList = bcm.CancelLists[d];
                            break;
                        case CommandListType.HURTBOX:
                            var hurt = cmd as HurtboxCommand;
                            hurt.X = inFile.ReadSingle();
                            hurt.Y = inFile.ReadSingle();
                            hurt.Rotation = inFile.ReadSingle();
                            hurt.Width = inFile.ReadSingle();
                            hurt.Height = inFile.ReadSingle();
                            hurt.FloatUnknown = inFile.ReadSingle();
                            hurt.Unknown1 = inFile.ReadUInt32();
                            hurt.Unused = (Unused16)inFile.ReadUInt16();
                            hurt.Unknown4 = inFile.ReadByte();
                            hurt.Unknown5 = inFile.ReadSByte();
                            break;
                        case CommandListType.PHYSICS:
                            var physics = cmd as PhysicsCommand;
                            physics.VelX = inFile.ReadSingle();
                            physics.VelY = inFile.ReadSingle();
                            physics.Unk01 = inFile.ReadUInt32();
                            physics.PhysicsFlags = (PhysicsCommand.PFlags)inFile.ReadUInt32();
                            Util.LogUnkEnumFlags(physics.PhysicsFlags, "script", script.Name);
                            physics.AccX = inFile.ReadSingle();
                            physics.AccY = inFile.ReadSingle();
                            physics.Unk02 = inFile.ReadUInt64();
                            //cmd.Raw = inFile.ReadBytes(0x20);
                            break;
                        case CommandListType.ETC:
                            var etc = cmd as EtcCommand;
                            etc.Type = (EtcCommand.EtcCommandType)inFile.ReadUInt16();
                            Util.LogUnkEnum(etc.Type, "script", script.Name);
                            etc.ShortParam = inFile.ReadUInt16();
                            var arr = new int[7];
                            for(int tmp = 0; tmp < 7; tmp++)
                                arr[tmp] = inFile.ReadInt32();
                            etc.RawParams = arr;
                            //cmd.Raw = inFile.ReadBytes(30);
                            break;
                        case CommandListType.HITBOX:
                            var hit = cmd as HitboxCommand;
                            hit.X = inFile.ReadSingle();
                            hit.Y = inFile.ReadSingle();
                            hit.Rotation = inFile.ReadSingle();
                            hit.Width = inFile.ReadSingle();
                            hit.Height = inFile.ReadSingle();
                            hit.Unused = (Unused32)inFile.ReadInt32();
                            hit.ID = inFile.ReadSByte();
                            hit.Juggle = inFile.ReadSByte();
                            hit.Type = (HitboxCommand.HitboxType)inFile.ReadByte();
                            Util.LogUnkEnum(hit.Type, "script", script.Name);
                            hit.HitLevel = (HitboxCommand.HitLevelType)inFile.ReadByte();
                            Util.LogUnkEnum(hit.HitLevel, "script", script.Name);
                            hit.HitFlags = (HitboxCommand.Flags)inFile.ReadInt16();
                            Util.LogUnkEnumFlags(hit.HitFlags, "script", script.Name);
                            hit.UnknownByte1 = inFile.ReadSByte();
                            hit.UnknownByte2 = inFile.ReadSByte();
                            hit.Hits = inFile.ReadSByte();
                            hit.JugglePotential = inFile.ReadSByte();
                            hit.JuggleIncrement = inFile.ReadSByte();
                            hit.JuggleIncrementLimit = inFile.ReadSByte();
                            hit.HitboxEffect = inFile.ReadSByte();
                            hit.UnknownByte3 = inFile.ReadSByte();
                            hit.Unused2 = (Unused16)inFile.ReadInt16();
                            var index2 = inFile.ReadInt32();
                            hit.HitboxDataSet = bac.HitboxTable[index2];
                            if (!hit.HitboxDataSet.Usage.Contains(script) && hit.Type != HitboxCommand.HitboxType.PROXIMITY)
                                hit.HitboxDataSet.Usage.Add(script);
                            break;
                        case CommandListType.INVINC:
                            var invinc = cmd as HurtNodeCommand;
                            invinc.Flags = (HurtNodeCommand.VulnerabilityFlags)inFile.ReadUInt32();
                            Util.LogUnkEnumFlags(invinc.Flags, "script", script.Name);
                            invinc.Location = (HurtNodeCommand.BodyParts)inFile.ReadUInt32();
                            invinc.Unk02 = inFile.ReadUInt16();
                            invinc.Unk03 = inFile.ReadUInt16();
                            invinc.Unk04 = inFile.ReadUInt16();
                            invinc.Unk05 = inFile.ReadUInt16();
                            break;
                        case CommandListType.TARGETLOCK:
                            var targetLock = (TargetLockCommand)cmd;
                            targetLock.Type = (TargetLockCommand.TargetLockType)inFile.ReadInt32();
                            var dmgScriptIndex = inFile.ReadInt32();
                            targetLock.DmgScript = dmgScriptIndex > -1 ? bac.Scripts.First(x => x.Index == dmgScriptIndex) : Script.NullScript;
                            targetLock.Unknown2 = inFile.ReadInt32();
                            targetLock.Unknown3 = inFile.ReadInt32();
                            break;
                        case CommandListType.SFX:
                            var sfx = (SfxCommand)cmd;
                            sfx.Type = (SfxType)inFile.ReadUInt16();
                            sfx.Sound = inFile.ReadInt16();
                            sfx.Unknown1 = inFile.ReadUInt32();
                            sfx.Unknown2 = inFile.ReadUInt32();
                            sfx.Unknown3 = inFile.ReadUInt32();
                            break;
                        default:
                            cmd.Raw = inFile.ReadBytes(8);
                            break;
                    }
                }
                script.CommandLists.Add(cl);

            }
            for (int i = 0; i < 13; i++)
            {
                if (script.CommandLists.Count <= i || script.CommandLists[i].Type != (CommandListType)i)
                {
                    var c = CommandListFactory.ByType((CommandListType)i);
                    c.Type = (CommandListType)i;
                    script.CommandLists.Insert(i, c);
                }
            }
        }
コード例 #8
0
ファイル: BACFile.cs プロジェクト: dantarion/ssf4ae-tools
        public static void ToFilename(string name, BACFile bac, BCMFile bcm)
        {
            bac.Scripts.Remove(Script.NullScript);
            bac.VFXScripts.Remove(Script.NullScript);

            bac.Scripts = new ObservableCollection<Script>(bac.Scripts.OrderBy(x => x.Index));
            bac.VFXScripts = new ObservableCollection<Script>(bac.VFXScripts.OrderBy(x => x.Index));

            using (var ms = new MemoryStream())
            using (var outFile = new BinaryWriter(ms))
            {
                outFile.Write(1128350243);
                outFile.Write(2686974);
                outFile.Write(65537);

                outFile.Write((short)(bac.Scripts.Last().Index + 1));
                if (bac.VFXScripts.Count > 0)
                    outFile.Write((short)(bac.VFXScripts.Last().Index + 1));
                else
                    outFile.Write((short)0);
                outFile.Write(bac.HitboxTable.Last().Index + 1);

                int OffsetOffset = (int)outFile.BaseStream.Position;

                outFile.Write(0);
                outFile.Write(0);
                outFile.Write(0);
                outFile.Write(0);
                outFile.Write(0);
                foreach (ObservableCollection<float> list in bac.UnknownFloatData)
                    foreach (float entry in list)
                        outFile.Write(entry);

                /* Scripts */
                int ScriptOffset = (int)outFile.BaseStream.Position;
                for (int i = 0; i < bac.Scripts.Last().Index + 1; i++)
                    outFile.Write(0);
                /* VFX Scripts */
                int VFXScriptOffset = (int)outFile.BaseStream.Position;
                if (bac.VFXScripts.Count != 0)
                    for (int i = 0; i < bac.VFXScripts.Last().Index + 1; i++)
                        outFile.Write(0);
                else
                    VFXScriptOffset = 0;

                /* Script Name Offsets */
                int ScriptNameOffset = (int)outFile.BaseStream.Position;
                for (int i = 0; i < bac.Scripts.Last().Index + 1; i++)
                    outFile.Write(0);

                /* VFX Script Name Offsets */
                int VFXScriptNameOffset = (int)outFile.BaseStream.Position;
                if (bac.VFXScripts.Count == 0)
                    VFXScriptNameOffset = 0;
                else
                    for (int i = 0; i < bac.VFXScripts.Last().Index + 1; i++)
                        outFile.Write(0);
                /* Hitbox Table */
                int HitboxTableOffset = (int)outFile.BaseStream.Position;
                for (int i = 0; i < bac.HitboxTable.Last().Index + 1; i++)
                    outFile.Write(0);
                outFile.BaseStream.Seek(0, SeekOrigin.End);

                foreach (Script script in bac.Scripts)
                {
                    int tmp = (int)outFile.BaseStream.Position;
                    writeScript(bac, bcm, outFile, script);
                    outFile.BaseStream.Seek(ScriptOffset + script.Index*4);
                    outFile.Write(tmp);
                    outFile.Seek(0, SeekOrigin.End);
                }
                foreach (Script script in bac.VFXScripts)
                {
                    int tmp = (int)outFile.BaseStream.Position;
                    writeScript(bac, bcm, outFile, script);
                    outFile.BaseStream.Seek(VFXScriptOffset + script.Index*4);
                    outFile.Write(tmp);
                    outFile.Seek(0, SeekOrigin.End);
                }
                /* Hitbox Table */
                foreach (HitBoxDataset dataset in bac.HitboxTable)
                {
                    int tmp = (int)outFile.BaseStream.Position;
                    outFile.BaseStream.Seek(HitboxTableOffset + dataset.Index*4);
                    outFile.Write(tmp);
                    outFile.Seek(0, SeekOrigin.End);
                    foreach (HitBoxData data in dataset.Data)
                    {
                        outFile.Write(data.Damage);
                        outFile.Write(data.Stun);
                        outFile.Write((ushort)data.Effect);
                        if (data.OnHit != null)
                            outFile.Write((short)(data.OnHit.Index - HitBoxData.getIndexOffset(data.Effect)));
                        else
                            outFile.Write((short)-1);
                        //0x8
                        outFile.Write(data.SelfHitstop);
                        outFile.Write(data.SelfShaking);
                        outFile.Write(data.TgtHitstop);
                        outFile.Write(data.TgtShaking);
                        //0x10
                        outFile.Write(data.HitGFX);
                        outFile.Write(data.Unknown1);
                        outFile.Write((short)data.Unused);
                        //0x18
                        outFile.Write(data.HitGFX2);
                        outFile.Write((int)data.Unused2);
                        outFile.Write((short)data.Unused3);
                        //0x20
                        outFile.Write(data.HitSFX);
                        outFile.Write(data.HitSFX2);
                        outFile.Write(data.TgtSFX);

                        outFile.Write(data.ArcadeScore);
                        outFile.Write(data.SelfMeter);
                        outFile.Write(data.TgtMeter);
                        outFile.Write(data.JuggleStart);
                        outFile.Write(data.TgtAnimTime);
                        outFile.Write((int)data.MiscFlag);
                        outFile.Write(data.VelX);
                        outFile.Write(data.VelY);

                        outFile.Write(data.VelZ);
                        outFile.Write(data.PushbackDist);
                        outFile.Write(data.AccX);
                        outFile.Write(data.AccY);
                        outFile.Write(data.AccZ);
                    }
                }
                /* Script Names+Offsets */

                List<string> strings = new List<string>();
                int index = 0;
                foreach (Script tmp in bac.Scripts)
                {
                    while (index != tmp.Index)
                    {
                        strings.Add(null);
                        index++;
                    }
                    index++;
                    if (tmp.Name != "null")
                        strings.Add(tmp.Name);
                    else
                        strings.Add(null);
                }
                Util.writeStringTable(outFile, ScriptNameOffset, strings);

                strings.Clear();
                index = 0;
                foreach (Script tmp in bac.VFXScripts)
                {
                    while (index != tmp.Index)
                    {
                        strings.Add(null);
                        index++;
                    }
                    index++;
                    strings.Add(tmp.Name);
                }
                Util.writeStringTable(outFile, VFXScriptNameOffset, strings);

                outFile.BaseStream.Seek(0x14);
                outFile.Write(ScriptOffset);
                outFile.Write(VFXScriptOffset);
                outFile.Write(ScriptNameOffset);
                outFile.Write(VFXScriptNameOffset);
                outFile.Write(HitboxTableOffset);

                using (var fs = File.Create(name))
                {
                    ms.WriteTo(fs);
                }
            }
        }
コード例 #9
0
ファイル: BCMFile.cs プロジェクト: dantarion/ssf4ae-tools
        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;
            }
        }
コード例 #10
0
ファイル: BCMFile.cs プロジェクト: dantarion/ssf4ae-tools
        public static void ToFilename(string filename, BCMFile bcm)
        {
            using (var ms = new MemoryStream())
            using (var inFile = new BinaryWriter(ms))
            {
                //Header
                inFile.Write(1296253475);
                inFile.Write(2686974);
                inFile.Write(65537);
                inFile.Write(0);
                inFile.Write((ushort)bcm.Charges.Count());
                inFile.Write((ushort)(bcm.InputMotions.Count() - 1));
                inFile.Write((ushort)bcm.Moves.Count());
                inFile.Write((ushort)bcm.CancelLists.Count());
                //TODO WRITE OFFSETS
                int offsets = (int)inFile.BaseStream.Position;
                inFile.Write(0);
                inFile.Write(0);

                inFile.Write(0);
                inFile.Write(0);

                inFile.Write(0);
                inFile.Write(0);

                inFile.Write(0);
                inFile.Write(0);
                int ChargeOffset = (int)inFile.BaseStream.Position;
                if (bcm.Charges.Count == 0)
                    ChargeOffset = 0;
                foreach (Charge c in bcm.Charges)
                {
                    inFile.Write((ushort)c.Input);
                    inFile.Write(c.Unknown1);
                    inFile.Write((ushort)c.MoveFlags);
                    inFile.Write(c.Frames);
                    inFile.Write(c.Unknown3);
                    inFile.Write(c.StorageIndex);
                }
                int ChargeNamesOffset = (int)inFile.BaseStream.Position;
                if (bcm.Charges.Count == 0)
                    ChargeNamesOffset = 0;
                foreach (Charge c in bcm.Charges)
                    inFile.Write(0);
                int InputOffset = (int)inFile.BaseStream.Position;
                foreach (InputMotion i in bcm.InputMotions)
                {
                    if (i == InputMotion.NONE)
                        continue;
                    inFile.Write(i.Entries.Count());
                    foreach (InputMotionEntry entry in i.Entries)
                    {
                        inFile.Write((ushort)entry.Type);
                        inFile.Write((ushort)entry.Buffer);
                        //if (entry.Type == InputType.CHARGE)
                        //    inFile.Write((ushort)bcm.Charges.IndexOf(entry.Charge));
                        inFile.Write((ushort)entry.Input);
                        inFile.Write((ushort)entry.MoveFlags);
                        inFile.Write((ushort)entry.Flags);
                        inFile.Write((ushort)entry.Requirement);
                    }
                    for (int j = i.Entries.Count; j < 16; j++)
                    {
                        inFile.Write(0);
                        inFile.Write(0);
                        inFile.Write(0);
                    }
                }
                int InputNamesOffset = (int)inFile.BaseStream.Position;
                foreach (InputMotion c in bcm.InputMotions)
                {
                    if (c == InputMotion.NONE)
                        continue;
                    inFile.Write(0);
                }
                int MoveOffset = (int)inFile.BaseStream.Position;
                foreach (Move m in bcm.Moves)
                {
                    inFile.Write((ushort)m.Input);
                    inFile.Write((ushort)m.MoveFlags);
                    inFile.Write((ushort)m.PositionRestriction);
                    inFile.Write((ushort)m.Restriction);
                    inFile.Write(m.Unk1);
                    inFile.Write((ushort)m.StateRestriction);
                    inFile.Write((uint)m.MiscRestriction);
                    inFile.Write((uint)m.UltraRestriction);
                    inFile.Write(m.PositionRestrictionDistance);
                    inFile.Write((short)m.EXRequirement);
                    inFile.Write((short)m.EXCost);
                    inFile.Write((short)m.UltraRequirement);
                    inFile.Write((short)m.UltraCost);
                    inFile.Write(bcm.InputMotions.IndexOf(m.InputMotion) - 1);
                    inFile.Write(m.Script.Index);

                    /* AI data */
                    inFile.Write((uint)m.Features);
                    inFile.Write(m.CpuMinRange);
                    inFile.Write(m.CpuMaxRange);
                    inFile.Write(m.Unk2);
                    inFile.Write(m.Unk3);
                    inFile.Write(m.CpuPassiveMove);
                    inFile.Write(m.CpuCounterMove);
                    inFile.Write(m.CpuVsStand);
                    inFile.Write(m.CpuVsCrouch);
                    inFile.Write(m.CpuVsAir);
                    inFile.Write(m.CpuVsDown);
                    inFile.Write(m.CpuVsStunned);
                    inFile.Write(m.CpuProbeMove);
                    inFile.Write(m.CpuVsVeryClose);
                    inFile.Write(m.CpuVsClose);
                    inFile.Write(m.CpuVsMidRange);
                    inFile.Write(m.CpuVsFar);
                    inFile.Write(m.CpuVsVeryFar);

                }
                int MovesNameOffset = (int)inFile.BaseStream.Position;
                foreach (Move m in bcm.Moves)
                    inFile.Write(0);
                int CancelListOffset = (int)inFile.BaseStream.Position;
                int off = bcm.CancelLists.Count*12;
                foreach (CancelList cl in bcm.CancelLists)
                {
                    inFile.Write(cl.Moves.Count);
                    inFile.Write(off);
                    off = off - 8 + cl.Moves.Count*2;
                }
                int CancelListNameOffset = (int)inFile.BaseStream.Position;
                foreach (CancelList cl in bcm.CancelLists)
                    inFile.Write(0);
                foreach (CancelList cl in bcm.CancelLists)
                {
                    foreach (Move m in cl.Moves)
                    {
                        inFile.Write((short)bcm.Moves.IndexOf(m));
                    }
                }
                //Names Time!
                List<string> strings = new List<string>();
                foreach (Charge tmp in bcm.Charges)
                    strings.Add(tmp.Name);
                Util.writeStringTable(inFile, ChargeNamesOffset, strings);

                strings.Clear();
                foreach (InputMotion tmp in bcm.InputMotions)
                {
                    if (tmp == InputMotion.NONE)
                        continue;
                    strings.Add(tmp.Name);
                }
                Util.writeStringTable(inFile, InputNamesOffset, strings);

                strings.Clear();
                foreach (Move tmp in bcm.Moves)
                    strings.Add(tmp.Name);
                Util.writeStringTable(inFile, MovesNameOffset, strings);

                strings.Clear();
                foreach (CancelList tmp in bcm.CancelLists)
                    strings.Add(tmp.Name);
                Util.writeStringTable(inFile, CancelListNameOffset, strings);

                inFile.Seek((int)offsets, SeekOrigin.Begin);
                inFile.Write(ChargeOffset);
                inFile.Write(ChargeNamesOffset);

                inFile.Write(InputOffset);
                inFile.Write(InputNamesOffset);

                inFile.Write(MoveOffset);
                inFile.Write(MovesNameOffset);

                inFile.Write(CancelListOffset);
                inFile.Write(CancelListNameOffset);

                using (var fs = File.Create(filename))
                {
                    ms.WriteTo(fs);
                }
            }
        }