示例#1
0
        public Vertex(EndianReader reader, XmlNode formatNode)
            : this()
        {
            if (!formatNode.HasChildNodes)
                throw new NotSupportedException(formatNode.Attributes["type"].Value + ":" + formatNode.Attributes["name"].Value + " has an empty definition.");
            
            var origin = (int)reader.Position;

            foreach (XmlNode val in formatNode.ChildNodes)
            {
                reader.SeekTo(origin + Convert.ToInt32(val.Attributes["offset"].Value, 16));
                Values.Add(new VertexValue(val, reader));
            }

            FormatName = formatNode.Attributes["name"].Value;
        }
示例#2
0
        public UVDataBlock_3001(EndianReader reader, bool loadMesh, Vertex[] Vertices)
            : base(reader, 0x3001)
        {
            DataCount = reader.ReadInt32(); //vCount

            x2E00 = reader.ReadInt16(); //2E00
            reader.EndianType = EndianFormat.BigEndian;

            unkUV0 = reader.ReadInt16(); //flags? 0x1C00 when world
            unkUV1 = reader.ReadByte();
            unkUV2 = reader.ReadByte();
            unkUV3 = reader.ReadByte();
            unkUV4 = reader.ReadByte(); //0x00 when world, else 0x20
            DataSize = reader.ReadByte();

            if (!loadMesh) reader.SeekTo(EOBOffset);
            else for (int i = 0; i < DataCount; i++)
            {
                Vector tex0 = new Vector();

                #region switch
                switch (DataSize)
                {
                    case 8:
                        tex0 = Vector.FromUByteN4(reader.ReadUInt32());
                        reader.Skip(0);
                        break;
                    case 12:
                        reader.Skip(4);
                        break;
                    case 16:
                        reader.Skip(12);
                        break;
                    case 20:
                        reader.Skip(16);
                        break;
                    case 24:
                        reader.Skip(16);
                        break;
                    case 28:
                        reader.Skip(20);
                        break;
                    case 32:
                        reader.Skip(16);
                        break;
                    case 36:
                        reader.Skip(24);
                        break;
                    case 44:
                        reader.Skip(28);
                        break;
                }
                #endregion

                int u = reader.ReadInt16();
                int v = reader.ReadInt16();

                //var tex0 = new RealQuat(((float)a + (float)0) / (float)0xFFFF, ((float)b + (float)0) / (float)0xFFFF);
                var tex1 = new Vector((float)u / (float)(0x7FFF), (float)v / (float)(0x7FFF));

                #region switch
                switch (DataSize)
                {
                    case 8:
                        reader.Skip(0);
                        break;
                    case 12:
                        reader.Skip(4);
                        break;
                    case 16:
                        reader.Skip(0);
                        break;
                    case 20:
                        reader.Skip(0);
                        break;
                    case 24:
                        reader.Skip(4);
                        break;
                    case 28:
                        reader.Skip(4);
                        break;
                    case 32:
                        reader.Skip(12);
                        break;
                    case 36:
                        reader.Skip(8);
                        break;
                    case 44:
                        reader.Skip(12);
                        break;
                }
                #endregion

                //Vertices[i].Values.Add(new VertexValue(tex0, 0, "normal", 0));
                Vertices[i].Values.Add(new VertexValue(tex1, VertexValue.ValueType.Int16_N2, "texcoords", 0));
            }

            reader.EndianType = EndianFormat.LittleEndian;
        }
示例#3
0
 public unkBlock_XXXX(EndianReader reader, int ident)
     : base(reader, ident)
 {
     reader.SeekTo(EOBOffset);
 }
示例#4
0
        public IndexBlock_F200(EndianReader reader, bool loadMesh)
            : base(reader, 0xF200)
        {
            DataCount = reader.ReadInt32();
            Data = new int[DataCount * 3];
            if (DataCount == 0) return;

            if (!loadMesh) reader.SeekTo(EOBOffset);
            else for (int i = 0; i < DataCount * 3; i++)
                    Data[i] = reader.ReadUInt16();
        }
