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