Пример #1
0
        /// <summary>
        /// Creates a table of offsets with a corresponding data size at each offset.
        /// </summary>
        private void GetLookupSizes(SakuraiArchiveHeader *hdr)
        {
            //Read lookup offsets first and use them to get entry sizes at each offset.
            bint *lookup = hdr->LookupEntries;

            //First add each offset to the dictionary with size of 0.
            //The dictionary will sort the offsets automatically, in case they aren't already.
            for (int i = 0; i < hdr->_lookupEntryCount; i++)
            {
                int w = *(bint *)Address(lookup[i]);
                if (!_lookupSizes.ContainsKey(w))
                {
                    _lookupSizes.Add(w, 0);
                }
            }
            //Now go through each offset and calculate the size with the offset difference.
            int prev = 0; bool first = true;

            int[] t = _lookupSizes.Keys.ToArray();
            for (int i = 0; i < t.Length; i++)
            {
                int off = t[i];
                if (first)
                {
                    first = false;
                }
                else
                {
                    _lookupSizes[prev] = off - prev;
                }
                prev = off;
            }
            //The last entry in the moveset file goes right up to the lookup offsets.
            _lookupSizes[prev] = Offset(lookup) - prev;
        }
Пример #2
0
        //This calculate data entry sizes.
        //One array will be initialized with each offset,
        //then another will be created and sorted using the same temp entries.
        //This will allow for sorted offsets and easy indexing of the same entries.
        internal static int[] CalculateSizes(int end, bint *hdr, int count, bool data, params int[] ignore)
        {
            Temp[] t = new Temp[count];
            for (int i = 0; i < count; i++)
            {
                if (Array.IndexOf(ignore, i) < 0)
                {
                    t[i] = new Temp((int)hdr[i], 0);
                }
                else
                {
                    t[i] = null;
                }
            }

            if (data)
            {
                t[2]._offset = 1;
            }
            Temp[] sorted = t.Where(x => x != null).OrderBy(x => x._offset).ToArray();
            if (data)
            {
                t[2]._offset -= 1;
            }

            for (int i = 0; i < sorted.Length; i++)
            {
                sorted[i]._size = ((i < sorted.Length - 1) ? sorted[i + 1]._offset : end) - sorted[i]._offset;
            }
            return(t.Select(x => x._size).ToArray());
        }
Пример #3
0
        protected override bool OnInitialize()
        {
            base.OnInitialize();

            _name = Header.Name;

            SetSizeInternal((int)DataLength);

            _indexAddrs = new List <VoidPtr>();
            _counts     = new List <uint>();
            _indices    = new List <int> [5];

            _indices[1] = new List <int>();
            _indices[2] = new List <int>();
            _indices[0] = new List <int>();
            _indices[4] = new List <int>();
            _indices[3] = new List <int>();

            if (Offset2 - Offset1 != 0)
            {
                _indexAddrs.Add(Base + Offset1);
                _counts.Add((Offset2 - Offset1) / 4);
            }
            if (Offset3 - Offset2 != 0)
            {
                _indexAddrs.Add(Base + Offset2);
                _counts.Add((Offset3 - Offset2) / 4);
            }
            if (Offset4 - Offset3 != 0)
            {
                _indexAddrs.Add(Base + Offset3);
                _counts.Add((Offset4 - Offset3) / 4);
            }
            if (Offset5 - Offset4 != 0)
            {
                _indexAddrs.Add(Base + Offset4);
                _counts.Add((Offset5 - Offset4) / 4);
            }
            if (DataLength - Offset5 != 0)
            {
                _indexAddrs.Add(Base + Offset5);
                _counts.Add((DataLength - Offset5) / 4);
            }
            int i = 0;

            foreach (VoidPtr ptr in _indexAddrs)
            {
                bint *addr = (bint *)ptr;
                for (int x = 0; x < _counts[i]; x++)
                {
                    if (*addr != -1)
                    {
                        _indices[i].Add(*addr);
                    }
                    addr++;
                }
                i++;
            }
            return(false);
        }