示例#5
0
        public int[] unkList; //cumulative face count per node

        #endregion Fields

        #region Constructors

        public Block_2202(EndianReader reader, int count)
            : base(reader, 0x2202)
        {
            unk0 = reader.ReadInt32();

            unk1 = reader.ReadInt32();
            unk2 = reader.ReadInt32();
            unk3 = reader.ReadInt32();

            unkList = new int[count];
            for (int i = 0; i < count; i++) unkList[i] = reader.ReadInt32();

            reader.SeekTo(EOBOffset);
        }
示例#6
0
        public Block_2102(EndianReader reader)
            : base(reader, 0x2102)
        {
            unk0 = reader.ReadInt32();

            //loads of empty space here

            reader.SeekTo(EOBOffset);
        }
示例#7
0
        public int unk0, unk1; //min/max?

        #endregion Fields

        #region Constructors

        public Block_0F03(EndianReader reader)
            : base(reader, 0x0F03)
        {
            unk0 = reader.ReadInt32();
            unk1 = reader.ReadInt32();

            reader.SeekTo(EOBOffset);
            return;

            //reader.ReadSingle();
            //reader.ReadSingle();
            //reader.ReadSingle();
            //reader.ReadInt16();
            //reader.ReadSingle();
            //reader.ReadSingle();
            //reader.ReadSingle();
            //reader.ReadSingle(); //???
            //reader.ReadInt32();
        }
