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