Пример #4
0
        public ModelLinker(MDL0Header *pModel)
        {
            Header    = pModel;
            Version   = pModel->_header._version;
            NodeCache = new IMatrixNode[pModel->Properties->_numNodes];

            bint *offsets = (bint *)((byte *)pModel + 0x10);
            List <MDLResourceType> iList = IndexBank[Version];
            int groupCount = iList.Count;
            int offset;

            //Extract resource addresses
            fixed(ResourceGroup **gList = &Defs)
            for (int i = 0; i < groupCount; i++)
            {
                if ((offset = offsets[i]) != 0 && iList[i] != MR.None)
                {
                    gList[(int)iList[i]] = (ResourceGroup *)((byte *)pModel + offset);
                }
                else if (offset > 0 && iList[i] == MR.None)
                {
                    MessageBox.Show("Unused data offset " + i + " is not 0!");
                }
            }
        }
Пример #5
0
        //To do
        //protected override int OnCalculateSize(bool force)
        //{
        //    int size = CLR0.Size + 0x18 + (Children.Count * 0x10);
        //    foreach (PAT0EntryNode n in Children)
        //        size += n.CalculateSize(force);
        //    return size;
        //}

        protected internal override void PostProcess(VoidPtr bresAddress, VoidPtr dataAddress, int dataLength, StringTable stringTable)
        {
            base.PostProcess(bresAddress, dataAddress, dataLength, stringTable);

            PAT0 *header = (PAT0 *)dataAddress;

            header->ResourceStringAddress = stringTable[Name] + 4;

            ResourceGroup *group = header->Group;

            group->_first = new ResourceEntry(0xFFFF, 0, 0, 0, 0);
            ResourceEntry *rEntry = group->First;

            int index = 1;

            foreach (PAT0EntryNode n in Children)
            {
                dataAddress = (VoidPtr)group + (rEntry++)->_dataOffset;
                ResourceEntry.Build(group, index++, dataAddress, (BRESString *)stringTable[n.Name]);
                n.PostProcess(dataAddress, stringTable);
            }

            bint *strings = header->StringOffsets1;

            for (int i = 0; i < _stringList1.Count; i++)
            {
                strings[i] = (int)stringTable[_stringList1[i]] + 4 - (int)strings;
            }

            strings = header->StringOffsets2;
            for (int i = 0; i < _stringList2.Count; i++)
            {
                strings[i] = (int)stringTable[_stringList2[i]] + 4 - (int)strings;
            }
        }
Пример #6
0
        protected internal override void PostProcess(VoidPtr bresAddress, VoidPtr dataAddress, int dataLength, StringTable stringTable)
        {
            base.PostProcess(bresAddress, dataAddress, dataLength, stringTable);

            SHP0v3 *header = (SHP0v3 *)dataAddress;

            header->ResourceStringAddress = stringTable[Name] + 4;

            bint *stringPtr = header->StringEntries;

            for (int i = 0; i < header->_numEntries; i++)
            {
                stringPtr[i] = ((int)stringTable[_strings[i]] + 4) - (int)stringPtr;
            }

            ResourceGroup *group = header->Group;

            group->_first = new ResourceEntry(0xFFFF, 0, 0, 0, 0);

            ResourceEntry *rEntry = group->First;

            int index = 1;

            foreach (SHP0EntryNode n in Children)
            {
                dataAddress = (VoidPtr)group + (rEntry++)->_dataOffset;
                ResourceEntry.Build(group, index++, dataAddress, (BRESString *)stringTable[n.Name]);
                n.PostProcess(dataAddress, stringTable);
            }
        }
Пример #7
0
        public override void OnPopulate()
        {
            if (DataOffset1 > 0)
            {
                new MoveDefRawDataNode("Left")
                {
                    offsetID = 0
                }.Initialize(this, BaseAddress + DataOffset1, 0);
            }

            if (DataOffset2 > 0)
            {
                new MoveDefRawDataNode("Right")
                {
                    offsetID = 1
                }.Initialize(this, BaseAddress + DataOffset2, 0);
            }

            foreach (MoveDefRawDataNode d in Children)
            {
                bint *addr = (bint *)d.Header;
                for (int i = 0; i < d.Size / 4; i++)
                {
                    new MoveDefRawDataNode(new string((sbyte *)(BaseAddress + addr[i]))).Initialize(d, d.Header + i * 4,
                                                                                                    4);
                }
            }
        }
