Ejemplo n.º 1
0
        protected virtual void ParseInternals(SakuraiArchiveHeader *hdr)
        {
            sStringTable *stringTable = hdr->StringTable;

            _sectionList = new BindingList <TableEntryNode>();

            //Parse sections
            int numSections = hdr->_sectionCount;

            if (numSections > 0)
            {
                sStringEntry *entries = (sStringEntry *)hdr->Sections;

                List <TableEntryNode> _specialSections = new List <TableEntryNode>();
                for (int i = 0; i < numSections; i++)
                {
                    int    offset = entries[i]._dataOffset;
                    string name   = stringTable->GetString(entries[i]._stringOffset);

                    TableEntryNode section = TableEntryNode.GetRaw(name);

                    //If null, this type of section doesn't have a dedicated class
                    if (section == null)
                    {
                        //Have the inheriting class handle it.
                        //Initialize the node with Parse() in here!!!
                        section = GetTableEntryNode(name, i);

                        //Still unhandled, so initialize as raw
                        if (section == null)
                        {
                            section = Parse <RawDataNode>(offset);
                        }
                    }
                    else
                    {
                        _specialSections.Add(section);
                    }

                    section._name  = name;
                    section._index = i;
                    section.DataOffsets.Add(offset);

                    _sectionList.Add(section);
                }

                //Now parse any dedicated-class nodes that may reference other sections.
                foreach (TableEntryNode section in _specialSections)
                {
                    section.ParseSelf(this, null, section.DataOffsets[0]);
                }

                HandleSpecialSections(_specialSections);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Reads external subroutine references
        /// </summary>
        private void ParseExternals(SakuraiArchiveHeader *hdr)
        {
            sStringTable *stringTable = hdr->StringTable;

            //Parse references
            int numRefs = hdr->_externalSubRoutineCount;

            if (numRefs > 0)
            {
                sStringEntry *entries = (sStringEntry *)hdr->ExternalSubRoutines;
                for (int i = 0; i < numRefs; i++)
                {
                    TableEntryNode e = Parse <TableEntryNode>(entries[i]._dataOffset);
                    e._name = stringTable->GetString(entries[i]._stringOffset);
                    _referenceList.Add(e);
                }
            }
        }
Ejemplo n.º 3
0
        public override bool OnInitialize()
        {
            //Start initializing.
            //This enables some functions for use.
            _initializing = true;

            //Get structs
            MovesetHeader *hdr         = (MovesetHeader *)WorkingUncompressed.Address;
            sStringTable * stringTable = hdr->StringTable;

            _dataSize = hdr->_fileSize;

            //Create lists
            _subRoutines        = new BindingList <Script>();
            _commonSubRoutines  = new BindingList <Script>();
            _referenceList      = new BindingList <ExternalEntry>();
            _sectionList        = new BindingList <ExternalEntry>();
            _lookupSizes        = new SortedList <int, int>();
            _actions            = new BindingList <ActionEntry>();
            _entryCache         = new SortedDictionary <int, MovesetEntry>();
            _postProcessEntries = new List <MovesetEntry>();
            _scriptOffsets      = new List <List <int> > [5];
            for (int i = 0; i < 5; i++)
            {
                _scriptOffsets[i] = new List <List <int> >();
                for (int x = 0; x < (i == 0 ? 2 : i == 1 ? 4 : 1); x++)
                {
                    _scriptOffsets[i].Add(new List <int>());
                }
            }

            //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;

            //Parse references
            int numRefs = hdr->_externalSubRoutineCount;

            if (numRefs > 0)
            {
                sStringEntry *entries = (sStringEntry *)hdr->ExternalSubRoutines;
                for (int i = 0; i < numRefs; i++)
                {
                    ExternalEntry e = Parse <ExternalEntry>(entries[i]._dataOffset);
                    e._name = stringTable->GetString(entries[i]._stringOffset);
                    _referenceList.Add(e);
                }
            }

            //Parse sections
            int numSections = hdr->_dataTableEntryCount;

            if (numSections > 0)
            {
                int           dataIndex = -1;
                sStringEntry *entries   = (sStringEntry *)hdr->DataTable;
                for (int i = 0; i < numSections; i++)
                {
                    ExternalEntry e    = null;
                    int           off  = entries[i]._dataOffset;
                    string        name = stringTable->GetString(entries[i]._stringOffset);
                    switch (name)
                    {
                    //Don't parse data sections until the very end
                    case "data":
                    case "dataCommon":
                        dataIndex = i;
                        _sectionList.Add(null);
                        continue;

                    //case "animParam":
                    //    e = _animParam = Parse<AnimParamSection>(off);
                    //    break;
                    //case "subParam":
                    //    e = _subParam = Parse<SubParamSection>(off);
                    //    break;
                    default:
                        if (name.Contains("AnimCmd"))
                        {
                            e = Parse <Script>(off);
                            _commonSubRoutines.Add(e as Script);
                        }
                        else
                        {
                            e = Parse <RawData>(off);
                        }
                        break;
                    }
                    e.DataOffsets.Add(off);
                    e._name = name;
                    _sectionList.Add(e);
                }

                if (dataIndex >= 0)
                {
                    int    off  = entries[dataIndex]._dataOffset;
                    string name = stringTable->GetString(entries[dataIndex]._stringOffset);
                    switch (name)
                    {
                    case "data":
                        _data = Parse <DataSection>(off);
                        _data.DataOffsets.Add(off);
                        _data._name             = name;
                        _sectionList[dataIndex] = _data;
                        break;

                    case "dataCommon":
                        _dataCommon = Parse <DataCommonSection>(off);
                        _dataCommon.DataOffsets.Add(off);
                        _dataCommon._name       = name;
                        _sectionList[dataIndex] = _dataCommon;
                        break;
                    }
                }
            }

            while (_postProcessEntries.Count > 0)
            {
                //Make a copy of the post process nodes
                MovesetEntry[] arr = _postProcessEntries.ToArray();
                //Clear the original array so it can be repopulated
                _postProcessEntries.Clear();
                //Parse subroutines - may add more entries to post process
                foreach (MovesetEntry e in arr)
                {
                    if (e is EventOffset)
                    {
                        ((EventOffset)e).LinkScript();
                    }
                }
            }

            //Sort subroutines by offset
            _subRoutines = new BindingList <Script>(_subRoutines.OrderBy(x => x._offset).ToList());
            //Add the proper information to the sorted subroutines
            int q = 0;

            foreach (Script s in _subRoutines)
            {
                s._name = String.Format("[{0}] SubRoutine", s._index = q++);
                foreach (EventOffset e in s.ActionRefs)
                {
                    e._offsetInfo = new ScriptOffsetInfo(ListValue.SubRoutines, TypeValue.None, s.Index);
                }
            }

            return(_initializing = false);
        }