Пример #1
0
        private byte[] GetFile(NitroFile sdat, uint fileID)
        {
            uint fatOffset = sdat.Read32(0x20);

            return(sdat.ReadBlock(sdat.Read32(fatOffset + 12 + 16 * fileID),
                                  sdat.Read32(fatOffset + 16 + 16 * fileID)));
        }
Пример #2
0
            public SDAT_File(string name, NitroFile file, uint fileID)
            {
                m_Name = name;
                uint fatOffset = file.Read32(0x20);

                m_Data        = new INitroROMBlock();
                m_Data.m_Data = file.ReadBlock(file.Read32(fatOffset + 12 + 16 * fileID),
                                               file.Read32(fatOffset + 16 + 16 * fileID));
            }
Пример #3
0
        //the last 2 record types don't exist in SM64DS.

        public SDAT(NitroFile file)
        {
            m_File     = file;
            m_Filename = file.m_Name;

            uint symbolOffset = file.Read32(0x10);
            uint infoOffset   = file.Read32(0x18);

            INitroROMBlock symbolBlock = new INitroROMBlock(file.ReadBlock(file.Read32(0x10), file.Read32(0x14)));
            INitroROMBlock infoBlock   = new INitroROMBlock(file.ReadBlock(file.Read32(0x18), file.Read32(0x1c)));
            INitroROMBlock fatBlock    = new INitroROMBlock(file.ReadBlock(file.Read32(0x20), file.Read32(0x24)));

            fatBlock.m_Data = fatBlock.ReadBlock(0x0c, fatBlock.Read32(0x08) * 0x10); //strip the header

            m_Sequences = new Sequence       [symbolBlock.Read32(symbolBlock.Read32(0x08))];
            m_SeqArcs   = new SequenceArchive[symbolBlock.Read32(symbolBlock.Read32(0x0c))];
            m_Banks     = new Bank           [symbolBlock.Read32(symbolBlock.Read32(0x10))];
            m_WaveArcs  = new SWAR           [symbolBlock.Read32(symbolBlock.Read32(0x14))];
            m_Players   = new Player         [symbolBlock.Read32(symbolBlock.Read32(0x18))];
            m_Groups    = new Group          [symbolBlock.Read32(symbolBlock.Read32(0x1c))];

            INitroROMBlock symbSeqBlock = new INitroROMBlock(
                symbolBlock.ReadBlock(symbolBlock.Read32(0x08) + 4, (uint)m_Sequences.Length * 4));
            INitroROMBlock symbSeqArcBlock = new INitroROMBlock(
                symbolBlock.ReadBlock(symbolBlock.Read32(0x0c) + 4, (uint)m_SeqArcs.Length * 8));
            INitroROMBlock symbBankBlock = new INitroROMBlock(
                symbolBlock.ReadBlock(symbolBlock.Read32(0x10) + 4, (uint)m_Banks.Length * 4));
            INitroROMBlock symbWaveBlock = new INitroROMBlock(
                symbolBlock.ReadBlock(symbolBlock.Read32(0x14) + 4, (uint)m_WaveArcs.Length * 4));
            INitroROMBlock symbPlayerBlock = new INitroROMBlock(
                symbolBlock.ReadBlock(symbolBlock.Read32(0x18) + 4, (uint)m_Players.Length * 4));
            INitroROMBlock symbGroupBlock = new INitroROMBlock(
                symbolBlock.ReadBlock(symbolBlock.Read32(0x1c) + 4, (uint)m_Groups.Length * 4));

            INitroROMBlock infoSeqBlock = new INitroROMBlock(
                infoBlock.ReadBlock(infoBlock.Read32(0x08) + 4, (uint)m_Sequences.Length * 4));
            INitroROMBlock infoSeqArcBlock = new INitroROMBlock(
                infoBlock.ReadBlock(infoBlock.Read32(0x0c) + 4, (uint)m_SeqArcs.Length * 4));
            INitroROMBlock infoBankBlock = new INitroROMBlock(
                infoBlock.ReadBlock(infoBlock.Read32(0x10) + 4, (uint)m_Banks.Length * 4));
            INitroROMBlock infoWaveBlock = new INitroROMBlock(
                infoBlock.ReadBlock(infoBlock.Read32(0x14) + 4, (uint)m_WaveArcs.Length * 4));
            INitroROMBlock infoPlayerBlock = new INitroROMBlock(
                infoBlock.ReadBlock(infoBlock.Read32(0x18) + 4, (uint)m_Players.Length * 4));
            INitroROMBlock infoGroupBlock = new INitroROMBlock(
                infoBlock.ReadBlock(infoBlock.Read32(0x1c) + 4, (uint)m_Groups.Length * 4));

            INitroROMBlock buffer = new INitroROMBlock();

            for (uint i = 0; i < m_WaveArcs.Length; ++i)
            {
                if (infoWaveBlock.Read32(4 * i) == 0) //An offset of 0 means "Does Not Exist".
                {
                    continue;
                }

                uint fileID  = infoBlock.Read32(infoWaveBlock.Read32(4 * i));
                SWAR waveArc = new SWAR(symbolBlock.ReadString(symbWaveBlock.Read32(4 * i), -1),
                                        new INitroROMBlock(GetFile(file, fileID)));
                m_WaveArcs[i] = waveArc;
            }

            for (uint i = 0; i < m_Banks.Length; ++i)
            {
                if (infoBankBlock.Read32(4 * i) == 0)
                {
                    continue;
                }

                buffer.m_Data = infoBlock.ReadBlock(infoBankBlock.Read32(4 * i), 12);
                Bank bank = new Bank();
                bank.m_File = new SDAT_File(symbolBlock.ReadString(symbBankBlock.Read32(4 * i), -1),
                                            file, buffer.Read32(0));
                bank.m_WaveArcs = new SWAR[4];
                for (uint j = 0; j < 4; ++j)
                {
                    uint waveArcID = buffer.Read16(4 + 2 * j);
                    bank.m_WaveArcs[j] = waveArcID != 0xffff ? m_WaveArcs[waveArcID] : null;
                }
                m_Banks[i] = bank;
            }

            for (uint i = 0; i < m_Players.Length; ++i)
            {
                buffer.m_Data = infoBlock.ReadBlock(infoPlayerBlock.Read32(4 * i), 8);
                Player player = new Player();
                player.m_Filename   = symbolBlock.ReadString(symbPlayerBlock.Read32(4 * i), -1);
                player.m_MaxNumSeqs = buffer.Read8(0);
                player.m_HeapSize   = buffer.Read32(4);
                m_Players[i]        = player;
            }

            for (uint i = 0; i < m_Sequences.Length; ++i)
            {
                if (infoSeqBlock.Read32(4 * i) == 0)
                {
                    continue;
                }

                buffer.m_Data = infoBlock.ReadBlock(infoSeqBlock.Read32(4 * i), 12);
                Sequence sequence = new Sequence();
                sequence.m_File = new SDAT_File(symbolBlock.ReadString(symbSeqBlock.Read32(4 * i), -1),
                                                file, buffer.Read32(0));
                sequence.m_Bank            = m_Banks[buffer.Read16(4)];
                sequence.m_Volume          = buffer.Read8(6);
                sequence.m_ChannelPriority = buffer.Read8(7);
                sequence.m_PlayerPriority  = buffer.Read8(8);
                sequence.m_Player          = m_Players[buffer.Read8(9)];
                m_Sequences[i]             = sequence;
            }

            for (uint i = 0; i < m_SeqArcs.Length; ++i)
            {
                if (infoSeqArcBlock.Read32(4 * i) == 0)
                {
                    continue;
                }

                uint            fileID = infoBlock.Read32(infoSeqArcBlock.Read32(4 * i));
                SequenceArchive seqArc = new SequenceArchive();
                seqArc.m_Filename  = symbolBlock.ReadString(symbSeqArcBlock.Read32(8 * i), -1);
                seqArc.m_Sequences = new SequenceArchive.Sequence[
                    symbolBlock.Read32(symbSeqArcBlock.Read32(8 * i + 4))];

                INitroROMBlock symbSeqArcSeqBlock = new INitroROMBlock(symbolBlock.ReadBlock(
                                                                           symbSeqArcBlock.Read32(8 * i + 4) + 4, (uint)seqArc.m_Sequences.Length * 4));
                INitroROMBlock ssar = new INitroROMBlock(GetFile(file, fileID));

                INitroROMBlock ssarInfo = new INitroROMBlock(
                    ssar.ReadBlock(0x20, (uint)seqArc.m_Sequences.Length * 12));
                seqArc.m_Data = new INitroROMBlock(
                    ssar.ReadBlock(ssar.Read32(0x18), (uint)ssar.m_Data.Length - ssar.Read32(0x18)));
                for (uint j = 0; j < seqArc.m_Sequences.Length; ++j)
                {
                    buffer.m_Data = ssarInfo.ReadBlock(12 * j, 12);
                    SequenceArchive.Sequence sequence = new SequenceArchive.Sequence();
                    sequence.m_Filename        = symbolBlock.ReadString(symbSeqArcSeqBlock.Read32(4 * j), -1);
                    sequence.m_SeqOffset       = buffer.Read32(0);
                    sequence.m_Bank            = m_Banks[buffer.Read16(4)];
                    sequence.m_Volume          = buffer.Read8(6);
                    sequence.m_ChannelPriority = buffer.Read8(7);
                    sequence.m_PlayerPriority  = buffer.Read8(8);
                    sequence.m_Player          = m_Players[buffer.Read8(9)];
                    seqArc.m_Sequences[j]      = sequence;
                }
                m_SeqArcs[i] = seqArc;
            }

            for (uint i = 0; i < m_Groups.Length; ++i)
            {
                if (infoGroupBlock.Read32(4 * i) == 0)
                {
                    continue;
                }

                Group group = new Group();
                group.m_Entries = new Group.Entry[
                    infoBlock.Read32(infoGroupBlock.Read32(4 * i))];
                buffer.m_Data = infoBlock.ReadBlock(infoGroupBlock.Read32(4 * i) + 4,
                                                    (uint)group.m_Entries.Length * 8);
                group.m_Filename = symbolBlock.ReadString(symbGroupBlock.Read32(4 * i), -1);

                for (uint j = 0; j < group.m_Entries.Length; ++j)
                {
                    uint        index = buffer.Read32(8 * j + 4);
                    Group.Entry entry = new Group.Entry();
                    entry.m_LoadFlag = buffer.Read8(8 * j + 1);
                    switch (buffer.Read8(8 * j))
                    {
                    case 0:
                        entry.m_Record = m_Sequences[index]; break;

                    case 3:
                        entry.m_Record = m_SeqArcs[index]; break;

                    case 1:
                        entry.m_Record = m_Banks[index]; break;

                    case 2:
                        entry.m_Record = m_WaveArcs[index]; break;

                    default:
                        throw new Exception("Group " + i + ", Record " + j +
                                            " has an unexpected record type: " + buffer.Read8(8 * j));
                    }
                    group.m_Entries[j] = entry;
                }
                m_Groups[i] = group;
            }
        }