Пример #8
0
        protected override void OnWrite(VoidPtr address)
        {
            bint *  offsets  = (bint *)address;
            VoidPtr dataAddr = address;

            if (_entries.Count > 0)
            {
                foreach (CollisionDataEntry o in _entries)
                {
                    if (!o.External)
                    {
                        o.Write(dataAddr);
                        Lookup(o.LookupAddresses);
                        dataAddr += o._calcSize;
                    }
                }
                offsets = (bint *)dataAddr;
                foreach (CollisionDataEntry o in _entries)
                {
                    Lookup(&offsets);
                    *offsets++ = o.RebuildOffset;
                }
            }

            RebuildAddress = offsets;
            sListOffset *header = (sListOffset *)offsets;

            header->_listCount = _entries.Count;
            if (_entries.Count > 0)
            {
                header->_startOffset = Offset(dataAddr);
                Lookup(header->_startOffset.Address);
            }
        }
Пример #9
0
 public unsafe void WriteScriptArray(Script[] scripts, bint *addr)
 {
     foreach (Script s in scripts)
     {
         *addr++ = WriteScript(s);
     }
 }
Пример #10
0
        public override bool OnInitialize()
        {
            base.OnInitialize();

            _strings.Clear();

            byte *floor = (byte *)WorkingUncompressed.Address;
            int   length = WorkingUncompressed.Length;
            bint *offsets = (bint *)floor;
            int   index, last, current;

            for (index = 1, last = offsets[0]; last != length; index++)
            {
                current = offsets[index];
                if (current < last || current > length)
                {
                    break;
                }

                _strings.Add(MSBinDecoder.DecodeString(floor + last, current - last));

                last = current;
            }

            return(false);
        }
Пример #11
0
        protected internal override void PostProcess(VoidPtr dataAddress, StringTable stringTable)
        {
            base.PostProcess(dataAddress, stringTable);

            SCN0LightSet *header = (SCN0LightSet *)dataAddress;

            if (_ambientLight != null)
            {
                header->AmbientStringAddress = stringTable[_ambientLight] + 4;
            }
            else
            {
                header->_ambNameOffset = 0;
            }

            int   i;
            bint *strings = header->StringOffsets;

            for (i = 0; i < _entries.Count; i++)
            {
                strings[i] = (int)stringTable[_entries[i]] + 4 - (int)strings;
            }
            while (i < 8)
            {
                strings[i++] = 0;
            }
        }
Пример #12
0
        /// <summary>
        /// This writes changed data without rewriting the entire file
        /// </summary>
        public unsafe void QuickWrite()
        {
            VoidPtr origAddr          = _rootNode.WorkingUncompressed.Address;
            SakuraiArchiveHeader *hdr = (SakuraiArchiveHeader *)origAddr;
            VoidPtr origBase          = hdr->BaseAddress;

            var changed = _rootNode.RebuildEntries;

            if (changed.Count != 0)
            {
                foreach (var entry in changed)
                {
                    int   eOffset       = entry._offset;
                    bint *lookup        = hdr->LookupEntries;
                    int   currentOffset = *(bint *)(origBase + *lookup++);
                    for (int i = 0; i < hdr->_lookupEntryCount - 1; i++, lookup++)
                    {
                        int nextOffset = *(bint *)(origBase + *lookup);
                        if (eOffset >= currentOffset && eOffset < nextOffset)
                        {
                            int newSize = entry._calcSize;
                            int oldSize = entry._initSize;
                            int diff    = newSize - oldSize;

                            for (int x = i; x < hdr->_lookupEntryCount; x++)
                            {
                                lookup[x] += diff;
                            }
                        }
                        currentOffset = nextOffset;
                    }
                }
            }
        }
