protected override bool OnInitialize() { RSARNode parent; //Find bank entry in rsar if ((_name == null) && ((parent = RSARNode) != null)) { RSARHeader *rsar = parent.Header; RuintList * list = rsar->INFOBlock->Banks; VoidPtr offset = &rsar->INFOBlock->_collection; SYMBHeader *symb = rsar->SYMBBlock; int count = list->_numEntries; for (int i = 0; i < count; i++) { INFOBankEntry *bank = (INFOBankEntry *)list->Get(offset, i); if (bank->_fileId == _fileIndex) { _name = symb->GetStringEntry(bank->_stringId); break; } } } base.OnInitialize(); ParseBlocks(); return(true); }
//[Category("Data Note Event")] //public List<RWSD_NoteEvent> Part2 { get { return _part2; } } //[Category("Data Note Info")] //public List<RWSD_NoteInfo> Part3 { get { return _part3; } } public override bool OnInitialize() { RuintList *list; _part1 = *Header->GetWsdInfo(_offset); list = Header->GetTrackTable(_offset); //Count is always 1 ruint * r = (ruint *)list->Get(_offset, 0); RuintList *l = (RuintList *)r->Offset(_offset); _part2 = *(RWSD_NoteEvent *)l->Get(_offset, 0); list = Header->GetNoteTable(_offset); //Count is always 1 _part3 = *(RWSD_NoteInfo *)list->Get(_offset, 0); if (_name == null) { _name = String.Format("Sound[{0}]", Index); } if (Parent.Parent.Children.Count > 1 && _part3._waveIndex < Parent.Parent.Children[1].Children.Count) { _soundNode = Parent.Parent.Children[1].Children[_part3._waveIndex] as RSARFileAudioNode; } SetSizeInternal((RWSD_DATAEntry.Size + RWSD_WSDEntry.Size + 0x20 + RWSD_NoteEvent.Size + 12 + RWSD_NoteInfo.Size)); return(false); }
public override void OnRebuild(VoidPtr address, int length, bool force) { INFOGroupHeader *header = (INFOGroupHeader *)address; _rebuildAddr = header; RuintList * list = (RuintList *)(address + INFOGroupHeader.Size); INFOGroupEntry *entries = (INFOGroupEntry *)((VoidPtr)list + 4 + _files.Count * 8); header->_entryNum = -1; header->_stringId = _rebuildStringId; //header->_extFilePathRef = 0; //header->_extFilePathRef._dataType = 0; //header->_headerLength = 0; //header->_headerOffset = 0; //header->_waveDataLength = 0; //header->_waveDataOffset = 0; header->_listOffset = (uint)((VoidPtr)list - _rebuildBase); list->_numEntries = _files.Count; int i = 0; foreach (RSARFileNode file in _files) { list->Entries[i] = (uint)((VoidPtr)(&entries[i]) - _rebuildBase); entries[i++]._fileId = file._fileIndex; //entries[i]._dataLength = 0; //entries[i]._dataOffset = 0; //entries[i]._headerLength = 0; //entries[i]._headerOffset = 0; } }
protected override bool OnInitialize() { base.OnInitialize(); _id = Header->_id; _magic = Header->_magic; _unk1 = Header->_unk1; _unk2 = Header->_unk2; //Get file references RSARNode rsar = RSARNode; VoidPtr offset = &rsar.Header->INFOBlock->_collection; //ResourceNode parent = rsar.Children[1]; RuintList *list = Header->GetCollection(offset); int count = list->_numEntries; for (int i = 0; i < count; i++) { INFOGroupEntry *entry = (INFOGroupEntry *)list->Get(offset, i); int id = entry->_fileId; foreach (RSARFileNode node in rsar.Files) { if (id == node._fileIndex) { _files.Add(node); break; } } //_files.Add(rsar.Files[id] as RSARFileNode); } return(false); }
public override bool OnInitialize() { base.OnInitialize(); _entryNo = Header->_entryNum; _extFilePathRef = Header->_extFilePathRef; //Get file references RSARNode rsar = RSARNode; VoidPtr offset = &rsar.Header->INFOBlock->_collection; RuintList *list = Header->GetCollection(offset); int count = list->_numEntries; for (int i = 0; i < count; i++) { INFOGroupEntry *entry = (INFOGroupEntry *)list->Get(offset, i); int id = entry->_fileId; _files.Add(rsar.Files[id] as RSARFileNode); rsar.Files[id]._groups.Add(this); } SetSizeInternal(INFOGroupHeader.Size + 4 + _files.Count * (8 + INFOGroupEntry.Size)); return(false); }
private void GetFiles() { RSARHeader *rsar = Header; //SYMBHeader* symb = rsar->SYMBBlock; //sbyte* offset = (sbyte*)symb + 8; //buint* stringOffsets = symb->StringOffsets; VoidPtr gOffset = (VoidPtr)rsar->INFOBlock + 8; ruint * groups = (ruint *)gOffset; ruint *list = (ruint *)((uint)groups + groups[3] + 4); int count = *((bint *)list - 1); //Get files INFOFileHeader * fileHeader; INFOFileEntry * fileEntry; RuintList * entryList; INFOGroupHeader *group; INFOGroupEntry * gEntry; RuintList * groupList = rsar->INFOBlock->Groups; RSARFileNode n; DataSource source; for (int x = 0; x < count; x++) { fileHeader = (INFOFileHeader *)(gOffset + list[x]); entryList = fileHeader->GetList(gOffset); if (entryList->_numEntries == 0) { //Must be external file. n = new RSARExtFileNode(); source = new DataSource(fileHeader, 0); } else { //use first entry fileEntry = (INFOFileEntry *)entryList->Get(gOffset, 0); //Find group with matching ID group = (INFOGroupHeader *)groupList->Get(gOffset, fileEntry->_groupId); //Find group entry with matching index gEntry = (INFOGroupEntry *)group->GetCollection(gOffset)->Get(gOffset, fileEntry->_index); //Create node and parse source = new DataSource((int)rsar + group->_headerOffset + gEntry->_headerOffset, gEntry->_headerLength); if ((n = NodeFactory.GetRaw(source) as RSARFileNode) == null) { n = new RSARFileNode(); } n._audioSource = new DataSource((int)rsar + group->_dataOffset + gEntry->_dataOffset, gEntry->_dataLength); } n._fileIndex = x; n._parent = this; //This is so that the node won't add itself to the child list. n.Initialize(this, source); _files.Add(n); } }
public override void OnRebuild(VoidPtr address, int length, bool force) { VoidPtr addr = address; RWSD_DATAEntry *header = (RWSD_DATAEntry *)addr; addr += RWSD_DATAEntry.Size; header->_wsdInfo = (int)(addr - _baseAddr); RWSD_WSDEntry *wsd = (RWSD_WSDEntry *)addr; *wsd = _part1; addr += RWSD_WSDEntry.Size; header->_trackTable = (int)(addr - _baseAddr); RuintList *list = (RuintList *)addr; addr += 12; list->_numEntries = 1; list->Entries[0] = (int)(addr - _baseAddr); ruint *r = (ruint *)addr; addr += 8; *r = (int)(addr - _baseAddr); RuintList *list2 = (RuintList *)addr; addr += 12; list2->_numEntries = 1; list2->Entries[0] = (int)(addr - _baseAddr); RWSD_NoteEvent *ev = (RWSD_NoteEvent *)addr; *ev = _part2; addr += RWSD_NoteEvent.Size; header->_noteTable = (int)(addr - _baseAddr); RuintList *list3 = (RuintList *)addr; addr += 12; list3->_numEntries = 1; list3->Entries[0] = (int)(addr - _baseAddr); RWSD_NoteInfo *info = (RWSD_NoteInfo *)addr; *info = _part3; addr += RWSD_NoteInfo.Size; }
public override void OnPopulate() { RWSDHeader * rwsd = Header; RWSD_DATAHeader *data = rwsd->Data; RuintList * list = &data->_list; int count = list->_numEntries; new RWSDDataGroupNode().Initialize(this, Header->Data, Header->_dataLength); if (Header->_waveOffset > 0 && VersionMinor < 3) { new RWSDSoundGroupNode().Initialize(this, Header->Wave, Header->_waveLength); } else if (VersionMinor >= 3) { new RWARNode() { _name = "Audio" } }
public override void OnRebuild(VoidPtr address, int length, bool force) { INFOGroupHeader *header = (INFOGroupHeader *)address; RuintList * list = (RuintList *)(address + INFOGroupHeader.Size); INFOGroupEntry * entries = (INFOGroupEntry *)((VoidPtr)list + 4 + _files.Count * 8); _headerAddr = header; //I believe these two values are set at runtime header->_entryNum = -1; header->_extFilePathRef = new ruint(ruint.RefType.Address, 0, 0); header->_stringId = _rebuildStringId; header->_listOffset = (uint)((VoidPtr)list - _rebuildBase); list->_numEntries = _files.Count; for (int i = 0; i < _files.Count; ++i) { list->Entries[i] = (uint)((VoidPtr)(&entries[i]) - _rebuildBase); entries[i]._fileId = _files[i]._fileIndex; } }
private void GetFiles() { INFOFileHeader * fileHeader; INFOFileEntry * fileEntry; RuintList * entryList; INFOGroupHeader *group; INFOGroupEntry * gEntry; RSARFileNode n; DataSource source; RSARHeader * rsar = Header; //SYMBHeader* symb = rsar->SYMBBlock; //sbyte* offset = (sbyte*)symb + 8; //buint* stringOffsets = symb->StringOffsets; //Get ruint collection from info header VoidPtr infoCollection = rsar->INFOBlock->_collection.Address; //Info has 5 groups: //Sounds 0 //Banks 1 //Types 2 //Files 3 //Groups 4 //Convert to ruint buffer ruint *groups = (ruint *)infoCollection; //Get file ruint list at file offset (groups[3]) RuintList *fileList = (RuintList *)((uint)groups + groups[3]); //Get the info list RuintList *groupList = rsar->INFOBlock->Groups; //Loop through the ruint offsets to get all files for (int x = 0; x < fileList->_numEntries; x++) { //Get the file header for the file info fileHeader = (INFOFileHeader *)(infoCollection + fileList->Entries[x]); entryList = fileHeader->GetList(infoCollection); if (entryList->_numEntries == 0) { //Must be external file. n = new RSARExtFileNode(); source = new DataSource(fileHeader, 0); } else { //Use first entry fileEntry = (INFOFileEntry *)entryList->Get(infoCollection, 0); //Find group with matching ID group = (INFOGroupHeader *)groupList->Get(infoCollection, fileEntry->_groupId); //Find group entry with matching index gEntry = (INFOGroupEntry *)group->GetCollection(infoCollection)->Get(infoCollection, fileEntry->_index); //Create node and parse source = new DataSource((int)rsar + group->_headerOffset + gEntry->_headerOffset, gEntry->_headerLength); if ((n = NodeFactory.GetRaw(source) as RSARFileNode) == null) { n = new RSARFileNode(); } n._audioSource = new DataSource((int)rsar + group->_waveDataOffset + gEntry->_dataOffset, gEntry->_dataLength); n._infoHdr = fileHeader; } n._fileIndex = x; n._parent = this; //This is so that the node won't add itself to the child list. n.Initialize(this, source); _files.Add(n); } //foreach (ResourceNode r in _files) // r.Populate(); }
protected override void OnPopulate() { //RSARNode rsar = RSARNode; //SYMBHeader* symb = null; //RuintList* soundList = null; //INFOSoundEntry** soundIndices = null; //VoidPtr soundOffset = null; //INFOSoundEntry* sEntry; //RWSDHeader* rwsd = Header; //RWSD_DATAHeader* data = rwsd->Data; ////RWSD_WAVEHeader* wave = rwsd->Wave; //RuintList* list = &data->_list; ////RuintList* waveList = &wave->_list; //int count = list->_numEntries; ////Get sound info from RSAR (mainly for names) //if (rsar != null) //{ // symb = rsar.Header->SYMBBlock; // soundOffset = &rsar.Header->INFOBlock->_collection; // soundList = rsar.Header->INFOBlock->Sounds; // soundIndices = (INFOSoundEntry**)Marshal.AllocHGlobal(count * 4); // //int sIndex = 0; // int soundCount = soundList->_numEntries; // for (int i = 0; i < soundCount; i++) // if ((sEntry = (INFOSoundEntry*)soundList->Get(soundOffset, i))->_fileId == _fileIndex) // soundIndices[((INFOSoundPart2*)sEntry->GetPart2(soundOffset))->_soundIndex] = sEntry; //} //for (int i = 0; i < count; i++) //{ // RWSD_DATAEntry* entry = (RWSD_DATAEntry*)list->Get(list, i); // RWSDDataNode node = new RWSDDataNode(); // node.Initialize(this, entry, 0); // //Attach from INFO block // if (soundIndices != null) // { // sEntry = soundIndices[i]; // node._name = symb->GetStringEntry(sEntry->_stringId); // } //} //if (soundIndices != null) // Marshal.FreeHGlobal((IntPtr)soundIndices); //Get labels RSARNode parent; int count = Header->Data->_list._numEntries; if ((_labels == null) && ((parent = RSARNode) != null)) { _labels = new LabelItem[count];// new string[count]; //Get them from RSAR SYMBHeader *symb = parent.Header->SYMBBlock; INFOHeader *info = parent.Header->INFOBlock; VoidPtr offset = &info->_collection; RuintList *soundList = info->Sounds; count = soundList->_numEntries; INFOSoundEntry *entry; for (int i = 0; i < count; i++) { if ((entry = (INFOSoundEntry *)soundList->Get(offset, i))->_fileId == _fileIndex) { _labels[((INFOSoundPart2 *)entry->GetPart2(offset))->_soundIndex] = new LabelItem() { Tag = i, String = symb->GetStringEntry(entry->_stringId) } } } ; } new RWSDGroupNode().Initialize(this, Header->Data, Header->_dataLength); new RWSDGroupNode().Initialize(this, Header->Wave, Header->_waveLength); }
public override void OnPopulate() { RWSDHeader * rwsd = Header; RWSD_DATAHeader *data = rwsd->Data; RuintList * list = &data->_list; int count = list->_numEntries; new RWSDDataGroupNode().Initialize(this, Header->Data, Header->_dataLength); if (Header->_waveOffset > 0 && VersionMinor < 3) { new RWSDSoundGroupNode().Initialize(this, Header->Wave, Header->_waveLength); } else if (VersionMinor >= 3) { new RWARNode { _name = "Audio" }.Initialize(this, _audioSource.Address, _audioSource.Length); } //Get labels RSARNode parent; if (_labels == null && (parent = RSARNode) != null) { //Get them from RSAR SYMBHeader *symb2 = parent.Header->SYMBBlock; INFOHeader *info = parent.Header->INFOBlock; VoidPtr offset = &info->_collection; RuintList *soundList = info->Sounds; int count2 = soundList->_numEntries; _labels = new LabelItem[count2]; INFOSoundEntry *entry; for (uint i = 0; i < count2; i++) { if ((entry = (INFOSoundEntry *)soundList->Get(offset, (int)i))->_fileId == _fileIndex) { int x = ((WaveSoundInfo *)entry->GetSoundInfoRef(offset))->_soundIndex; if (x >= 0 && x < count2) { _labels[x] = new LabelItem { Tag = i, String = symb2->GetStringEntry(entry->_stringId) }; } } } } for (int i = 0; i < count; i++) { string name = "Entry" + i; if (_labels != null && i < _labels.Length) { name = _labels[i].String; } RWSD_DATAEntry *entry = (RWSD_DATAEntry *)list->Get(list, i); RWSDDataNode node = new RWSDDataNode { _name = name }; node._offset = list; node.Initialize(Children[0], entry, 0); } }
internal int EncodeINFOBlock(INFOHeader* header, RSAREntryList entries, RSARNode node) { int len = 0; VoidPtr baseAddr = header->_collection.Address; ruint* values = (ruint*)baseAddr; VoidPtr dataAddr = baseAddr + 0x30; RuintList* entryList; int index = 0; //Set up sound ruint list values[0] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList*)dataAddr; entryList->_numEntries = entries._sounds.Count; dataAddr += entries._sounds.Count * 8 + 4; //Write sound entries foreach (RSAREntryState r in entries._sounds) { r._node._rebuildBase = baseAddr; entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; r._node.Rebuild(dataAddr, r._node._calcSize, true); dataAddr += r._node._calcSize; } index = 0; //Set up bank ruint list values[1] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList*)dataAddr; entryList->_numEntries = entries._banks.Count; dataAddr += entries._banks.Count * 8 + 4; //Write bank entries foreach (RSAREntryState r in entries._banks) { r._node._rebuildBase = baseAddr; entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; r._node.Rebuild(dataAddr, r._node._calcSize, true); dataAddr += r._node._calcSize; } index = 0; //Set up playerInfo ruint list values[2] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList*)dataAddr; entryList->_numEntries = entries._playerInfo.Count; dataAddr += entries._playerInfo.Count * 8 + 4; //Write playerInfo entries foreach (RSAREntryState r in entries._playerInfo) { r._node._rebuildBase = baseAddr; entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; r._node.Rebuild(dataAddr, r._node._calcSize, true); dataAddr += r._node._calcSize; } index = 0; //Set up file ruint list values[3] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList*)dataAddr; entryList->_numEntries = entries._files.Count; dataAddr += entries._files.Count * 8 + 4; //Write file entries foreach (RSARFileNode file in entries._files) { entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; INFOFileHeader* fileHdr = (INFOFileHeader*)dataAddr; dataAddr += INFOFileHeader.Size; RuintList* list = (RuintList*)dataAddr; fileHdr->_entryNumber = -1; if (file is RSARExtFileNode) { //Make an attempt to get current file size uint s = 0; if (file.ExternalFileInfo.Exists) s = (uint)file.ExternalFileInfo.Length; if (file._extFileSize != s && s != 0) file._extFileSize = s; //Shouldn't matter if 0 fileHdr->_headerLen = file._extFileSize; fileHdr->_dataLen = 0; fileHdr->_stringOffset = (uint)((VoidPtr)list - (VoidPtr)baseAddr); sbyte* dPtr = (sbyte*)list; file._extPath.Write(ref dPtr); dataAddr += ((int)((VoidPtr)dPtr - (VoidPtr)dataAddr)).Align(4); fileHdr->_listOffset = (uint)((VoidPtr)dataAddr - (VoidPtr)baseAddr); dataAddr += 4; //Empty list } else { fileHdr->_headerLen = (uint)file._headerLen; fileHdr->_dataLen = (uint)file._audioLen; //fileHdr->_stringOffset = 0; fileHdr->_listOffset = (uint)((VoidPtr)list - (VoidPtr)baseAddr); list->_numEntries = file._groups.Count; INFOFileEntry* fileEntries = (INFOFileEntry*)((VoidPtr)list + 4 + file._groups.Count * 8); int z = 0; List<int> used = new List<int>(); foreach (RSARGroupNode g in file._groups) { list->Entries[z] = (uint)((VoidPtr)(&fileEntries[z]) - baseAddr); fileEntries[z]._groupId = g._rebuildIndex; int[] all = g._files.FindAllOccurences(file); bool done = false; foreach (int i in all) if (!used.Contains(i)) { fileEntries[z]._index = i; used.Add(i); done = true; break; } if (!done) fileEntries[z]._index = g._files.IndexOf(file); z++; } dataAddr = (VoidPtr)fileEntries + file._groups.Count * INFOFileEntry.Size; } } index = 0; //Set up group ruint list values[4] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList*)dataAddr; entryList->_numEntries = entries._groups.Count + 1; dataAddr += (entries._groups.Count + 1) * 8 + 4; //Write group entries foreach (RSAREntryState r in entries._groups) { r._node._rebuildBase = baseAddr; entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; r._node.Rebuild(dataAddr, r._node._calcSize, true); dataAddr += r._node._calcSize; } //Null group at the end entryList->Entries[entries._groups.Count] = (uint)dataAddr - (uint)baseAddr; INFOGroupHeader* grp = (INFOGroupHeader*)dataAddr; node._nullGroup._rebuildAddr = grp; node._nullGroup._rebuildBase = baseAddr; *(bint*)(dataAddr + INFOGroupHeader.Size) = 0; grp->_entryNum = -1; grp->_stringId = -1; //grp->_extFilePathRef = 0; //grp->_extFilePathRef._dataType = 0; grp->_headerLength = 0; grp->_waveDataLength = 0; grp->_headerOffset = grp->_waveDataOffset = _headerLen + _symbLen + _infoLen + _fileLen; grp->_listOffset = (uint)((VoidPtr)(dataAddr + INFOGroupHeader.Size) - baseAddr); dataAddr += INFOGroupHeader.Size; RuintList* l = (RuintList*)dataAddr; INFOGroupEntry* e = (INFOGroupEntry*)((VoidPtr)l + 4 + node._nullGroup.Files.Count * 8); l->_numEntries = node._nullGroup.Files.Count; int y = 0; foreach (RSARFileNode file in node._nullGroup.Files) { l->Entries[y] = (uint)((VoidPtr)(&e[y]) - baseAddr); e[y++]._fileId = file._fileIndex; //entries[i]._dataLength = 0; //entries[i]._dataOffset = 0; //entries[i]._headerLength = 0; //entries[i]._headerOffset = 0; } dataAddr = (VoidPtr)e + node._nullGroup.Files.Count * 0x18; //Write footer values[5] = (uint)dataAddr - (uint)baseAddr; *(INFOFooter*)dataAddr = node.ftr; //Set header header->_header._tag = INFOHeader.Tag; header->_header._length = len = ((int)((dataAddr + INFOFooter.Size) - (baseAddr - 8))).Align(0x20); return len; }
protected override void OnPopulate() { RSARHeader *rsar = Header; INFOHeader *info = Header->INFOBlock; VoidPtr offset = &info->_collection; RuintList * list = (RuintList *)info->_collection[_listIndex]; int count = list->_numEntries; Type t; switch (_listIndex) { case 2: t = typeof(RSARTypeNode); break; //Types case 3: //Files INFOFileHeader * fileHeader; INFOFileEntry * fileEntry; RuintList * entryList; INFOGroupHeader *group; INFOGroupEntry * gEntry; RuintList * groupList = info->Groups; RSARFileNode n; DataSource source; for (int i = 0; i < count; i++) { fileHeader = (INFOFileHeader *)list->Get(offset, i); entryList = fileHeader->GetList(offset); if (entryList->_numEntries == 0) { //Must be external file. n = new RSARExtFileNode(); n._fileIndex = i; n.Initialize(this, fileHeader, 0); } else { //use first entry fileEntry = (INFOFileEntry *)entryList->Get(offset, 0); //Find group with matching ID group = (INFOGroupHeader *)groupList->Get(offset, fileEntry->_groupId); //Find group entry with matching index gEntry = (INFOGroupEntry *)group->GetCollection(offset)->Get(offset, fileEntry->_index); //Create node and parse source = new DataSource((int)rsar + group->_headerOffset + gEntry->_headerOffset, gEntry->_headerLength); if ((n = NodeFactory.GetRaw(source) as RSARFileNode) == null) { n = new RSARFileNode(); } n._audioSource = new DataSource((int)rsar + group->_dataOffset + gEntry->_dataOffset, gEntry->_dataLength); n._fileIndex = i; n.Initialize(this, source); } } return; case 4: t = typeof(RSARGroupNode); break; //Groups default: return; } for (int i = 0; i < count; i++) { ResourceNode node = Activator.CreateInstance(t) as ResourceNode; node.Initialize(this, list->Get(offset, i), 0); } base.OnPopulate(); }
public override void OnPopulate() { //Enumerate entries, attaching them to the files. RSARHeader *rsar = Header; SYMBHeader *symb = rsar->SYMBBlock; sbyte * offset = (sbyte *)symb + 8; buint * stringOffsets = symb->StringOffsets; VoidPtr baseAddr = (VoidPtr)rsar->INFOBlock + 8; ruint * typeList = (ruint *)baseAddr; //Iterate through group types for (int i = 0; i < 5; i++) { _infoCache[i] = new List <RSAREntryNode>(); Type t = null; RuintList *list = (RuintList *)((uint)baseAddr + typeList[i]); sbyte * str, end; switch (i) { case 0: t = typeof(RSARSoundNode); break; case 1: t = typeof(RSARBankNode); break; case 2: t = typeof(RSARPlayerInfoNode); break; case 3: continue; //Files case 4: t = typeof(RSARGroupNode); break; //Last group entry is null } for (int x = 0; x < list->_numEntries; x++) { VoidPtr addr = list->Get(baseAddr, x); ResourceNode parent = this; RSAREntryNode n = Activator.CreateInstance(t) as RSAREntryNode; n._origSource = n._uncompSource = new DataSource(addr, 0); n._infoIndex = x; if (i == 4 && x == list->_numEntries - 1) { n._name = "<null>"; n._parent = this; _nullGroup = n as RSARGroupNode; } else { str = offset + stringOffsets[n.StringId]; for (end = str; *end != 0; end++) { ; } while ((--end > str) && (*end != '_')) { ; } if (end > str) { parent = CreatePath(parent, str, (int)end - (int)str); n._name = new String(end + 1); } else { n._name = new String(str); } } n.Initialize(parent, addr, 0); _infoCache[i].Add(n); } } ftr = *(INFOFooter *)((uint)baseAddr + typeList[5]); foreach (RSARFileNode n in Files) { if (!(n is RSARExtFileNode)) { n.GetName(); } } _rootIds = new int[4]; _symbCache = new List <SYMBMaskEntry> [4]; bint *offsets = (bint *)((VoidPtr)symb + 12); for (int i = 0; i < 4; i++) { _symbCache[i] = new List <SYMBMaskEntry>(); SYMBMaskHeader *hdr = (SYMBMaskHeader *)((VoidPtr)symb + 8 + offsets[i]); //Console.WriteLine("Root Index = " + hdr->_rootId); _rootIds[i] = hdr->_rootId; for (int x = 0; x < hdr->_numEntries; x++) { SYMBMaskEntry *e = &hdr->Entries[x]; _symbCache[i].Add(*e); //Console.WriteLine(String.Format("[{5}] {0}, {1}, {2} - {4}", e->_bit != -1 ? e->_bit.ToString().PadLeft(3) : " ", e->_leftId != -1 ? e->_leftId.ToString().PadLeft(3) : " ", e->_rightId != -1 ? e->_rightId.ToString().PadLeft(3) : " ", e->_index != -1 ? e->_index.ToString().PadLeft(3) : " ", new string(offset + stringOffsets[e->_stringId]), x.ToString().PadLeft(3))); } } //Sort(true); }
internal int EncodeINFOBlock(INFOHeader *header, RSAREntryList entries, RSARNode node) { int len = 0; VoidPtr baseAddr = header->_collection.Address; ruint * values = (ruint *)baseAddr; VoidPtr dataAddr = baseAddr + 0x30; RuintList *entryList; int index = 0; //Set up sound ruint list values[0] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList *)dataAddr; entryList->_numEntries = entries._sounds.Count; dataAddr += entries._sounds.Count * 8 + 4; //Write sound entries foreach (RSAREntryNode r in entries._sounds) { r._rebuildBase = baseAddr; entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; r.Rebuild(dataAddr, r._calcSize, true); dataAddr += r._calcSize; } index = 0; //Set up bank ruint list values[1] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList *)dataAddr; entryList->_numEntries = entries._banks.Count; dataAddr += entries._banks.Count * 8 + 4; //Write bank entries foreach (RSAREntryNode r in entries._banks) { r._rebuildBase = baseAddr; entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; r.Rebuild(dataAddr, r._calcSize, true); dataAddr += r._calcSize; } index = 0; //Set up playerInfo ruint list values[2] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList *)dataAddr; entryList->_numEntries = entries._playerInfo.Count; dataAddr += entries._playerInfo.Count * 8 + 4; //Write playerInfo entries foreach (RSAREntryNode r in entries._playerInfo) { r._rebuildBase = baseAddr; entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; r.Rebuild(dataAddr, r._calcSize, true); dataAddr += r._calcSize; } index = 0; //Set up file ruint list values[3] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList *)dataAddr; entryList->_numEntries = entries._files.Count; dataAddr += entries._files.Count * 8 + 4; //Write file entries foreach (RSARFileNode file in entries._files) { //if (file._groupRefs.Count == 0 && !(file is RSARExtFileNode)) // continue; entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; INFOFileHeader *fileHdr = (INFOFileHeader *)dataAddr; dataAddr += INFOFileHeader.Size; RuintList *list = (RuintList *)dataAddr; fileHdr->_entryNumber = -1; if (file is RSARExtFileNode) { uint extFileSize = 0; //Make an attempt to get current file size if (file.ExternalFileInfo.Exists) { extFileSize = (uint)file.ExternalFileInfo.Length; } if (file._extFileSize != extFileSize && extFileSize != 0) { file._extFileSize = extFileSize; } //Shouldn't matter if 0 fileHdr->_headerLen = file._extFileSize; fileHdr->_dataLen = 0; fileHdr->_stringOffset = (uint)((VoidPtr)list - (VoidPtr)baseAddr); sbyte *dPtr = (sbyte *)list; file._extPath.Write(ref dPtr); dataAddr += ((int)((VoidPtr)dPtr - (VoidPtr)dataAddr)).Align(4); fileHdr->_listOffset = (uint)((VoidPtr)dataAddr - (VoidPtr)baseAddr); dataAddr += 4; //Empty list } else { fileHdr->_headerLen = (uint)file._headerLen; fileHdr->_dataLen = (uint)file._audioLen; //fileHdr->_stringOffset = 0; fileHdr->_listOffset = (uint)((VoidPtr)list - (VoidPtr)baseAddr); list->_numEntries = file._groupRefs.Count; INFOFileEntry *fileEntries = (INFOFileEntry *)((VoidPtr)list + 4 + file._groupRefs.Count * 8); int z = 0; List <int> used = new List <int>(); foreach (RSARGroupNode g in file._groupRefs) { list->Entries[z] = (uint)((VoidPtr)(&fileEntries[z]) - baseAddr); fileEntries[z]._groupId = g._rebuildIndex; int[] all = g._files.FindAllOccurences(file); bool done = false; foreach (int i in all) { if (!used.Contains(i)) { fileEntries[z]._index = i; used.Add(i); done = true; break; } } if (!done) { fileEntries[z]._index = g._files.IndexOf(file); } z++; } dataAddr = (VoidPtr)fileEntries + file._groupRefs.Count * INFOFileEntry.Size; } } index = 0; //Set up group ruint list values[4] = (uint)dataAddr - (uint)baseAddr; entryList = (RuintList *)dataAddr; entryList->_numEntries = entries._groups.Count; dataAddr += entries._groups.Count * 8 + 4; //Write group entries foreach (RSAREntryNode r in entries._groups) { r._rebuildBase = baseAddr; entryList->Entries[index++] = (uint)dataAddr - (uint)baseAddr; r.Rebuild(dataAddr, r._calcSize, true); dataAddr += r._calcSize; } //Write footer values[5] = (uint)dataAddr - (uint)baseAddr; *(INFOFooter *)dataAddr = node._ftr; //Set header header->_header._tag = INFOHeader.Tag; header->_header._length = len = ((int)((dataAddr + INFOFooter.Size) - (baseAddr - 8))).Align(0x20); return(len); }
//public RSARGroupNode _nullGroup; public override void OnPopulate() { //Enumerate entries, attaching them to the files. RSARHeader *rsar = Header; SYMBHeader *symb = rsar->SYMBBlock; sbyte * offset = (sbyte *)symb + 8; buint * stringOffsets = symb->StringOffsets; VoidPtr baseAddr = (VoidPtr)rsar->INFOBlock + 8; ruint * typeList = (ruint *)baseAddr; //Iterate through group types for (int i = 0; i < 5; i++) { Type t = null; switch (i) { case 0: t = typeof(RSARSoundNode); break; case 1: t = typeof(RSARBankNode); break; case 2: t = typeof(RSARPlayerInfoNode); break; case 3: continue; //Files case 4: t = typeof(RSARGroupNode); break; //Last group entry has no name } _infoCache[i] = new List <RSAREntryNode>(); RuintList *list = (RuintList *)((uint)baseAddr + typeList[i]); sbyte * str, end; for (int x = 0; x < list->_numEntries; x++) { VoidPtr addr = list->Get(baseAddr, x); ResourceNode parent = this; RSAREntryNode n = Activator.CreateInstance(t) as RSAREntryNode; n._origSource = n._uncompSource = new DataSource(addr, 0); if (n.StringId >= 0) { str = offset + stringOffsets[n.StringId]; for (end = str; *end != 0; end++) { ; } while ((--end > str) && (*end != '_')) { ; } if (end > str) { parent = CreatePath(parent, str, (int)end - (int)str); n._name = new String(end + 1); } else { n._name = new String(str); } } else { n._name = null; } n._infoIndex = x; n.Initialize(parent, addr, 0); _infoCache[i].Add(n); } _ftr = *(INFOFooter *)((uint)baseAddr + typeList[5]); foreach (RSARFileNode n in Files) { if (!(n is RSARExtFileNode)) { n.GetName(); } } } }