Ejemplo n.º 1
0
 private void Setup(SakuraiArchiveNode node, SakuraiEntryNode parent, int offset, string name)
 {
     _name   = name;
     _root   = node;
     _offset = offset;
     _parent = parent;
     if (_initSize <= 0)
     {
         _initSize = _root.GetSize(_offset);
     }
     _root.EntryCache[_offset] = this;
     if ((_externalEntry = _root.TryGetExternal(offset)) != null)
     {
         _externalEntry.References.Add(this);
     }
 }
Ejemplo n.º 2
0
        public unsafe void Write(SakuraiArchiveNode node, VoidPtr address, int length)
        {
            _baseAddress    = address + 0x20;
            _currentAddress = _baseAddress;

            //Write header
            SakuraiArchiveHeader *hdr = (SakuraiArchiveHeader *)address;

            hdr->_sectionCount            = _sectionCount;
            hdr->_externalSubRoutineCount = _referenceCount;
            hdr->_lookupEntryCount        = _lookupManager.Count;
            hdr->_fileSize = length;
            hdr->_pad1     = hdr->_pad2 = hdr->_pad3 = 0;

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

            //Write section data
            foreach (TableEntryNode section in node.SectionList)
            {
                SakuraiEntryNode entry = section;

                //If this section is referenced from an entry,
                //write that entry instead
                if (section.References.Count > 0)
                {
                    entry = section.References[0];
                }

                _sectionOffsets.Add(entry.Write(_currentAddress));
                _currentAddress += entry.TotalSize;
            }

            //Write lookup values
            hdr->_lookupOffset = (int)_currentAddress - (int)_baseAddress;
            _lookupManager.Write(ref _currentAddress);

            //These can only be accessed after the lookup offset and count
            //have been written to the header.
            sStringEntry *sectionAddr = hdr->Sections;
            sStringEntry *refAddr     = hdr->ExternalSubRoutines;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Don't call this outside of the Parse functions.
        /// This is here to eliminate redundant code.
        /// </summary>
        private static T CommonInit <T>(SakuraiArchiveNode root, SakuraiEntryNode parent, VoidPtr addr, params object[] parameters) where T : SakuraiEntryNode
        {
            int  offset     = root.Offset(addr);
            bool attributes = parameters.Contains("Attributes");

            if (offset <= 0 && !attributes)
            {
                return(null);
            }

            if (attributes)
            {
                parameters = new object[0];
            }

            T n = Activator.CreateInstance(typeof(T), parameters) as T;

            n.Setup(root, parent, offset);
            n.OnParse(addr);
            return(n);
        }
Ejemplo n.º 4
0
        public int GetSize()
        {
            _calculatingSize = true;

            //Reset variables
            _lookupCount          = _lookupLen = 0;
            _lookupManager        = new LookupManager();
            _postProcessNodes     = new List <SakuraiEntryNode>();
            _referenceStringTable = new CompactStringTable();

            //Add header size
            _size = SakuraiArchiveHeader.Size;

            //Calculate the size of each section and add names to string table
            foreach (TableEntryNode section in _rootNode.SectionList)
            {
                SakuraiEntryNode entry = section;

                //Sections *usually* have only one reference in data or dataCommon
                //An example of an exception to this is the 'AnimCmd' section
                //If a reference exists, calculate the size of that reference instead
                if (section.References.Count > 0)
                {
                    entry = section.References[0];
                }

                //Add the size of the entry's data, and the entry itself
                _size += entry.GetSize() + 8;

                //Add the lookup count
                _lookupCount += entry.GetLookupCount();

                //Add the section's name to the string table
                _referenceStringTable.Add(entry.Name);
            }

            //Calculate reference table size and add names to string table
            foreach (TableEntryNode reference in _rootNode.ReferenceList)
            {
                if (reference.References.Count > 0 || AddUnreferencedReferences)
                {
                    //Add entry name to string table
                    _referenceStringTable.Add(reference.Name);

                    //Add entry size (reference don't have any actual 'data' size)
                    _size += 8;
                }

                //TODO: Does each reference offset throughout the file
                //have a lookup offset?
                //Also, subtract 1 because the initial offset has no lookup entry
                //lookupCount += e.References.Count - 1;
            }

            _calculatingSize = false;

            //Add the lookup size and reference table size
            _size += (_lookupLen = _lookupCount * 4) + _referenceStringTable.TotalSize;

            return(_size);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Returns a node of the given type at an address in the moveset file.
 /// </summary>
 public T Parse <T>(VoidPtr address) where T : SakuraiEntryNode
 {
     return(SakuraiEntryNode.Parse <T>(this, null, address));
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Returns a node of the given type at an offset in the moveset file.
 /// </summary>
 public T Parse <T>(int offset) where T : SakuraiEntryNode
 {
     return(SakuraiEntryNode.Parse <T>(this, null, Address(offset)));
 }
Ejemplo n.º 7
0
 private void Setup(SakuraiArchiveNode node, SakuraiEntryNode parent, int offset)
 {
     Setup(node, parent, offset, null);
 }
Ejemplo n.º 8
0
 public void ParseSelf(SakuraiArchiveNode root, SakuraiEntryNode parent, VoidPtr address)
 {
     Setup(root, parent, Offset(address));
     OnParse(address);
 }
Ejemplo n.º 9
0
 public void ParseSelf(SakuraiArchiveNode root, SakuraiEntryNode parent, int offset)
 {
     Setup(root, parent, offset);
     OnParse(Address(offset));
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Use this to parse a node of a specific type at the given address.
 /// This will automatically add the node to the entry cache, get its size,
 /// set its offset value, and attach its external entry if it has one.
 /// Be sure to send the proper constructor parameters for the given type
 /// as well, or an error will be thrown.
 /// </summary>
 public static T Parse <T>(SakuraiArchiveNode root, SakuraiEntryNode parent, VoidPtr address, params object[] parameters) where T : SakuraiEntryNode
 {
     return(CommonInit <T>(root, parent, address, parameters));
 }