Beispiel #1
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 (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);
        }
        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;
        }