Пример #13
0
        public void Write(VoidPtr address)
        {
            LABLHeader *header   = (LABLHeader *)address;
            int         count    = _labels.Count;
            VoidPtr     dataAddr = address + 12 + count * 4;
            bint *      list     = (bint *)(address + 8);
            LabelItem   label;
            int         size;
            byte *      pad;

            for (int i = 0; i < count;)
            {
                label   = _labels[i++];
                list[i] = (int)dataAddr - (int)list;
                ((LABLEntry *)dataAddr)->Set(label.Tag, label.String);
                dataAddr += label.DataLen;
            }

            pad = (byte *)dataAddr;
            for (size = dataAddr - address; (size & 0x1F) != 0; size++)
            {
                *pad++ = 0;
            }

            header->Set(size, count);
        }
Пример #14
0
        protected internal override void OnRebuild(VoidPtr address, int length, bool force)
        {
            bint *addr = (bint *)address;

            foreach (MoveDefBoneIndexNode b in Children)
            {
                b.Rebuild(addr++, 4, true);
            }

            _entryOffset = addr;

            FDefBoneRef2 *header = (FDefBoneRef2 *)addr;

            header->_handNBoneIndex1 = HandNBoneIndex1;
            header->_handNBoneIndex2 = HandNBoneIndex2;
            header->_handNBoneIndex3 = HandNBoneIndex3;
            header->_handNBoneIndex4 = HandNBoneIndex4;
            header->_count           = Children.Count;

            if (Children.Count > 0)
            {
                header->_offset = (int)address - (int)_rebuildBase;
                _lookupOffsets.Add((int)header->_offset.Address - (int)_rebuildBase);
            }
        }
Пример #15
0
        protected override void OnWrite(VoidPtr address)
        {
            bint *addr = (bint *)address;

            foreach (BoneIndexValue b in _bones)
            {
                b.Write(addr++);
            }

            RebuildAddress = addr;

            sDataBoneRef2 *header = (sDataBoneRef2 *)addr;

            header->_handNBoneIndex1 = HandNBoneIndex1;
            header->_handNBoneIndex2 = HandNBoneIndex2;
            header->_handNBoneIndex3 = HandNBoneIndex3;
            header->_handNBoneIndex4 = HandNBoneIndex4;
            header->_count           = _bones.Count;

            if (_bones.Count > 0)
            {
                header->_offset = Offset(address);
                _lookupOffsets.Add(&header->_offset);
            }
        }
Пример #16
0
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            base.OnRebuild(address, length, force);

            SCN0Camera *header = (SCN0Camera *)address;

            header->_projType       = (int)_projType;
            header->_flags2         = (ushort)(2 + (int)_type);
            header->_userDataOffset = 0;

            int newFlags1 = 0;

            bint *values = (bint *)&header->_position;

            for (int i = 0; i < 15; i++)
            {
                EncodeFrames(GetKeys(i), ref keyframeAddr, &values[i], ref newFlags1, (int)Ordered[i]);
            }

            if (_userEntries.Count > 0)
            {
                _userEntries.Write(header->UserData = (VoidPtr)header + SCN0Camera.Size);
            }

            header->_flags1 = (ushort)newFlags1;
        }
Пример #17
0
        protected internal override void PostProcess(VoidPtr scn0Address, VoidPtr dataAddress, StringTable stringTable)
        {
            base.PostProcess(scn0Address, dataAddress, stringTable);

            SCN0LightSet *header = (SCN0LightSet *)dataAddress;

            if (_ambient != null && !String.IsNullOrEmpty(_ambient.Name))
            {
                header->AmbientStringAddress = stringTable[_ambient.Name] + 4;
            }
            else
            {
                header->_ambNameOffset = 0;
            }

            int   i;
            bint *strings = header->StringOffsets;

            for (i = 0; i < 8; i++)
            {
                if (!String.IsNullOrEmpty(GetLightName(i)))
                {
                    strings[i] = (int)stringTable[GetLightName(i)] + 4 - (int)strings;
                }
                else
                {
                    break;
                }
            }
            while (i < 8)
            {
                strings[i++] = 0;
            }
        }
        public ModelLinker(MDL0Header *pModel)
        {
            Header    = pModel;
            Version   = pModel->_header._version;
            NodeCache = pModel->Properties == null ?
                        new IMatrixNode[0] :
                        new IMatrixNode[pModel->Properties->_numNodes];
            BoneCache = new MDL0BoneNode[0];

            bint *offsets = (bint *)((byte *)pModel + 0x10);

            if (Version >= 9 && Version <= 11)
            {
                List <MDLResourceType> iList = IndexBank[Version];
                int groupCount = iList.Count;
                int offset;

                //Extract resource addresses
                fixed(ResourceGroup **gList = &Defs)
                for (int i = 0; i < groupCount; i++)
                {
                    if ((offset = offsets[i]) > 0)
                    {
                        gList[(int)iList[i]] = (ResourceGroup *)((byte *)pModel + offset);
                    }
                }
            }
        }
