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; }
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; }
public unkBlock_XXXX(EndianReader reader, int ident) : base(reader, ident) { reader.SeekTo(EOBOffset); }
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(); }
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); }
public Block_2102(EndianReader reader) : base(reader, 0x2102) { unk0 = reader.ReadInt32(); //loads of empty space here reader.SeekTo(EOBOffset); }
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(); }
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); }
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); } }