Example #1
0
        public static BCMFile FromUassetFile(string fileName)
        {
            byte[] fileBytes = File.ReadAllBytes(fileName);

            byte[] UassetHeaderBytes = Common.GetUassetHeader(fileBytes);
            fileBytes = Common.RemoveUassetHeader(fileBytes);

            List <Move>       MoveList    = new List <Move>();
            List <CancelList> CancelLists = new List <CancelList>();
            List <Input>      InputList   = new List <Input>();
            List <Charge>     ChargeList  = new List <Charge>();

            Debug.WriteLine("READING");
            using (var ms = new MemoryStream(fileBytes))
                using (var inFile = new BinaryReader(ms))
                {
                    string bcmString = new string(inFile.ReadChars(4));

                    if (bcmString != "#BCM")
                    {
                        throw new Exception("Error: Not a valid KWBCM file!");
                    }

                    Debug.WriteLine(bcmString);

                    inFile.BaseStream.Seek(0xA, SeekOrigin.Begin);
                    short BCMVER = inFile.ReadInt16();
                    Debug.WriteLine("BCMVER: " + BCMVER);
                    short ChargeCount = inFile.ReadInt16();
                    Debug.WriteLine("ChargeCount: " + ChargeCount);
                    short InputCount = inFile.ReadInt16();
                    Debug.WriteLine("InputCount: " + InputCount);
                    short MoveCount = inFile.ReadInt16();
                    Debug.WriteLine("Movecount: " + MoveCount);
                    short CancelCount = inFile.ReadInt16(); //last cancel index
                    Debug.WriteLine("Cancelcount: " + CancelCount);

                    int startOfCharges     = inFile.ReadInt32();
                    int startOfInputs      = inFile.ReadInt32();
                    int startOfMoves       = inFile.ReadInt32();
                    int startOfNames       = inFile.ReadInt32();
                    int startOfCancelLists = inFile.ReadInt32();
                    Debug.WriteLine("StartOfCharges: " + startOfCharges);
                    Debug.WriteLine("StartOfInputs: " + startOfInputs);

                    Debug.WriteLine("StartOfMoves: " + startOfMoves);
                    Debug.WriteLine("StartOfNames: " + startOfNames);

                    Debug.WriteLine("StartOfCancelLists: " + startOfCancelLists);

                    Debug.WriteLine("Current pos: " + inFile.BaseStream.Position.ToString("X"));
                    Debug.WriteLine("\n\n");

                    inFile.BaseStream.Seek(startOfCharges, SeekOrigin.Begin);

                    List <int> ChargeAddresses = new List <int>();

                    for (int i = 0; i < ChargeCount; i++)
                    {
                        ChargeAddresses.Add(inFile.ReadInt32());
                    }

                    for (int i = 0; i < ChargeAddresses.Count; i++)
                    {
                        Charge thisCharge        = new Charge();
                        int    thisChargeAddress = ChargeAddresses[i];
                        inFile.BaseStream.Seek(thisChargeAddress, SeekOrigin.Begin);
                        Debug.WriteLine("ChargeAddress: " + thisChargeAddress.ToString("X"));

                        thisCharge.ChargeDirection = inFile.ReadInt16();
                        thisCharge.Unknown1        = inFile.ReadInt16();
                        thisCharge.Unknown2        = inFile.ReadInt16();
                        thisCharge.Unknown3        = inFile.ReadInt16();
                        thisCharge.ChargeFrames    = inFile.ReadInt16();
                        thisCharge.Flags           = inFile.ReadInt16();
                        thisCharge.ChargeIndex     = inFile.ReadInt16();
                        thisCharge.Unknown4        = inFile.ReadInt16();

                        thisCharge.Index = i;
                        ChargeList.Add(thisCharge);
                    }

                    inFile.BaseStream.Seek(startOfInputs, SeekOrigin.Begin);

                    List <int> InputAddresses = new List <int>();

                    for (int i = 0; i < InputCount; i++)
                    {
                        InputAddresses.Add(inFile.ReadInt32());
                    }

                    for (int i = 0; i < InputAddresses.Count; i++)
                    {
                        Input thisInput        = new Input();
                        int   thisInputAddress = InputAddresses[i];
                        inFile.BaseStream.Seek(thisInputAddress, SeekOrigin.Begin);
                        Debug.WriteLine("InputAddress: " + thisInputAddress.ToString("X"));

                        List <int> moveEntryOffsets = new List <int>();

                        moveEntryOffsets.Add(inFile.ReadInt32());
                        moveEntryOffsets.Add(inFile.ReadInt32());
                        moveEntryOffsets.Add(inFile.ReadInt32());
                        moveEntryOffsets.Add(inFile.ReadInt32());

                        var entries = new List <InputEntry>();

                        foreach (var entryOffset in moveEntryOffsets)
                        {
                            if (entryOffset == 0)
                            {
                                entries.Add(new InputEntry());
                                continue;
                            }

                            inFile.BaseStream.Seek(entryOffset + thisInputAddress, SeekOrigin.Begin);
                            var partCount = inFile.ReadInt32();

                            InputEntry       thisInputEntry = new InputEntry();
                            List <InputPart> parts          = new List <InputPart>();

                            for (int j = 0; j < partCount; j++)
                            {
                                InputPart thisPart = new InputPart()
                                {
                                    InputType      = (InputType)inFile.ReadInt16(),
                                    Buffer         = inFile.ReadInt16(),
                                    InputDirection = (InputDirection)inFile.ReadInt16(),
                                    Unknown1       = inFile.ReadInt16(),
                                    Unknown2       = inFile.ReadInt16(),
                                    Unknown3       = inFile.ReadInt16(),
                                    Unknown4       = inFile.ReadInt16(),
                                    Unknown5       = inFile.ReadInt16(),
                                };

                                parts.Add(thisPart);
                            }

                            for (int j = 0; j < 16 - partCount; j++) //There can be up to 16 parts, but even if they are empty they are still there, only filled with 0x00
                            {
                                var unused = inFile.ReadBytes(16);
                                foreach (var b in unused)
                                {
                                    if (b != 0)
                                    {
                                        Debug.WriteLine("Read unexpected byte in what was thought to be an empty part of an input.");
                                    }
                                }
                            }

                            thisInputEntry.InputParts = parts.ToArray();
                            entries.Add(thisInputEntry);
                        }

                        thisInput.InputEntries = entries.ToArray();

                        thisInput.Index = i;
                        InputList.Add(thisInput);
                        Debug.WriteLine("Created input with index: " + i);
                    }

                    for (int i = 0; i < MoveCount * 4; i += 0x4)
                    {
                        long thisMovePosition = startOfMoves + i;
                        long thisNamePosition = startOfNames + i;

                        inFile.BaseStream.Seek(thisNamePosition, SeekOrigin.Begin);
                        int    NameAddress = inFile.ReadInt32();
                        string Name        = GetName(NameAddress, inFile);

                        inFile.BaseStream.Seek(thisMovePosition, SeekOrigin.Begin);
                        int offset = inFile.ReadInt32();
                        Debug.WriteLine("Adding move at: " + offset.ToString("X"));

                        inFile.BaseStream.Seek(offset, SeekOrigin.Begin);

                        short input            = inFile.ReadInt16();
                        short inputFlags       = inFile.ReadInt16();
                        int   restrict         = inFile.ReadInt32();
                        int   restrict2        = inFile.ReadInt32();
                        float restrictDistance = inFile.ReadSingle();
                        int   unknown4         = (BCMVER > 0) ? inFile.ReadInt32() : 0;
                        // CHANGED: split projectileRestrict into 2 16bit properties.
                        var   projectileGroup    = inFile.ReadInt16();
                        var   projectileMaxCount = inFile.ReadInt16();
                        int   unknown6           = inFile.ReadInt16();
                        int   unknown7           = inFile.ReadInt16();
                        short unknown8           = inFile.ReadInt16();
                        short unknown9           = inFile.ReadInt16();

                        short MeterRequirement    = inFile.ReadInt16();
                        short MeterUsed           = inFile.ReadInt16();
                        short unknown10           = inFile.ReadInt16();
                        short unknown11           = inFile.ReadInt16();
                        int   VtriggerRequirement = inFile.ReadInt16();
                        int   VtriggerUsed        = inFile.ReadInt16();
                        int   Unknown16           = inFile.ReadInt32();
                        int   InputMotionIndex    = inFile.ReadInt16();
                        int   ScriptIndex         = inFile.ReadInt16();

                        Move thisMove = new Move()
                        {
                            Name                = Name,
                            Index               = (short)(i == 0 ? 0 : (i / 4)),
                            Input               = input,
                            InputFlags          = inputFlags,
                            PositionRestriction = restrict,
                            Unknown3            = restrict2,
                            RestrictionDistance = restrictDistance,
                            Unknown4            = unknown4,
                            ProjectileGroup     = projectileGroup,
                            ProjectileMaxCount  = projectileMaxCount,
                            Unknown6            = (short)unknown6,
                            Unknown7            = (short)unknown7,
                            Unknown8            = unknown8,
                            Unknown9            = unknown9,
                            Unknown10           = unknown10,
                            Unknown11           = unknown11,
                            MeterRequirement    = (short)MeterRequirement,
                            MeterUsed           = (short)MeterUsed,
                            VtriggerRequirement = (short)VtriggerRequirement,
                            VtriggerUsed        = (short)VtriggerUsed,
                            Unknown16           = Unknown16,
                            InputMotionIndex    = (short)InputMotionIndex,
                            ScriptIndex         = (short)ScriptIndex,
                            Unknown17           = inFile.ReadInt32(),
                            Unknown18           = inFile.ReadInt32(),
                            Unknown19           = (BCMVER == 0) ? inFile.ReadInt32() : 0,
                            Unknown20           = inFile.ReadSingle(),
                            Unknown21           = inFile.ReadSingle(),
                            Unknown22           = inFile.ReadInt32(),
                            Unknown23           = inFile.ReadInt32(),
                            Unknown24           = inFile.ReadInt32(),
                            Unknown25           = inFile.ReadInt32(),
                            Unknown26           = inFile.ReadInt16(),
                            NormalOrVtrigger    = inFile.ReadInt16(),
                            Unknown28           = inFile.ReadInt32()
                        };

                        if (thisMove.InputMotionIndex != -1) //Just for debugging...
                        {
                            InputList.Where(x => x.Index == thisMove.InputMotionIndex).ToList()[0].Name += thisMove.Name + ", ";
                        }

                        MoveList.Add(thisMove);

                        Debug.WriteLine("MOVE: " + "Index: " + (i == 0 ? 0 : (i / 4)) +
                                        "\nName: " + Name +
                                        "\nOffset: " + offset.ToString("X") +
                                        "\nNameOffet: " + NameAddress.ToString("X") +
                                        "\nInput: " + input +
                                        "\nflags: " + inputFlags
                                        + "\nRestrict: " + restrict
                                        + "\nRestrict2: " + restrict2
                                        + "\nRestrictDistance: " + restrictDistance
                                        + "\nUnknown4: " + unknown4
                                        + "\nProjectileGroup: " + projectileGroup
                                        + "\nProjectileMaxCount: " + projectileMaxCount
                                        + "\nUnknown6: " + unknown6
                                        + "\nUnknown7: " + unknown7
                                        + "\nUnknown8: " + unknown8
                                        + "\nUnknown9: " + unknown9
                                        + "\nUnknown10: " + unknown10
                                        + "\nUnknown11: " + unknown11
                                        + "\nMeterReq: " + MeterRequirement
                                        + "\nMeterUsed: " + MeterUsed
                                        + "\nVtriggerReq: " + VtriggerRequirement
                                        + "\nVtriggerUsed: " + VtriggerUsed
                                        + "\nUnknown16: " + Unknown16
                                        + "\nInputMotionIndex: " + InputMotionIndex
                                        + "\nScriptIndex: " + ScriptIndex
                                        + "\nUnknown17: " + thisMove.Unknown17
                                        + "\nUnknown18: " + thisMove.Unknown18
                                        + "\nUnknown19: " + thisMove.Unknown19
                                        + "\nUnknown20: " + thisMove.Unknown20
                                        + "\nUnknown21: " + thisMove.Unknown21
                                        + "\nUnknown22: " + thisMove.Unknown22
                                        + "\nUnknown23: " + thisMove.Unknown23
                                        + "\nUnknown24: " + thisMove.Unknown24
                                        + "\nUnknown25: " + thisMove.Unknown25
                                        + "\nUnknown26: " + thisMove.Unknown26
                                        + "\nUnknown27: " + thisMove.NormalOrVtrigger
                                        + "\nUnknown28: " + thisMove.Unknown28
                                        + "\n\n");
                    }

                    inFile.BaseStream.Seek(startOfCancelLists, SeekOrigin.Begin);
                    List <int> CancelAddresses = new List <int>();
                    for (int i = 0; i < CancelCount; i++)
                    {
                        int thisCancelAddress = inFile.ReadInt32();
                        Debug.WriteLine("Cancel " + (i) + ": " + thisCancelAddress.ToString("X"));
                        CancelAddresses.Add(thisCancelAddress);
                    }

                    for (int i = 0; i < CancelAddresses.Count; i++)
                    {
                        CancelList thisCancelList = new CancelList();
                        int        thisAddress    = CancelAddresses[i];

                        if (thisAddress == 0)
                        {
                            CancelLists.Add(thisCancelList);
                            continue;
                        }

                        inFile.BaseStream.Seek(thisAddress, SeekOrigin.Begin);

                        thisCancelList.Unknown1 = inFile.ReadInt32();
                        int MovesInList        = inFile.ReadInt32();
                        int LastIndex          = inFile.ReadInt32(); //last move index in list -1...
                        int StartOffset        = inFile.ReadInt32(); //offset until real list FROM START OF CANCEL!!!
                        int StartOfCancelInts  = inFile.ReadInt32();
                        int StartOfCancelBytes = inFile.ReadInt32();

                        Debug.WriteLine("ThisCancelAddress: " + thisAddress.ToString("X"));
                        Debug.WriteLine($"Cancel {i}:\nCU1: {thisCancelList.Unknown1}\nMovesInList: {MovesInList}\nNumberOfSomethingInList: {LastIndex}\nStartOffset: {StartOffset.ToString("X")}\nCU5: {StartOfCancelInts.ToString("X")}\nEndOffset: {StartOfCancelBytes.ToString("X")}\n");

                        inFile.BaseStream.Seek(thisAddress + StartOffset, SeekOrigin.Begin);
                        Debug.WriteLine("ListAddress: " + (thisAddress + StartOffset).ToString("X"));
                        Debug.WriteLine("ListAddressEnd: " + (thisAddress + StartOfCancelBytes).ToString("X"));

                        List <Cancel> cancels = new List <Cancel>();
                        thisCancelList.Index = i;

                        for (int j = 0; j < MovesInList; j++)
                        {
                            int thisMoveInList = inFile.ReadInt16();
                            Debug.WriteLine("Move: " + thisMoveInList);

                            Move cancelMove = MoveList.Where(x => x.Index == thisMoveInList).ToList()[0];

                            Cancel thisCancel = new Cancel();
                            thisCancel.Index       = (short)thisMoveInList;
                            thisCancel.Name        = cancelMove.Name;
                            thisCancel.ScriptIndex = cancelMove.ScriptIndex;

                            cancels.Add(thisCancel);
                        }

                        thisCancelList.Cancels = cancels.ToArray();

                        //All lists should have Moves divisible by 2. If it doesn't, simply add an empty one (0x00, 0x00)
                        if (MovesInList % 2 != 0)
                        {
                            Debug.WriteLine("READING EMPTY MOVE");
                            inFile.ReadInt16();
                        }

                        if (StartOfCancelInts != 0)
                        {
                            Debug.WriteLine("We got something!!!" + inFile.BaseStream.Position.ToString("X") + " - Should be: " + (thisAddress + StartOfCancelInts).ToString("X"));
                            Debug.WriteLine(((thisAddress + StartOfCancelBytes) - (thisAddress + StartOfCancelInts)) / MovesInList);

                            for (int j = 0; j < MovesInList; j++)
                            {
                                int value1 = inFile.ReadInt32();
                                int value2 = inFile.ReadInt32();

                                thisCancelList.Cancels[j].CancelInts = new CancelInts()
                                {
                                    Unknown1 = value1,
                                    Unknown2 = value2
                                };
                            }
                        }

                        Debug.WriteLine("Position is " + inFile.BaseStream.Position.ToString("X") + " - Should be: " + (thisAddress + StartOfCancelBytes).ToString("X"));

                        if (inFile.BaseStream.Position != thisAddress + StartOfCancelBytes) //NOT a good idea
                        {
                            Debug.WriteLine("We are not where we're supposed to be, reading bytes until we are...");

                            while (inFile.BaseStream.Position != thisAddress + StartOfCancelBytes)
                            {
                                Debug.WriteLine(inFile.ReadByte());
                            }

                            Debug.WriteLine("Position is " + inFile.BaseStream.Position.ToString("X") + " - Should be: " + (thisAddress + StartOfCancelBytes).ToString("X"));
                        }

                        for (int j = 0; j < LastIndex; j++)
                        {
                            inFile.BaseStream.Seek((thisAddress + StartOfCancelBytes) + (j * 4), SeekOrigin.Begin);

                            var offset = inFile.ReadInt32();

                            if (offset == 0)
                            {
                                continue;
                            }

                            Debug.WriteLine("SomethingElseInCancelList(offsets?): " + offset.ToString("X") + " Pos: " + (inFile.BaseStream.Position - 4).ToString("X") + " - Index: " + j + "  added offset:" + (offset + thisAddress).ToString("X"));

                            var address = offset + thisAddress;

                            inFile.BaseStream.Seek(address, SeekOrigin.Begin);

                            var cancelBytesBelongsTo = thisCancelList.Cancels.First(x => x.Index == j);

                            var unkBytes = inFile.ReadBytes(0x24);

                            cancelBytesBelongsTo.UnknownBytes = unkBytes;
                        }

                        CancelLists.Add(thisCancelList);
                        Debug.WriteLine("\n");
                    }

                    try
                    {
                        foreach (var cancelList in CancelLists)
                        {
                            if (cancelList?.Cancels == null)
                            {
                                continue;
                            }

                            Debug.WriteLine($"\nCancelList Index: {cancelList.Index}\n");

                            foreach (var cancel in cancelList.Cancels)
                            {
                                if (cancel == null)
                                {
                                    continue;
                                }

                                Debug.WriteLine("Cancel: " + cancel.Index + " ScriptIndex:" + cancel.ScriptIndex);

                                foreach (var unknownByte in cancel.UnknownBytes)
                                {
                                    Debug.Write(unknownByte.ToString("X") + " ");
                                }

                                Debug.WriteLine("");
                            }
                        }
                    }
                    catch (Exception)
                    {
                        Debug.WriteLine("Are the Cancel indices of the CancelList in order?");
                    }

                    Debug.WriteLine("\nCharges\n");

                    foreach (var charge in ChargeList)
                    {
                        Debug.WriteLine("CHARGE: " + charge.Index);
                        Debug.WriteLine("Dir: " + charge.ChargeDirection);
                        Debug.WriteLine("u1: " + charge.Unknown1);
                        Debug.WriteLine("u2: " + charge.Unknown2);
                        Debug.WriteLine("u3: " + charge.Unknown3);
                        Debug.WriteLine("ChargeFrames: " + charge.ChargeFrames);
                        Debug.WriteLine("Flags: " + charge.Flags);
                        Debug.WriteLine("CINDEX: " + charge.ChargeIndex);
                        Debug.WriteLine("u4: " + charge.Unknown4);
                        Debug.WriteLine("\n");
                    }

                    foreach (var input in InputList)
                    {
                        Debug.WriteLine("Input: " + input.Index);
                        Debug.WriteLine("Name: " + input.Name);
                        Debug.WriteLine("Entries: " + input.InputEntries.Length);

                        WriteInputToDebug(input);

                        Debug.WriteLine("\n");
                    }
                }

            Debug.WriteLine("Done");

            BCMFile bcm = new BCMFile()
            {
                Inputs      = InputList.ToArray(),
                CancelLists = CancelLists.ToArray(),
                Charges     = ChargeList.ToArray(),
                Moves       = MoveList.ToArray(),
                RawUassetHeaderDontTouch = UassetHeaderBytes
            };

            return(bcm);
        }