Пример #19
0
        protected override void OnWrite(VoidPtr address)
        {
            *(CollisionType *)address = _type;
            switch (_type)
            {
            case CollisionType.Type0:

                bint *addr = (bint *)address;
                foreach (BoneIndexValue b in _bones)
                {
                    b.Write(addr++);
                }

                RebuildAddress = addr;

                sCollData0 *data1 = (sCollData0 *)addr;
                data1->unk1 = _length;
                data1->unk2 = _width;
                data1->unk3 = _height;

                if (_bones.Count > 0)
                {
                    data1->_list._startOffset = Offset(address);
                    Lookup(&data1->_list._startOffset);
                }
                data1->_list._listCount = _bones.Count;


                break;

            case CollisionType.Type1:

                RebuildAddress = address;

                sCollData1 *data2 = (sCollData1 *)address;
                data2->unk1 = _length;
                data2->unk2 = _width;
                data2->unk3 = _height;

                break;

            case CollisionType.Type2:

                RebuildAddress = address;

                sCollData2 *data3 = (sCollData2 *)address;
                data3->flags = _flags;
                data3->unk1  = _length;
                data3->unk2  = _width;
                data3->unk3  = _height;

                if ((_flags & 2) == 2)
                {
                    data3->unk4 = _unknown;
                }

                break;
            }
        }
Пример #20
0
        public override bool OnInitialize()
        {
            bint *addr = (bint *)Data;

            dataAddr = addr[0].OffsetAddress;
            count    = addr[1];
            return(base.OnInitialize());
        }
Пример #21
0
        public Model(MDL0Header *pModel)
        {
            int   version = pModel->_header._version;
            bint *offsets = (bint *)((byte *)pModel + 0x10);
            List <MDLResourceType> iList = ModelLinker.IndexBank[version];

            List <Bone> boneList = ExtractBones((ResourceGroup *)((byte *)pModel + offsets[iList.IndexOf(MDLResourceType.Bones)]));
        }
Пример #22
0
        public static void EncodeSRT0Keyframes(KeyframeCollection kf, VoidPtr entryAddress, VoidPtr dataAddress, SRT0Code code)
        {
            SRT0TextureEntry *header = (SRT0TextureEntry *)entryAddress;

            header->Code = code;

            bint *pOffset = (bint *)entryAddress + 1;

            int index = 0;

            //Write values/offset and encode groups
            for (int type = 0; type < 3; type++)
            {
                bool has = false;
                switch (type)
                {
                case 0: has = !code.NoScale; break;

                case 1: has = !code.NoRotation; break;

                case 2: has = !code.NoTranslation; break;
                }
                for (int axis = 0; axis < (type == 1 ? 1 : 2); axis++, index++)
                {
                    if (has)
                    {
                        if (code.ScaleIsotropic && type == 0)
                        {
                            if (axis == 0)
                            {
                                if (code.FixedScaleX)
                                {
                                    *(bfloat *)pOffset++ = kf._keyArrays[0]._keyRoot._next._value;
                                }
                                else
                                {
                                    *pOffset = (int)dataAddress - (int)pOffset; pOffset++;
                                    dataAddress += EncodeEntry(index, AnimDataFormat.I12, kf, dataAddress);
                                }
                            }
                        }
                        else
                        {
                            //This gets the fixed bit. Same order, so it can be indexed
                            if (code._data[5 + index])
                            {
                                *(bfloat *)pOffset++ = kf._keyArrays[index]._keyRoot._next._value;
                            }
                            else
                            {
                                *pOffset = (int)dataAddress - (int)pOffset; pOffset++;
                                dataAddress += EncodeEntry(index, AnimDataFormat.I12, kf, dataAddress);
                            }
                        }
                    }
                }
            }
        }
