Ejemplo n.º 1
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");
            }
        }
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            // Update base address for children.
            VoidPtr baseAddress = 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 (ResourceNode child in Children)
            {
                int size = child.CalculateSize(false);
                dataLocations.Add(child, ptr);
                if (child is ClassicStageTblSizeTblNode && size == 48)
                {
                    // Rebuild
                    Dictionary <string, int> sizes = Children.ToDictionary(c => c.Name, c =>
                    {
                        int fullSize    = c.CalculateSize(false);
                        int paddingInts = (c as ClassicStageTblNode)?.Padding?.Length ?? 0;
                        return(fullSize - sizeof(bint) * paddingInts);
                    });

                    bint[] newTbl = new bint[12];
                    fixed(bint *newTblPtr = newTbl)
                    {
                        foreach (string key in new[]
                        {
                            "simpleStageB1Tbl",
                            "simpleStageB2Tbl",
                            "simpleStage11Tbl"
                        })
                        {
                            if (!sizes.TryGetValue(key, out int s) || s != 0x104)
                            {
                                MessageBox.Show(
                                    $"Changing the size of {key} may not work properly (BrawlCrate doesn't know yet which size entry to update)");
                            }
                        }

                        bint *bptr = newTblPtr;

                        foreach (string key in new[]
                        {
                            "simpleStage1Tbl",
                            "simpleStage2Tbl",
                            "simpleStage3Tbl",
                            "simpleStage4Tbl",
                            "simpleStageB1Tbl",
                            "simpleStage5Tbl",
                            "simpleStage6Tbl",
                            "simpleStage7Tbl",
                            "simpleStage8Tbl",
                            "simpleStage9Tbl",
                            "simpleStage10Tbl",
                            "simpleStageB2Tbl"
                        })
                        {
                            if (sizes.TryGetValue(key, out int s))
                            {
                                *bptr = s;
                            }
                            else
                            {
                                MessageBox.Show($"Cannot get size of {key}");
                            }

                            bptr++;
                        }

                        child.ReplaceRaw(newTblPtr, 48);
                    }
                }

                child.Rebuild(ptr, size, false);
                ptr += size;
            }

            Header->_DataLength = ptr - baseAddress;

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

            List <ResourceNode> childrenAlphabetical = Children.OrderBy(o => o.Name).ToList();

            foreach (ResourceNode child in childrenAlphabetical)
            {
                *dataPointers = 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++;
                }
            }

            if (currentString - address > length)
            {
                throw new Exception($"Wrong amount of memory allocated for rebuild of common2 data (Expected: {currentString - address} | Actual: {length})");
            }

            Header->_Length = length;
        }