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 }
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; }
protected override void OnParse(VoidPtr address) { //Initialize lists _paramLists = new List <RawParamList>(); _articles = new List <ArticleNode>(); _subActions = new BindingList <SubActionEntry>(); //Get header values _hdr = *(DataHeader *)address; _unk27 = _hdr.Unknown27; _unk28 = _hdr.Unknown28; _flags1 = _hdr.Flags1; _flags2 = _hdr.Flags2; bint *v = (bint *)address; //Calculate the size of each section using the offsets in order of data appearance int[] sizes = SakuraiArchiveNode.CalculateSizes(_root._dataSize, v, 27, true); //Parse any data related to scripts ParseScripts(v, sizes); //Now parse all other data entries for this character. //If an offset is 0 (except for the attributes), the entry will be set to null. //subaction flags (offset 0) are parsed in ParseScripts _modelVis = Parse <ModelVisibility>(v[1]); _attributes = Parse <AttributeList>(v[2], "Attributes"); _sseAttributes = Parse <AttributeList>(v[3]); _misc = Parse <MiscSectionNode>(v[4]); _commonActionFlags = Parse <EntryList <ActionFlags> >(v[5], 0x10); //action flags (offset 6) are parsed in ParseScripts _unknown7 = Parse <EntryList <Unknown7Entry> >(v[7], 8); _actionInterrupts = Parse <ActionInterrupts>(v[8]); //entry actions (offset 9) are parsed in ParseScripts //exit actions (offset 10) are parsed in ParseScripts _actionPre = Parse <EntryList <ActionPre> >(v[11], 4); //main subactions (offset 12) are parsed in ParseScripts //gfx subactions (offset 13) are parsed in ParseScripts //sfx subactions (offset 14) are parsed in ParseScripts //other subactions (offset 15) are parsed in ParseScripts _anchoredItems = Parse <EntryList <ItemAnchor> >(v[16], sItemAnchor.Size); _gooeyBomb = Parse <EntryList <ItemAnchor> >(v[17], sItemAnchor.Size); _boneRef1 = Parse <EntryList <BoneIndexValue> >(v[18], 4, sizes[18] / 4); _boneRef2 = Parse <BoneReferences2>(v[19]); _entryOverrides = Parse <ActionOverrideList>(v[20]); _exitOverrides = Parse <ActionOverrideList>(v[21]); _unknown22 = Parse <Unknown22>(v[22]); _samusCannon = Parse <EntryList <ItemAnchor> >(v[23], sItemAnchor.Size + 4); _unknown24 = Parse <Unknown24>(v[24]); //Parse extra offsets specific to this character //It appears that the module controls this data ExtraDataOffsets.ParseCharacter(((MovesetNode)_root).Character, this, address + DataHeader.Size); //Sort and set article indices (they are parsed as extra offsets) int u = 0; _articles = _articles.OrderBy(x => x._offset).ToList(); foreach (ArticleNode e in _articles) { e._index = u++; } }
public SakuraiArchiveBuilder(SakuraiArchiveNode node) { _rootNode = node; }