Пример #23
0
        public override bool OnInitialize()
        {
            base.OnInitialize();

            _strings.Clear();
            if (_version == 4)
            {
                SHP0v4 *header = Header4;

                if ((_name == null) && (header->_stringOffset != 0))
                {
                    _name = header->ResourceString;
                }

                _numFrames = header->_numFrames;
                _loop      = header->_loop != 0;

                bint *stringOffset = header->StringEntries;
                for (int i = 0; i < header->_numEntries; i++)
                {
                    _strings.Add(new String((sbyte *)stringOffset + stringOffset[i]));
                }

                if (header->_origPathOffset > 0)
                {
                    _originalPath = header->OrigPath;
                }

                (_userEntries = new UserDataCollection()).Read(header->UserData);

                return(header->Group->_numEntries > 0);
            }
            else
            {
                SHP0v3 *header = Header3;

                if ((_name == null) && (header->_stringOffset != 0))
                {
                    _name = header->ResourceString;
                }

                _numFrames = header->_numFrames;
                _loop      = header->_loop != 0;

                bint *stringOffset = header->StringEntries;
                for (int i = 0; i < header->_numEntries; i++)
                {
                    _strings.Add(new String((sbyte *)stringOffset + stringOffset[i]));
                }

                if (header->_origPathOffset > 0)
                {
                    _originalPath = header->OrigPath;
                }

                return(header->Group->_numEntries > 0);
            }
        }
Пример #24
0
        protected override void OnParse(VoidPtr address)
        {
            hdr = *(DataCommonHeader *)address;
            bint *v      = (bint *)address;
            int   offset = 0;

            //Calculate the sizes of each section using their offsets,
            //in order of appearance
            int[] sizes = SakuraiArchiveNode.CalculateSizes(_root._dataSize, v, 26, false);

            //Parse all script-related data first
            ParseScripts(v, sizes);

            //These ICs need to be sorted into int and float arrays
            //Right now they're just a mess of values
            //The indices in the IC variable storage class
            _globalICs    = Parse <RawParamList>(v[0], 188);
            _globalsseICs = Parse <RawParamList>(v[1], 188);
            _ICs          = Parse <RawParamList>(v[2], 2204);
            _sseICs       = Parse <RawParamList>(v[3], 2204);
            //Entry action script offsets
            //Exit action script offsets
            //Flash overlay script offsets/flags
            _unk7          = Parse <EntryList <CommonUnk7Entry> >(v[7], 12);
            _unk8          = Parse <RawParamList>(v[8], 0x1A4);
            _itemSwingData = Parse <RawParamList>(v[9], 0x64);
            _unk10         = Parse <RawParamList>(v[10], 0x10);
            if ((offset = v[11]) > 0)
            {
                sListOffset *list = (sListOffset *)Address(offset);
                _unk11 = Parse <EntryList <Unknown11EntryNode> >(list->_startOffset, 12, (int)list->_listCount);
            }
            _unk12 = Parse <RawParamList>(v[12], 0x80);
            _unk13 = Parse <RawParamList>(v[13], 0x80);
            _unk14 = Parse <RawParamList>(v[14], 0x40);
            _unk15 = Parse <RawParamList>(v[15], 0x24);
            _unk16 = Parse <RawParamList>(v[16], 0x48);
            _ppMul = Parse <CmnPatternPowerMulNode>(v[17]);
            _unk18 = Parse <RawParamList>(v[18], 0x10);

            //Screen tint script offsets
            _legBones = Parse <CmnLegBonesNode>(v[21]);

            if ((offset = v[23]) > 0)
            {
                _unk23 = Parse <RawParamList>(*(bint *)Address(offset), 0xA8);
            }

            _unk24 = Parse <RawParamList>(v[24], 4);

            //Notes:

            //Unk12 and Unk13 are copies of the same parameters
            //with some different values

            //Unk23 is one value (0) in Global IC-Basics - offset to data at start of section child data
            //Params24 is one value (32) in IC-Basics
        }
Пример #25
0
        protected override void OnPopulate()
        {
            bint *addr = (bint *)(BaseAddress + EntryOffset);

            for (int i = 0; i < EntryCount; i++)
            {
                new MoveDefBoneIndexNode().Initialize(this, addr++, 4);
            }
        }