示例#8
0
        public VertexBlock_F100(EndianReader reader, bool loadMesh, int geomUnk01)
            : base(reader, 0xF100)
        {
            DataCount = reader.ReadInt32();
            Data = new Vertex[DataCount];
            if (DataCount == 0) return;

            if (geomUnk01 != 134 && geomUnk01 != 142)
            {
                CentreX = reader.ReadInt16();
                CentreY = reader.ReadInt16();
                CentreZ = reader.ReadInt16();
                RadiusX = reader.ReadInt16();
                RadiusY = reader.ReadInt16();
                RadiusZ = reader.ReadInt16();
            }

            if (!loadMesh) reader.SeekTo(EOBOffset);
            else for (int i = 0; i < DataCount; i++)
            {
                Vertex v;

                if (geomUnk01 == 134 || geomUnk01 == 142)
                {
                    v = new Vertex() { FormatName = "S3D_World" };
                    var data = new Vector(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                    v.Values.Add(new VertexValue(data, VertexValue.ValueType.Float32_3, "position", 0));
                }
                else
                {
                    v = new Vertex() { FormatName = "S3D_Compressed" };
                    var data = new Vector(reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16(), reader.ReadInt16());
                    v.Values.Add(new VertexValue(data, VertexValue.ValueType.Int16_N4, "position", 0));
                }
                Data[i] = v;
            }
        }
            public Submesh(EndianReader reader)
            {
                reader.ReadInt16(); //0x0501
                reader.ReadInt32(); //EOB offset
                FaceStart = reader.ReadInt32();
                FaceLength = reader.ReadInt32();
                reader.ReadInt16(); //0x0D01
                reader.ReadInt32(); //EOB offset
                VertStart = reader.ReadInt32();
                VertLength = reader.ReadInt32();

                if (reader.PeekUInt16() == 0x3201)
                    _3201 = new Block_3201(reader);

                if (reader.PeekUInt16() == 0x3401)
                    _3401 = new Block_3401(reader);

                #region Block 0B01
                reader.ReadInt16(); //0x0B01
                var addr = reader.ReadInt32(); //EOB offset
                MaterialCount = reader.ReadInt32();
                reader.ReadInt16(); //0x0E01
                reader.ReadInt32(); //EOB offset
                MaterialIndex = reader.ReadInt32();

                reader.SeekTo(addr);
                #endregion

                _1C01 = new Block_1C01(reader);

                _2001 = new Block_2001(reader);

                if (reader.PeekUInt16() == 0x2801)
                    _2801 = new Block_2801(reader);

                reader.ReadInt16(); //0100
                reader.ReadInt32(); //address to next
            }
        private void ReadGeomBlocks(EndianReader reader, bool loadmesh)
        {
            if (reader.PeekUInt16() == 0x2901)
                _2901 = new Block_2901(reader);

            _2E01 = new Block_2E01(reader);

            if(_2901 != null)
            {
                isInheritor = true;

                if (reader.PeekUInt16() == 0x3501)
                    _3501 = new Block_3501(reader);

                reader.ReadInt16(); //2301
                reader.ReadInt32(); //EOB offset

                if (reader.PeekUInt16() == 0x3101)
                {
                    reader.ReadInt16(); //3101
                    reader.ReadInt32(); //EOB offset
                }

                reader.ReadInt16(); //2A01
                reader.ReadInt32(); //EOB offset
            }
            else
            {
                Vertices = new VertexBlock_F100(reader, loadmesh, _2E01.geomUnk01);

                if (_2E01.geomUnk01 != 0 && _2E01.geomUnk01 != 3)
                {
                    _3001 = new UVDataBlock_3001(reader, loadmesh, Vertices.Data);
                    reader.SeekTo(_3001.EOBOffset); //failsafe
                }

                Indices = new IndexBlock_F200(reader, loadmesh);
            }

            BoundingBox = new BoundsBlock_1D01(reader);

            #region Block F800
            reader.ReadInt16(); //F800
            reader.ReadInt32(); //EOB address
            reader.ReadInt32(); //FFFFFFFF
            #endregion

            if (reader.PeekUInt16() == 0x2F01)
                _2F01 = new Block_2F01(reader);
        }
示例#11
0
        private void ReadBlocks(EndianReader reader, int size)
        {
            reader.EndianType = EndianFormat.BigEndian;

            int offset = 4 * 3; // Start reading after the header
            long baseOffset = reader.Position - offset; // Start of the RIFX data

            // Read each block in the file
            while (offset < size)
            {
                // Read the block ID and size
                int blockId = reader.ReadInt32();
                int blockSize = reader.ReadInt32();
                offset += 4 * 2;

                // Handle the block
                switch (blockId)
                {
                    case 0x666D7420: // 'fmt '
                        ReadFormatBlock(reader, blockSize);
                        break;

                    case 0x64617461: // 'data'
                        // Don't read anything, just store the info
                        DataOffset = offset;
                        DataSize = blockSize;
                        break;

                    case 0x7365656B: // 'seek'
                        ReadSeekOffsets(reader, blockSize);
                        break;
                }

                // Skip to the next block
                offset += blockSize;
                reader.SeekTo(offset + baseOffset);
            }
        }
        private void ReadFiles(EndianReader reader)
        {
            // The file table comes after the folder list and padding
            reader.SeekTo(FolderListStart + _folderListSize);

            // Align 4
            reader.SeekTo((reader.Position + 3) & ~3);

            // TODO: Load these into separate lists or something to make stuff easier
            ReadFileTable(reader); // Sound banks
            ReadFileTable(reader); // Global files
        }
        private void ReadHeader(EndianReader reader)
        {
            reader.EndianType = EndianFormat.BigEndian;// Endianness = Endian.BigEndian;
            reader.SeekTo(0);

            // Validate the magic number at the beginning
            if (reader.ReadUInt32() != HeaderMagic)
                throw new InvalidOperationException("Invalid sound pack magic");

            reader.Skip(4 * 2); // Skip two unknown uint32s

            // Read the size of the folder list (needed to find the start of the file table)
            _folderListSize = reader.ReadInt32();
        }
        private void ReadFolderTable(EndianReader reader)
        {
            // Seek to the beginning of the folder list
            reader.EndianType = EndianFormat.BigEndian;
            reader.SeekTo(FolderListStart);

            // Read the number of folders
            int folderCount = reader.ReadInt32();

            // Sort the folders into a list sorted by offset
            SortedList<int, int> folderOffsets = new SortedList<int, int>(); // Maps offset -> ID, sorted by offset
            for (int i = 0; i < folderCount; i++)
            {
                int offset = reader.ReadInt32();
                int id = reader.ReadInt32();
                folderOffsets.Add(offset, id);
            }

            // Read the folder names and create wrappers for them
            foreach (KeyValuePair<int, int> offset in folderOffsets)
            {
                reader.SeekTo(FolderListStart + offset.Key); // The name's offset is relative to the start of the folder list
                string name = reader.ReadNullTerminatedString();

                _foldersById[offset.Value] = new SoundPackFolder(name);
            }
        }
        private void ReadObjects(EndianReader reader)
        {
            int numObjects = reader.ReadInt32();
            long offset = reader.Position;

            for (int i = 0; i < numObjects; i++)
            {
                // Read the object's header
                ObjectType type = (ObjectType)reader.ReadSByte();
                int size = reader.ReadInt32();
                offset += 5;

                // Read the object's ID
                uint id = reader.ReadUInt32();

                // Read the rest of the object based upon its type
                IWwiseObject obj = null;
                switch (type)
                {
                    case ObjectType.Voice:
                        obj = new SoundBankVoice(reader, id);
                        break;

                    case ObjectType.Action:
                        obj = new SoundBankAction(reader, id);
                        break;

                    case ObjectType.Event:
                        SoundBankEvent ev = new SoundBankEvent(reader, id);
                        _eventsById[ev.ID] = ev;
                        obj = ev;
                        break;

                    case ObjectType.SequenceContainer:
                        obj = new SoundBankSequenceContainer(reader, id);
                        break;

                    case ObjectType.SwitchContainer:
                        obj = new SoundBankSwitchContainer(reader, id);
                        break;

                    case ObjectType.ActorMixer:
                        obj = new SoundBankActorMixer(reader, id);
                        break;

                    case ObjectType.MusicPlaylistContainer:
                        obj = new SoundBankMusicPlaylist(reader, id);
                        break;

                    case ObjectType.MusicSegment:
                        obj = new SoundBankMusicSegment(reader, id);
                        break;

                    case ObjectType.MusicTrack:
                        obj = new SoundBankMusicTrack(reader, id);
                        break;

                    case ObjectType.MusicSwitchContainer:
                        obj = new SoundBankMusicSwitchContainer(reader, id);
                        break;
                }

                // Register the object if something was read
                if (obj != null)
                    _objects.Add(obj);

                // Skip to the next object
                offset += size;
                reader.SeekTo(offset);
            }
        }
        private void ReadBlocks(EndianReader reader, long fileSize)
        {
            EndianFormat defaultEndian = reader.EndianType;

            long startOffset = reader.Position;
            long endOffset = startOffset + fileSize;
            long offset = startOffset;
            while (offset < endOffset)
            {
                // Read the block header
                // The magic value is *always* big-endian, so switch to it temporarily
                reader.EndianType = EndianFormat.BigEndian;
                int blockMagic = reader.ReadInt32();
                reader.EndianType = defaultEndian;

                int blockSize = reader.ReadInt32();
                offset += 8;

                // Process the block based upon its magic value
                switch (blockMagic)
                {
                    case BlockMagic.BKHD:
                        ReadHeader(reader);
                        break;

                    case BlockMagic.DIDX:
                        ReadFiles(reader, blockSize);
                        break;

                    case BlockMagic.DATA:
                        // Just store the offset of this block's contents to the DataOffset field
                        DataOffset = (int)(offset - startOffset);
                        break;

                    case BlockMagic.HIRC:
                        ReadObjects(reader);
                        break;
                }

                // Skip to the next block
                offset += blockSize;
                reader.SeekTo(offset);
            }
        }