Example #2
0
        public static BCMFile FromUassetFile(string fileName)
        {
            byte[] fileBytes = File.ReadAllBytes(fileName);

            byte[] UassetHeaderBytes = GetUassetHeader(fileBytes);
            fileBytes = CreateGameBCMFromFile(fileBytes);

               List<Move> MoveList = new List<Move>();
               List<CancelList> CancelLists = new List<CancelList>();
               List<Input> InputList = new List<Input>();
               List<Charge> ChargeList = new List<Charge>();

            Debug.WriteLine("READING");
            using (var ms = new MemoryStream(fileBytes))
            using (var inFile = new BinaryReader(ms))
            {
                string bcmString = new string(inFile.ReadChars(4));

                if (bcmString != "#BCM")
                {
                    throw new Exception("Error: Not a valid KWBCM file!");
                }

                Debug.WriteLine(bcmString);

                inFile.BaseStream.Seek(0xC, SeekOrigin.Begin);

                short ChargeCount = inFile.ReadInt16();
                Debug.WriteLine("ChargeCount: " + ChargeCount);
                short InputCount = inFile.ReadInt16();
                Debug.WriteLine("InputCount: " + InputCount);
                short MoveCount = inFile.ReadInt16();
                Debug.WriteLine("Movecount: " + MoveCount);
                short CancelCount = inFile.ReadInt16(); //last cancel index
                Debug.WriteLine("Cancelcount: " + CancelCount);

                int startOfCharges = inFile.ReadInt32();
                int startOfInputs = inFile.ReadInt32();
                int startOfMoves = inFile.ReadInt32();
                int startOfNames = inFile.ReadInt32();
                int startOfCancelLists = inFile.ReadInt32();
                Debug.WriteLine("StartOfCharges: " + startOfCharges);
                Debug.WriteLine("StartOfInputs: " + startOfInputs);

                Debug.WriteLine("StartOfMoves: " + startOfMoves);
                Debug.WriteLine("StartOfNames: " + startOfNames);

                Debug.WriteLine("StartOfCancelLists: " + startOfCancelLists);

                Debug.WriteLine("Current pos: " + inFile.BaseStream.Position.ToString("X"));
                Debug.WriteLine("\n\n");

                inFile.BaseStream.Seek(startOfCharges, SeekOrigin.Begin);

                List<int> ChargeAddresses = new List<int>();

                for (int i = 0; i < ChargeCount; i++)
                {
                    ChargeAddresses.Add(inFile.ReadInt32());
                }

                for (int i = 0; i < ChargeAddresses.Count; i++)
                {
                    Charge thisCharge = new Charge();
                    int thisChargeAddress = ChargeAddresses[i];
                    inFile.BaseStream.Seek(thisChargeAddress, SeekOrigin.Begin);
                    Debug.WriteLine("ChargeAddress: " + thisChargeAddress.ToString("X"));

                    thisCharge.ChargeDirection = inFile.ReadInt16();
                    thisCharge.Unknown1 = inFile.ReadInt16();
                    thisCharge.Unknown2 = inFile.ReadInt16();
                    thisCharge.Unknown3 = inFile.ReadInt16();
                    thisCharge.ChargeFrames = inFile.ReadInt16();
                    thisCharge.Flags = inFile.ReadInt16();
                    thisCharge.ChargeIndex = inFile.ReadInt16();
                    thisCharge.Unknown4 = inFile.ReadInt16();

                    thisCharge.Index = i;
                    ChargeList.Add(thisCharge);
                }

                inFile.BaseStream.Seek(startOfInputs, SeekOrigin.Begin);

                List<int> InputAddresses = new List<int>();

                for (int i = 0; i < InputCount; i++)
                {
                    InputAddresses.Add(inFile.ReadInt32());
                }

                for (int i = 0; i < InputAddresses.Count; i++)
                {
                    Input thisInput = new Input();
                    int thisInputAddress = InputAddresses[i];
                    inFile.BaseStream.Seek(thisInputAddress, SeekOrigin.Begin);
                    Debug.WriteLine("InputAddress: " + thisInputAddress.ToString("X"));

                    List<int> moveEntryOffsets = new List<int>();

                    moveEntryOffsets.Add(inFile.ReadInt32());
                    moveEntryOffsets.Add(inFile.ReadInt32());
                    moveEntryOffsets.Add(inFile.ReadInt32());
                    moveEntryOffsets.Add(inFile.ReadInt32());

                    var entries = new List<InputEntry>();

                    foreach (var entryOffset in moveEntryOffsets)
                    {
                        if (entryOffset == 0)
                        {
                            entries.Add(new InputEntry());
                            continue;
                        }

                        inFile.BaseStream.Seek(entryOffset + thisInputAddress, SeekOrigin.Begin);
                        var partCount = inFile.ReadInt32();

                        InputEntry thisInputEntry = new InputEntry();
                        List<InputPart> parts = new List<InputPart>();

                        for (int j = 0; j < partCount; j++)
                        {
                            InputPart thisPart = new InputPart()
                            {
                                InputType = (InputType)inFile.ReadInt16(),
                                Buffer = inFile.ReadInt16(),
                                InputDirection = (InputDirection)inFile.ReadInt16(),
                                Unknown1 = inFile.ReadInt16(),
                                Unknown2 = inFile.ReadInt16(),
                                Unknown3 = inFile.ReadInt16(),
                                Unknown4 = inFile.ReadInt16(),
                                Unknown5 = inFile.ReadInt16(),
                            };

                            parts.Add(thisPart);
                        }

                        for (int j = 0; j < 16-partCount; j++) //There can be up to 16 parts, but even if they are empty they are still there, only filled with 0x00
                        {
                            var unused = inFile.ReadBytes(16);
                            foreach (var b in unused)
                            {
                                if (b != 0)
                                {
                                    Debug.WriteLine("Read unexpected byte in what was thought to be an empty part of an input.");
                                }
                            }
                        }

                        thisInputEntry.InputParts = parts.ToArray();
                        entries.Add(thisInputEntry);
                    }

                    thisInput.InputEntries = entries.ToArray();

                    thisInput.Index = i;
                    InputList.Add(thisInput);
                    Debug.WriteLine("Created input with index: " + i);
                }

                for (int i = 0; i < MoveCount*4; i+=0x4)
                {
                    long thisMovePosition = startOfMoves + i;
                    long thisNamePosition = startOfNames + i;

                    inFile.BaseStream.Seek(thisNamePosition, SeekOrigin.Begin);
                    int NameAddress = inFile.ReadInt32();
                    string Name = GetName(NameAddress, inFile);

                    inFile.BaseStream.Seek(thisMovePosition, SeekOrigin.Begin);
                    int offset = inFile.ReadInt32();
                    Debug.WriteLine("Adding move at: " + offset.ToString("X"));

                    inFile.BaseStream.Seek(offset, SeekOrigin.Begin);

                    short input = inFile.ReadInt16();
                    short inputFlags = inFile.ReadInt16();
                    int restrict = inFile.ReadInt32();
                    int restrict2 = inFile.ReadInt32();
                    float restrictDistance = inFile.ReadSingle();
                    int projectileRestrict = inFile.ReadInt32();
                    int unknown6 = inFile.ReadInt16();
                    int unknown7 = inFile.ReadInt16();
                    short unknown8 = inFile.ReadInt16();
                    short unknown9 = inFile.ReadInt16();

                    short MeterRequirement = inFile.ReadInt16();
                    short MeterUsed = inFile.ReadInt16();
                    short unknown10 = inFile.ReadInt16();
                    short unknown11 = inFile.ReadInt16();
                    int VtriggerRequirement = inFile.ReadInt16();
                    int VtriggerUsed = inFile.ReadInt16();
                    int Unknown16 = inFile.ReadInt32();
                    int InputMotionIndex = inFile.ReadInt16();
                    int ScriptIndex = inFile.ReadInt16();

                    Move thisMove = new Move()
                    {
                        Name = Name,
                        Index = (short)(i == 0 ? 0 : (i / 4)),
                        Input = input,
                        InputFlags = inputFlags,
                        PositionRestriction = restrict,
                        Unknown3 = restrict2,
                        RestrictionDistance = restrictDistance,
                        ProjectileLimit = projectileRestrict,
                        Unknown6 = (short)unknown6,
                        Unknown7 = (short)unknown7,
                        Unknown8 = unknown8,
                        Unknown9 = unknown9,
                        Unknown10 = unknown10,
                        Unknown11 = unknown11,
                        MeterRequirement =  (short)MeterRequirement,
                        MeterUsed = (short)MeterUsed,
                        VtriggerRequirement = (short)VtriggerRequirement,
                        VtriggerUsed = (short)VtriggerUsed,
                        Unknown16 = Unknown16,
                        InputMotionIndex = (short)InputMotionIndex,
                        ScriptIndex = (short)ScriptIndex,
                        Unknown17 = inFile.ReadInt32(),
                        Unknown18 = inFile.ReadInt32(),
                        Unknown19 = inFile.ReadInt32(),
                        Unknown20 = inFile.ReadSingle(),
                        Unknown21 = inFile.ReadSingle(),
                        Unknown22 = inFile.ReadInt32(),
                        Unknown23 = inFile.ReadInt32(),
                        Unknown24 = inFile.ReadInt32(),
                        Unknown25 = inFile.ReadInt32(),
                        Unknown26 = inFile.ReadInt16(),
                        Unknown27 = inFile.ReadInt16(),
                        Unknown28 = inFile.ReadInt32()
                    };

                    if (thisMove.InputMotionIndex != -1) //Just for debugging...
                    {
                        InputList.Where(x => x.Index == thisMove.InputMotionIndex).ToList()[0].Name += thisMove.Name + ", ";
                    }

                    MoveList.Add(thisMove);

                    Debug.WriteLine("MOVE: " + "Index: " + (i == 0 ? 0 : (i/4)) +
                                    "\nName: " + Name +
                                    "\nOffset: " + offset.ToString("X") +
                                    "\nNameOffet: " + NameAddress.ToString("X") +
                                    "\nInput: " + input +
                                    "\nflags: " + inputFlags
                                    + "\nRestrict: " + restrict
                                    + "\nRestrict2: " + restrict2
                                    + "\nRestrictDistance: " + restrictDistance
                                    + "\nProjectileRestrict: " + projectileRestrict
                                    + "\nUnknown6: " + unknown6
                                    + "\nUnknown7: " + unknown7
                                    + "\nUnknown8: " + unknown8
                                    + "\nUnknown9: " + unknown9
                                    + "\nUnknown10: " + unknown10
                                    + "\nUnknown11: " + unknown11
                                    + "\nMeterReq: " + MeterRequirement
                                    + "\nMeterUsed: " + MeterUsed
                                    + "\nVtriggerReq: " + VtriggerRequirement
                                    + "\nVtriggerUsed: " + VtriggerUsed
                                    + "\nUnknown16: " + Unknown16
                                    + "\nInputMotionIndex: " + InputMotionIndex
                                    + "\nScriptIndex: " + ScriptIndex
                                    +"\nUnknown17: " + thisMove.Unknown17
                                    + "\nUnknown18: " + thisMove.Unknown18
                                    + "\nUnknown19: " + thisMove.Unknown19
                                    + "\nUnknown20: " + thisMove.Unknown20
                                    + "\nUnknown21: " + thisMove.Unknown21
                                    + "\nUnknown22: " + thisMove.Unknown22
                                    + "\nUnknown23: " + thisMove.Unknown23
                                    + "\nUnknown24: " + thisMove.Unknown24
                                    + "\nUnknown25: " + thisMove.Unknown25
                                    + "\nUnknown26: " + thisMove.Unknown26
                                    + "\nUnknown27: " + thisMove.Unknown27
                                    + "\nUnknown28: " + thisMove.Unknown28
                                    + "\n\n");
                }

                inFile.BaseStream.Seek(startOfCancelLists, SeekOrigin.Begin);
                List<int> CancelAddresses = new List<int>();
                for (int i = 0; i < CancelCount; i++)
                {
                    int thisCancelAddress = inFile.ReadInt32();
                    Debug.WriteLine("Cancel " + (i) + ": " + thisCancelAddress.ToString("X"));
                    CancelAddresses.Add(thisCancelAddress);
                }

                for (int i = 0; i < CancelAddresses.Count; i++)
                {
                    CancelList thisCancelList = new CancelList();
                    int thisAddress = CancelAddresses[i];

                    if (thisAddress == 0)
                    {
                        CancelLists.Add(new CancelList());
                        continue;
                    }

                    inFile.BaseStream.Seek(thisAddress, SeekOrigin.Begin);

                    thisCancelList.Unknown1 = inFile.ReadInt32();
                    int MovesInList = inFile.ReadInt32();
                    int LastIndex = inFile.ReadInt32(); //last move index in list -1...
                    int StartOffset = inFile.ReadInt32(); //offset until real list FROM START OF CANCEL!!!
                    int StartOfCancelInts = inFile.ReadInt32();
                    int StartOfCancelBytes = inFile.ReadInt32();

                    Debug.WriteLine("ThisCancelAddress: " + thisAddress.ToString("X"));
                    Debug.WriteLine("Cancel {6}:\nCU1: {0}\nMovesInList: {1}\nNumberOfSomethingInList: {2}\nStartOffset: {3}\nCU5: {4}\nEndOffset: {5}\n", thisCancelList.Unknown1, MovesInList, LastIndex, StartOffset.ToString("X"), StartOfCancelInts.ToString("X"), StartOfCancelBytes.ToString("X"), i);

                    inFile.BaseStream.Seek(thisAddress + StartOffset, SeekOrigin.Begin);
                    Debug.WriteLine("ListAddress: " + (thisAddress + StartOffset).ToString("X"));
                    Debug.WriteLine("ListAddressEnd: " + (thisAddress + StartOfCancelBytes).ToString("X"));

                    List<Cancel> cancels = new List<Cancel>();
                    thisCancelList.Index = i;

                    for (int j = 0; j < MovesInList; j++)
                    {
                        int thisMoveInList = inFile.ReadInt16();
                        Debug.WriteLine("Move: " + thisMoveInList);

                        Move cancelMove = MoveList.Where(x => x.Index == thisMoveInList).ToList()[0];

                        Cancel thisCancel = new Cancel();
                        thisCancel.Index = (short)thisMoveInList;
                        thisCancel.Name = cancelMove.Name;
                        thisCancel.ScriptIndex = cancelMove.ScriptIndex;

                        cancels.Add(thisCancel);
                    }

                    thisCancelList.Cancels = cancels.ToArray();

                    //All lists should have Moves divisible by 2. If it doesn't, simply add an empty one (0x00, 0x00)
                    if (MovesInList % 2 != 0)
                    {
                        Debug.WriteLine("READING EMPTY MOVE");
                        inFile.ReadInt16();
                    }

                    if (StartOfCancelInts != 0)
                    {
                        Debug.WriteLine("We got something!!!" + inFile.BaseStream.Position.ToString("X") + " - Should be: " + (thisAddress + StartOfCancelInts).ToString("X"));
                        Debug.WriteLine(((thisAddress + StartOfCancelBytes) - (thisAddress + StartOfCancelInts)) / MovesInList);

                        for (int j = 0; j < MovesInList; j++)
                        {
                            int value1 = inFile.ReadInt32();
                            int value2 = inFile.ReadInt32();

                            thisCancelList.Cancels[j].CancelInts = new CancelInts()
                            {
                                Unknown1 = value1,
                                Unknown2 = value2
                            };
                        }
                    }

                    Debug.WriteLine("Position is " + inFile.BaseStream.Position.ToString("X") + " - Should be: " + (thisAddress + StartOfCancelBytes).ToString("X"));

                    if (inFile.BaseStream.Position != thisAddress + StartOfCancelBytes) //NOT a good idea
                    {
                        Debug.WriteLine("We are not where we're supposed to be, reading bytes until we are...");

                        while (inFile.BaseStream.Position != thisAddress + StartOfCancelBytes)
                        {
                            Debug.WriteLine(inFile.ReadByte());
                        }

                        Debug.WriteLine("Position is " + inFile.BaseStream.Position.ToString("X") + " - Should be: " + (thisAddress + StartOfCancelBytes).ToString("X"));
                    }

                    for (int j = 0; j < LastIndex; j++)
                    {
                        inFile.BaseStream.Seek((thisAddress + StartOfCancelBytes) + (j * 4), SeekOrigin.Begin);

                        var offset = inFile.ReadInt32();

                        if (offset == 0)
                        {
                            continue;
                        }

                        Debug.WriteLine("SomethingElseInCancelList(offsets?): " + offset.ToString("X") + " Pos: " + (inFile.BaseStream.Position - 4).ToString("X") + " - Index: " + j + "  added offset:" + (offset+thisAddress).ToString("X"));

                        var address = offset + thisAddress;

                        inFile.BaseStream.Seek(address, SeekOrigin.Begin);

                        var cancelBytesBelongsTo = thisCancelList.Cancels.First(x => x.Index == j);

                        cancelBytesBelongsTo.UnknownBytes = inFile.ReadBytes(0x24);
                    }

                    CancelLists.Add(thisCancelList);
                    Debug.WriteLine("\n");
                }

                foreach (var cancelList in CancelLists)
                {
                    if (cancelList.Cancels == null)
                    {
                        continue;
                    }

                    foreach (var cancel in cancelList.Cancels)
                    {
                        if (cancel == null)
                        {
                            continue;
                        }
                        Debug.WriteLine("Cancel: " + cancel.Index + " ScriptIndex:" + cancel.ScriptIndex);
                        foreach (var unknownByte in cancel.UnknownBytes)
                        {
                            Debug.Write(unknownByte.ToString("X") + " ");
                        }
                        Debug.WriteLine("");
                    }
                }

                Debug.WriteLine("\nCharges\n");

                foreach (var charge in ChargeList)
                {
                    Debug.WriteLine("CHARGE: " + charge.Index);
                    Debug.WriteLine("Dir: " + charge.ChargeDirection);
                    Debug.WriteLine("u1: " + charge.Unknown1);
                    Debug.WriteLine("u2: " + charge.Unknown2);
                    Debug.WriteLine("u3: " + charge.Unknown3);
                    Debug.WriteLine("ChargeFrames: " + charge.ChargeFrames);
                    Debug.WriteLine("Flags: " + charge.Flags);
                    Debug.WriteLine("CINDEX: " + charge.ChargeIndex);
                    Debug.WriteLine("u4: " + charge.Unknown4);
                    Debug.WriteLine("\n");
                }

                foreach (var input in InputList)
                {
                    Debug.WriteLine("Input: " + input.Index);
                    Debug.WriteLine("Name: " + input.Name);
                    Debug.WriteLine("Entries: " + input.InputEntries.Length);

                    WriteInputToDebug(input);

                    Debug.WriteLine("\n");
                }
            }

            Debug.WriteLine("Done");

            BCMFile bcm = new BCMFile()
            {
                Inputs = InputList.ToArray(),
                CancelLists = CancelLists.ToArray(),
                Charges = ChargeList.ToArray(),
                Moves = MoveList.ToArray(),
                RawUassetHeaderDontTouch = UassetHeaderBytes
            };

            return bcm;
        }