Пример #26
0
        protected override void OnPopulate()
        {
            bint *entry = Start;

            for (int i = 0; i < Count; i++)
            {
                new MoveDefIndexNode().Initialize(this, new DataSource((VoidPtr)(entry++), 0x4));
            }
        }
Пример #27
0
        protected override void OnPopulate()
        {
            bint *entry = (bint *)(BaseAddress + DataOffset);

            for (int i = 0; i < Count; i++)
            {
                new MoveDefIndexNode().Initialize(this, new DataSource((VoidPtr)(entry++), 4));
            }
        }
Пример #28
0
        public override void OnPopulate()
        {
            bint *entry = Start;

            for (int i = 0; i < Count; i++)
            {
                new MoveDefBoneIndexNode().Initialize(this, new DataSource((VoidPtr)entry++, 0x4));
            }
        }
Пример #29
0
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            // Update base address for children.
            BaseAddress = (VoidPtr)address + sizeof(Common2TblHeader);

            // Initiate header struct
            Common2TblHeader *Header = (Common2TblHeader *)address;

            *Header = new Common2TblHeader();
            Header->_OffCount  = _offCount;
            Header->_DataTable = Children.Count;
            Header->_pad0      = Header->_pad1 =
                Header->_pad2  = Header->_pad3 = 0;

            Dictionary <ResourceNode, VoidPtr> dataLocations = new Dictionary <ResourceNode, VoidPtr>();

            VoidPtr ptr = BaseAddress;

            foreach (var child in Children)
            {
                int size = child.CalculateSize(false);
                dataLocations.Add(child, ptr);
                child.Rebuild(ptr, size, false);
                ptr += size;
            }
            Header->_DataLength = (int)(ptr - BaseAddress);

            bint *dataPointers   = (bint *)ptr;
            bint *stringPointers = dataPointers + 1;
            byte *strings        = (byte *)(dataPointers + Children.Count + Children.Count);
            byte *currentString  = strings;

            foreach (var child in Children)
            {
                *dataPointers = (int)(dataLocations[child] - BaseAddress);
                dataPointers += 2;
                *stringPointers = (int)(currentString - strings);
                stringPointers += 2;

                byte[] text = Encoding.UTF8.GetBytes(child.Name);
                fixed(byte *from = text)
                {
                    Memory.Move(currentString, from, (uint)text.Length);
                    currentString += text.Length;
                    *currentString = 0;
                    currentString++;
                }
            }

            Header->_Length = (int)(currentString - address);

            if (Header->_Length != length)
            {
                throw new Exception("Wrong amount of memory allocated for rebuild of common2 data");
            }
        }
        protected override void OnWrite(VoidPtr address)
        {
            int leftOffset, rightOffset;

            List <int> offsets = new List <int>();
            sbyte *    ptr     = (sbyte *)address;

            foreach (string s in _left)
            {
                s.Write(ptr);
                offsets.Add(Offset(ptr));
                ptr += (s.Length + 1).Align(4);
            }

            bint *offPtr = (bint *)ptr;

            leftOffset = Offset(offPtr);
            foreach (int i in offsets)
            {
                Lookup(offPtr);
                *offPtr++ = i;
            }

            offsets.Clear();
            ptr = (sbyte *)offPtr;
            foreach (string s in _right)
            {
                s.Write(ptr);
                offsets.Add(Offset(ptr));
                ptr += (s.Length + 1).Align(4);
            }

            offPtr      = (bint *)ptr;
            rightOffset = Offset(offPtr);
            foreach (int i in offsets)
            {
                Lookup(offPtr);
                *offPtr++ = i;
            }

            RebuildAddress = offPtr;

            if (_left.Count > 0)
            {
                Lookup(offPtr);
            }
            *offPtr++ = _left.Count > 0 ? leftOffset : 0;
            *offPtr++ = _left.Count;

            if (_right.Count > 0)
            {
                Lookup(offPtr);
            }
            *offPtr++ = _right.Count > 0 ? rightOffset : 0;
            *offPtr++ = _right.Count;
        }