/// <summary> /// Read the file. /// </summary> /// <param name="r">The reader.</param> public override void Read(FileReader r) { //Read data. r.ByteOrder = ByteOrder.BigEndian; uint numSamples = r.ReadUInt32(); r.ReadUInt32(); //Num nibbles. SampleRate = r.ReadUInt32(); Loops = r.ReadUInt16() > 0; r.ReadUInt16(); //DSP-ADPCM is 0. LoopStart = r.ReadUInt32(); LoopEnd = r.ReadUInt32(); r.ReadUInt32(); //Always 2??? DspAdpcmContext context = r.Read <DspAdpcmContext>(); ushort numChannels = r.ReadUInt16(); BlockSize = (uint)(r.ReadUInt16() * 8); Extended = numChannels > 0; //Add channel 0. //Channels = new List<AudioEncoding>(); //Channels.Add(new DspAdpcmOLD() { Context = context }); r.Align(0x60); //Extra channels. for (int i = 1; i < numChannels; i++) { r.ReadBytes(0x1C); //Channels.Add(new DspAdpcmOLD() { Context = r.Read<DspAdpcmContext>() }); r.Align(0x60); } //Do block reading logic. if (numChannels == 0) { numChannels = 1; } long dataLen = r.Length - r.Position; long channelLen = dataLen / numChannels; if (!Extended) { BlockSize = (uint)channelLen; } uint lastBlockSize = (uint)(channelLen % BlockSize); bool blockCarry = false; if (lastBlockSize == 0) { lastBlockSize = BlockSize; } else { blockCarry = true; } uint numBlocks = (uint)(channelLen / BlockSize + (blockCarry ? 1 : 0)); //Read data. //Audio.Read(r, encodingType, numChannels, numBlocks, BlockSize, blockSamples, lastBlockSize, lastBlockSamples, 0); }
private void Read(FileReader reader) { if (reader.ReadString(4) != "SAHT") { throw new Exception("Wrong magic"); } uint FileSize = reader.ReadUInt32(); uint Offset = reader.ReadUInt32(); if (Offset != 0x10) //EFE uses big endian. WT uses little. { Offset = 0x10; reader.SetByteOrder(true); } uint EntryCount = reader.ReadUInt32(); Console.WriteLine($"FileSize {FileSize} Offset {Offset} EntryCount {EntryCount}"); reader.SeekBegin(Offset); for (int i = 0; i < EntryCount; i++) { HashEntry entry = new HashEntry(); entry.Read(reader); reader.Align(16); if (EntryCount == 4) { Console.WriteLine($"{entry.Name} {entry.Hash} {EntryCount}"); } HashEntries.Add(entry.Hash, entry.Name); } }
/// <summary> /// Read the archive. /// </summary> /// <param name="r">The reader.</param> public override void Read(FileReader r) { //Read the archive. r.ReadUInt32(); r.Align(0x10); //Info block. r.ReadUInt32(); uint num = r.ReadUInt32(); List <Tuple <string, uint, int> > offs = new List <Tuple <string, uint, int> >(); Files = new Dictionary <string, byte[]>(); PackedFiles = new List <string>(); for (uint i = 0; i < num; i++) { offs.Add(new Tuple <string, uint, int>(r.ReadString(), r.ReadUInt32(), r.ReadInt32())); if (r.ReadBoolean()) { PackedFiles.Add(offs[(int)i].Item1); } } //Data block. foreach (var o in offs) { r.Jump(o.Item2); Files.Add(o.Item1, r.ReadBytes(o.Item3)); } }
public override void Read(FileReader reader, Header header) { Padding = reader.ReadBytes(8); long pos = reader.Position; EntryCount = reader.ReadUInt32(); for (int i = 0; i < EntryCount; i++) { LabelGroup group = new LabelGroup(); group.NumberOfLabels = reader.ReadUInt32(); group.Offset = reader.ReadUInt32(); Groups.Add(group); } foreach (LabelGroup group in Groups) { reader.Seek(pos + group.Offset, SeekOrigin.Begin); for (int i = 0; i < group.NumberOfLabels; i++) { LabelEntry entry = new LabelEntry(); entry.Length = reader.ReadByte(); entry.Name = reader.ReadString((int)entry.Length); entry.Index = reader.ReadUInt32(); entry.Checksum = (uint)Groups.IndexOf(group); Labels.Add(entry); } } reader.Align(8); }
public void Load(System.IO.Stream stream) { using (var reader = new FileReader(stream)) { ushort fileFlags = reader.ReadUInt16(); ushort fileMagic = reader.ReadUInt16(); uint fileSize = reader.ReadUInt32(); reader.SetByteOrder(true); while (!reader.EndOfStream) { ushort flags = reader.ReadUInt16(); ushort magic = reader.ReadUInt16(); uint sectionSize = reader.ReadUInt32(); long pos = reader.Position; Console.WriteLine($"Magic {(SectionMagic)magic} sectionSize {sectionSize}"); if (!SectionLookup.ContainsKey((SectionMagic)magic)) { SectionLookup.Add((SectionMagic)magic, new SectionHeader(sectionSize, pos)); } //This section will skip sub sections so don't do that reader.SeekBegin(pos + sectionSize); Nodes.Add(magic.ToString("X")); reader.Align(4); } } }
public static NodeBase[] ReadNodes(FileReader reader, bool align = false) { var nodes = new List <NodeBase>(); Header header; while (true) { if (align) { reader.Align(16); } using (reader.TemporarySeek()) { header = Header.Read(reader); } var node = Create(header.Signature); node.ReadNode(reader, header); nodes.Add(node); if (header.SiblingOffset != Header.NULL_OFFSET) { reader.Seek(header.SiblingOffset); } else { break; } } return(nodes.ToArray()); }
private void ReadSystemGrezzoArchive(FileReader reader) { reader.SeekBegin(FileGroupOffset); for (int i = 0; i < FileGroupCount; i++) { FileGroups.Add(new SystemFileGroup(reader)); reader.Align(0x20); } reader.BaseStream.Position = FileGroups.Min(x => ((SystemFileGroup)x).SubTableOffset); byte[] entries = reader.ReadBytes((int)FileInfoOffset - (int)reader.BaseStream.Position); reader.SeekBegin(FileInfoOffset); for (int i = 0; i < FileGroupCount; i++) { for (int f = 0; f < ((SystemFileGroup)FileGroups[i]).FileCount; f++) { GarFileInfos.Add(new SystemGarFileInfo(reader)); ((SystemGarFileInfo)GarFileInfos.Last()).ext = ((SystemFileGroup)FileGroups[i]).Name; } } reader.SeekBegin(DataOffset); for (int i = 0; i < GarFileInfos.Count; i++) { var info = (SystemGarFileInfo)GarFileInfos[i]; Files.Add(new FileEntry() { OpenFileFormatOnLoad = info.ext == "csab", FileName = $"{info.Name}.{info.ext}", FileData = new SubStream(reader.BaseStream, info.FileOffset, info.FileSize) }); } }
public void Read(FileReader reader) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; Magic = reader.ReadString(4, Encoding.ASCII); if (Magic == "EFCC") { reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; } uint Version = reader.ReadUInt32(); ushort EntryCount = reader.ReadUInt16(); ushort StringCount = reader.ReadUInt16(); ushort SlotSpecificDataCount = reader.ReadUInt16(); ushort Padding = reader.ReadUInt16(); for (int i = 0; i < EntryCount; i++) { Entry entry = new Entry(); entry.Read(reader); Entries.Add(entry); } for (int i = 0; i < StringCount; i++) { StringEntries.Add(reader.ReadString(Syroot.BinaryData.BinaryStringFormat.ZeroTerminated)); reader.Align(2); } }
/// <summary> /// Read the archive. /// </summary> /// <param name="r">The reader.</param> public override void Read(FileReader r) { //New file reader. MemoryStream src = new MemoryStream(r.ReadBytes((int)r.Length)); FileReader = new FileReader(src); //Read INFO block. r.Position = 0; FileListing = new Dictionary <string, FileInfo>(); r.ReadUInt32(); r.Align(0x10); r.ReadUInt32(); uint num = r.ReadUInt32(); for (uint i = 0; i < num; i++) { string name = r.ReadString(); FileInfo f = new FileInfo(); f.Offset = r.ReadUInt32(); f.Size = r.ReadInt32(); f.IsPacked = r.ReadBoolean(); FileListing.Add(name, f); } }
public void Load(System.IO.Stream stream) { using (var reader = new FileReader(stream)) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; reader.ReadSignature(4, "pack"); uint FileCount = reader.ReadUInt32(); uint OffsetStringPool = reader.ReadUInt32(); uint Alignment = reader.ReadUInt32(); uint FileType = reader.ReadUInt32(); for (int i = 0; i < FileCount; i++) { var file = new FileEntry(); file.Read(reader); files.Add(file); } //Use the header alignment and set the block data reader.Align((int)Alignment); var DataBlockPosition = reader.Position; for (int i = 0; i < files.Count; i++) { reader.Seek(DataBlockPosition + files[i].Offset, System.IO.SeekOrigin.Begin); files[i].FileData = reader.ReadBytes((int)files[i].Size); //Get the string data reader.Seek(DataBlockPosition + OffsetStringPool + files[i].NameOffset, System.IO.SeekOrigin.Begin); files[i].FileName = reader.ReadZeroTerminatedString(); } } }
private Stream CheckCompression(Stream stream) { using (var reader = new FileReader(stream, true)) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; uint unk = reader.ReadUInt32(); try { uint chunkCount = reader.ReadUInt32(); uint unk2 = reader.ReadUInt32(); uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount); //Not very sure about this reader.Align(128); List <byte[]> DecompressedChunks = new List <byte[]>(); //Now search for zlibbed chunks while (!reader.EndOfStream) { uint size = reader.ReadUInt32(); long pos = reader.Position; ushort magic = reader.ReadUInt16(); ///Check zlib magic if (magic == 0x78da) { var data = STLibraryCompression.ZLIB.Decompress(reader.getSection((uint)pos, size)); DecompressedChunks.Add(data); reader.SeekBegin(pos + size); //Seek the compressed size and align it to goto the next chunk reader.Align(128); } else //If the magic check fails, seek back 2. This shouldn't happen, but just incase { reader.Seek(-2); } } //Return the decompressed stream with all chunks combined return(new MemoryStream(Utils.CombineByteArray(DecompressedChunks.ToArray()))); } catch { } } return(stream); }
public void Read(FileReader reader) { ElementCount = reader.ReadUInt32(); DataType = reader.ReadEnum <FaceType>(true); Unknown1 = reader.ReadUInt32(); BufferData = reader.ReadBytes((int)(ElementCount * Stride)); reader.Align(4); }
public void Load(System.IO.Stream stream) { _stream = stream; using (var reader = new FileReader(stream, true)) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; header = reader.ReadStruct <RomfsHeader>(); reader.Align(0x10); byte[] masterHash = reader.ReadBytes((int)header.MasterHashSize); reader.Align(1 << (int)header.Level1BlockSize); Level3Position = reader.Position; Level3Header = reader.ReadStruct <Level3Header>(); reader.SeekBegin(Level3Position + Level3Header.DirectoryMetaDataTableOffset); ReadDirectories(reader, reader.Position, Level3Position + Level3Header.FileMetaDataTableOffset); } }
public void Read(FileReader reader) { reader.SetByteOrder(false); reader.ReadSignature(4, "csab"); uint FileSize = reader.ReadUInt32(); uint versionNum = reader.ReadUInt32(); if (versionNum == 5) { Version = GameVersion.MM3D; } else if (versionNum == 3) { Version = GameVersion.OOT3D; } else { Version = GameVersion.LM3DS; } uint padding = reader.ReadUInt32(); //Unsure if (Version >= GameVersion.MM3D) { uint unknown = reader.ReadUInt32(); //0x42200000 uint unknown2 = reader.ReadUInt32(); //0x42200000 uint unknown3 = reader.ReadUInt32(); //0x42200000 } uint numAnimations = reader.ReadUInt32(); //Unsure uint location = reader.ReadUInt32(); //Unsure uint unknown4 = reader.ReadUInt32(); //0x00 uint unknown5 = reader.ReadUInt32(); //0x00 uint unknown6 = reader.ReadUInt32(); //0x00 uint unknown7 = reader.ReadUInt32(); //0x00 uint unknown8 = reader.ReadUInt32(); //0x00 uint duration = reader.ReadUInt32(); uint nodeCount = reader.ReadUInt32(); uint boneCount = reader.ReadUInt32(); if (nodeCount != boneCount) { throw new Exception("Unexpected bone and node count!"); } ushort[] BoneIndexTable = reader.ReadUInt16s((int)boneCount); reader.Align(4); uint[] nodeOffsets = reader.ReadUInt32s((int)nodeCount); for (int i = 0; i < nodeCount; i++) { reader.SeekBegin(nodeOffsets[i] + 0x18); AnimationNode node = new AnimationNode(); node.Read(reader, Version); Nodes.Add(node); } }
public void Read(HsdfFile header, FileReader reader) { reader.Seek(-4); uint size = reader.ReadUInt32(); long pos = reader.Position; while (reader.Position < pos + size) { uint offset = (uint)(reader.Position - pos); Strings.Add(offset, reader.ReadZeroTerminatedString()); } reader.Align(4); }
private TXE[] ReadTextures(FileReader reader) { uint count = reader.ReadUInt32(); //count reader.Align(32); TXE[] textures = new TXE[count]; for (int i = 0; i < count; i++) { textures[i] = new TXE(); textures[i].Read(reader); textures[i].Name = $"Texture{i}"; } return(textures); }
private void Read(FileReader reader) { reader.ReadSignature(4, "SAHT"); uint FileSize = reader.ReadUInt32(); uint Offset = reader.ReadUInt32(); uint EntryCount = reader.ReadUInt32(); reader.Seek(Offset, System.IO.SeekOrigin.Begin); for (int i = 0; i < EntryCount; i++) { HashEntry entry = new HashEntry(); entry.Read(reader); reader.Align(16); HashEntries.Add(entry); } ToTextFile(); }
public void Read(FileReader reader) { reader.SetByteOrder(true); ImageHeader = reader.ReadStruct <Header>(); reader.Align(32); Width = ImageHeader.Width; Height = ImageHeader.Height; MipCount = 1; Console.WriteLine($"Width {Width} Height {Height}"); var format = FormatsTXE[ImageHeader.ImageFormat]; ImageHeader.ImageSize = (uint)Decode_Gamecube.GetDataSize(format, (int)Width, (int)Height); ImageData = reader.ReadBytes((int)ImageHeader.ImageSize); Platform = new GamecubeSwizzle(format); }
public void Load(System.IO.Stream stream) { Text = FileName; //Set this if you want to save the file format CanSave = true; CanReplace = true; ImageKey = "Texture"; SelectedImageKey = "Texture"; //You can add a FileReader with Toolbox.Library.IO namespace using (var reader = new FileReader(stream)) { reader.SetByteOrder(true); Width = reader.ReadUInt16(); Height = reader.ReadUInt16(); Unknown = reader.ReadInt16(); //Turn this format into a common format used by this tool ushort texFormat = reader.ReadUInt16(); Format = FormatsTXE[texFormat]; int ImageSize = reader.ReadInt32(); //Unsure //Lets set our method of decoding PlatformSwizzle = PlatformSwizzle.Platform_Gamecube; reader.Align(32); //Calculate size automatically if ImageSize is 0 if (ImageSize == 0) { ImageSize = (int)reader.BaseStream.Length - (int)reader.Position; } ImageData = reader.ReadBytes(ImageSize); Text = FileName; } }
/// <summary> /// Read the header. /// </summary> /// <param name="r">The reader.</param> public override void Read(FileReader r) { Magic = new string(r.ReadChars(4)); r.ByteOrder = ByteOrder.BigEndian; r.ByteOrder = ByteOrder = r.ReadUInt16() == 0xFEFF ?ByteOrder.BigEndian : ByteOrder.LittleEndian; r.ReadUInt16(); //Version is always constant. FileSize = r.ReadUInt32(); HeaderSize = r.ReadUInt16(); ushort numBlocks = r.ReadUInt16(); BlockOffsets = new long[numBlocks]; BlockSizes = new long[numBlocks]; if (numBlocks == 3) { r.ReadUInt64(); } for (int i = 0; i < numBlocks; i++) { BlockOffsets[i] = r.ReadUInt32(); BlockSizes[i] = r.ReadUInt32(); } r.Align(0x20); }
public void Read(FileReader reader) { //Gather a list of hashes from our hash lists var HashList = Hashing.HashNames; reader.SetByteOrder(true); reader.ReadUInt32(); //magic reader.ReadUInt32(); //fileSize //Create a list of all the major sections //The sections are not in order, so we must order them while parsing SectionLookup.Clear(); while (!reader.EndOfStream) { uint magic = reader.ReadUInt32(); uint sectionSize = reader.ReadUInt32(); long pos = reader.Position; if (!SectionLookup.ContainsKey((SectionMagic)magic)) { SectionLookup.Add((SectionMagic)magic, new SectionHeader(sectionSize, pos)); } //This section will skip sub sections so don't do that if (magic != 0x8001B000) { reader.SeekBegin(pos + sectionSize); } if (!IsGamecube) //Align for RLG { reader.Align(4); } } ParseModel(reader); }
public void Load(System.IO.Stream stream) { Text = FileName; using (var reader = new FileReader(stream)) { uint magic = reader.ReadUInt32(); uint audioInfoSize = reader.ReadUInt32(); reader.SeekBegin(48); uint numEntries = reader.ReadUInt32(); uint audioOffset = audioInfoSize + 12; for (int i = 0; i < numEntries; i++) { AudioEntry entry = new AudioEntry(); entry.ImageKey = "bfwav"; entry.SelectedImageKey = "bfwav"; Nodes.Add(entry); entry.HashID = reader.ReadUInt32(); uint alignment = reader.ReadUInt32(); uint AudioSize = reader.ReadUInt32(); uint unk = reader.ReadUInt32(); reader.ReadUInt32(); //0 entry.Text = entry.HashID.ToString("X") + ".wem"; using (reader.TemporarySeek(audioOffset, System.IO.SeekOrigin.Begin)) { reader.Align((int)alignment); entry.AudioData = reader.ReadBytes((int)AudioSize); audioOffset = (uint)reader.Position; } } } }
public Header(FileReader reader, List <FileInfo> files) { reader.SetByteOrder(false); uint magic = reader.ReadUInt32(); uint Version = reader.ReadUInt32(); if (Version != 1) { reader.SetByteOrder(true); } reader.ReadUInt32(); //0 uint alignment = reader.ReadUInt32(); reader.ReadUInt32(); //slightly larger than file size reader.ReadUInt32(); //0 uint dataOffset = reader.ReadUInt32(); uint stringTableOffset = reader.ReadUInt32(); uint stringTableSize = reader.ReadUInt32(); reader.ReadUInt32(); //64 uint unkSectionCount = reader.ReadUInt32(); uint FileCount = reader.ReadUInt32(); reader.ReadUInt32(); //1 reader.ReadUInt32(); //0 reader.ReadUInt32(); //0 reader.ReadUInt32(); //0 //Skip an unknown section that is 32 bytes in size reader.Seek(unkSectionCount * 32); for (int i = 0; i < FileCount; i++) { files.Add(new FileInfo(reader, dataOffset, stringTableOffset)); } //Now read data and align offsets reader.SeekBegin(dataOffset); for (int i = 0; i < FileCount; i++) { files[i].FileName = $"File {i}"; files[i].DataOffset = reader.Position; if (files[i].CompressedSize != 0) { reader.Seek((int)files[i].CompressedSize); } else { reader.Seek((int)files[i].UncompressedSize); } // Console.WriteLine($"{i} {files[i].DataOffset} {files[i].CompressedSize} {files[i].Alignment}"); if (files[i].Alignment != 0) { reader.Align((int)files[i].Alignment); } } //Try to get file names from file formats inside //The string table for this file uses a bunch of ids and not very ideal for viewing for (int i = 0; i < FileCount; i++) { if (files[i].CompressedSize == 0) { continue; } reader.SeekBegin(files[i].DataOffset); var data = reader.ReadBytes((int)files[i].CompressedSize); if (files[i].CompressedSize != 0 && files[i].CompressedSize != files[i].UncompressedSize && data[0] == 0x78 && data[1] == 0x5E) { data = STLibraryCompression.ZLIB.Decompress(data); } using (var dataReader = new FileReader(data)) { if (dataReader.CheckSignature(4, "FRES") || dataReader.CheckSignature(4, "BNTX")) { dataReader.SetByteOrder(false); dataReader.SeekBegin(16); uint fileNameOffset = dataReader.ReadUInt32(); dataReader.SeekBegin(fileNameOffset); files[i].FileName = dataReader.ReadZeroTerminatedString(); } } } }
public void Read(FileReader reader, Header header) { long pos = reader.Position; Console.WriteLine("pos " + pos); TotalTextureSize = reader.ReadUInt32(); //Including header PaletteSize = reader.ReadUInt32(); //Used in older versions ImageSize = reader.ReadUInt32(); HeaderSize = reader.ReadUInt16(); PaletteCount = reader.ReadUInt16(); //Used in older versions OldFormat = reader.ReadByte(); //Used in older versions MipCount = reader.ReadByte(); PaletteFormat = reader.ReadByte(); //Used in older versions NutFormat = reader.ReadByte(); Format = SetFormat(NutFormat); Width = reader.ReadUInt16(); Height = reader.ReadUInt16(); uint Unknown = reader.ReadUInt32(); //Maybe related to 3D depth size uint Flags = reader.ReadUInt32(); //Determine when to use cube maps uint dataOffset = 0; if (header.IsNTP3) { if (header.Version < 0x0200) { dataOffset = HeaderSize; uint padding2 = reader.ReadUInt32(); } else if (header.Version >= 0x0200) { dataOffset = reader.ReadUInt32(); } } else { dataOffset = reader.ReadUInt32(); } uint mipOffset = reader.ReadUInt32(); uint gtxHeaderOffset = reader.ReadUInt32(); uint padding = reader.ReadUInt32(); //Could be an offset to an unused section? uint cubeMapSize1 = 0; uint cubeMapSize2 = 0; if ((Flags & (uint)DDS.DDSCAPS2.CUBEMAP) == (uint)DDS.DDSCAPS2.CUBEMAP) { //Only supporting all six faces if ((Flags & (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES) == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES) { IsCubeMap = true; ArrayCount = 6; } else { throw new NotImplementedException($"Unsupported cubemap face amount for texture."); } } if (IsCubeMap) { cubeMapSize1 = reader.ReadUInt32(); cubeMapSize2 = reader.ReadUInt32(); uint unk = reader.ReadUInt32(); uint unk2 = reader.ReadUInt32(); } ImageSizes = new uint[MipCount]; uint MipBlockSize = 0; if (MipCount == 1) { if (IsCubeMap) { ImageSizes[0] = cubeMapSize1; } else { ImageSizes[0] = ImageSize; } } else { if (header.IsNTP3) { ImageSizes = reader.ReadUInt32s((int)MipCount); } else { ImageSizes[0] = reader.ReadUInt32(); MipBlockSize = reader.ReadUInt32(); reader.ReadUInt32s((int)MipCount - 2); //Padding / Unused } reader.Align(16); } ExternalData = new EXT(); ExternalData.Read(reader, header.IsNTP3); GIDXHeaderData = new GIDX(); GIDXHeaderData.Read(reader, header.IsNTP3); Text = GIDXHeaderData.HashID.ToString(); if (dataOffset != 0) { using (reader.TemporarySeek(dataOffset + pos, System.IO.SeekOrigin.Begin)) { if (header.IsNTP3) { Data = reader.ReadBytes((int)ImageSize); } else { Data = reader.ReadBytes((int)ImageSizes[0]); //Mip maps are seperate for GX2 } } } if (mipOffset != 0) { using (reader.TemporarySeek(mipOffset + pos, System.IO.SeekOrigin.Begin)) { MipData = reader.ReadBytes((int)MipBlockSize); } } if (gtxHeaderOffset != 0) { using (reader.TemporarySeek(gtxHeaderOffset + pos, System.IO.SeekOrigin.Begin)) { //Now here is where the GX2 header starts Gx2HeaderData = new NutGX2Surface(); Gx2HeaderData.Read(reader); Gx2HeaderData.data = Data; Gx2HeaderData.mipData = MipData; Format = Bfres.Structs.FTEX.ConvertFromGx2Format((GX2SurfaceFormat)Gx2HeaderData.format); } } //Seek back for next image reader.Seek(pos + HeaderSize, System.IO.SeekOrigin.Begin); }
public void Read(FileReader reader) { Label1 = new LBL1(); NLI1 = new NLI1(); Text2 = new TXT2(); reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; reader.ReadSignature(8, "MsgStdBn"); ByteOrderMark = reader.ReadUInt16(); reader.CheckByteOrderMark(ByteOrderMark); IsBigEndian = reader.IsBigEndian; Padding = reader.ReadUInt16(); byte encoding = reader.ReadByte(); Version = reader.ReadByte(); ushort SectionCount = reader.ReadUInt16(); Unknown = reader.ReadUInt16(); uint FileSize = reader.ReadUInt32(); Reserved = reader.ReadBytes(10); if (encoding == 0x00) { StringEncoding = Encoding.UTF8; } else if (reader.IsBigEndian) { StringEncoding = Encoding.BigEndianUnicode; } else { StringEncoding = Encoding.Unicode; } for (int i = 0; i < SectionCount; i++) { long pos = reader.Position; string Signature = reader.ReadString(4, Encoding.ASCII); uint SectionSize = reader.ReadUInt32(); Console.WriteLine("Signature " + Signature); switch (Signature) { case "NLI1": NLI1 = new NLI1(); NLI1.Signature = Signature; NLI1.Read(reader, this); entries.Add(NLI1); break; case "TXT2": Text2 = new TXT2(); Text2.Signature = Signature; Text2.Read(reader, this); entries.Add(Text2); break; case "LBL1": Label1 = new LBL1(); Label1.Signature = Signature; Label1.Read(reader, this); entries.Add(Label1); break; case "ATR1": case "ATO1": case "TSY1": default: MSBTEntry entry = new MSBTEntry(); entry.Signature = Signature; entry.Padding = reader.ReadBytes(8); entry.Data = reader.ReadBytes((int)SectionSize); entries.Add(entry); break; } reader.SeekBegin(pos + SectionSize + 0x10); reader.Align(16); } //Setup labels to text properly if (Label1 != null && Text2 != null) { foreach (var label in Label1.Labels) { label.String = Text2.TextData[(int)label.Index]; } } }
public void Load(System.IO.Stream stream) { Renderer = new Strikers_Renderer(); DrawableContainer.Name = FileName; DrawableContainer.Drawables.Add(Renderer); IsGamecube = Utils.GetExtension(FileName) == ".glg"; Text = FileName; using (var reader = new FileReader(stream)) { reader.SetByteOrder(true); reader.ReadUInt32(); //magic reader.ReadUInt32(); //fileSize //Create a list of all the major sections //The sections are not in order, so we must order them while parsing Dictionary <SectionMagic, SectionHeader> SectionLookup = new Dictionary <SectionMagic, SectionHeader>(); while (!reader.EndOfStream) { uint magic = reader.ReadUInt32(); uint sectionSize = reader.ReadUInt32(); long pos = reader.Position; Console.WriteLine($"Magic {(SectionMagic)magic} sectionSize {sectionSize}"); if (!SectionLookup.ContainsKey((SectionMagic)magic)) { SectionLookup.Add((SectionMagic)magic, new SectionHeader(sectionSize, pos)); } //This section will skip sub sections so don't do that if (magic != 0x8001B000) { reader.SeekBegin(pos + sectionSize); } if (!IsGamecube) { reader.Align(4); } } var HashList = NLG_Common.HashNames; //Now read our model properly //First get our model info Matrix4 TransformMatrix = Matrix4.Identity; uint totalNumMeshes = 0; uint modelSize = 12; if (IsGamecube) { modelSize = 16; } if (SectionLookup.ContainsKey(SectionMagic.ModelData)) { var modelHeader = SectionLookup[SectionMagic.ModelData]; for (int m = 0; m < modelHeader.Size / modelSize; m++) { reader.SeekBegin(modelHeader.Position + (m * modelSize)); if (IsGamecube) { totalNumMeshes += reader.ReadUInt32(); reader.ReadUInt32(); } else { reader.ReadUInt32(); totalNumMeshes += reader.ReadUInt32(); } } } uint meshIndex = 0; if (SectionLookup.ContainsKey(SectionMagic.ModelData)) { var modelHeader = SectionLookup[SectionMagic.ModelData]; reader.SeekBegin(modelHeader.Position); uint numModels = modelHeader.Size / modelSize; uint hashId = 0; for (int m = 0; m < numModels; m++) { Model model = new Model(); Nodes.Add(model); Models.Add(model); uint numMeshes = 0; reader.SeekBegin(modelHeader.Position + (m * modelSize)); if (IsGamecube) { numMeshes = reader.ReadUInt32(); hashId = reader.ReadUInt32(); } else { hashId = reader.ReadUInt32(); numMeshes = reader.ReadUInt32(); } model.Text = hashId.ToString("X"); if (HashList.ContainsKey(hashId)) { model.Text = HashList[hashId]; } if (SectionLookup.ContainsKey(SectionMagic.MeshData)) { var meshHeader = SectionLookup[SectionMagic.MeshData]; reader.SeekBegin(meshHeader.Position); for (int i = 0; i < numMeshes; i++) { if (IsGamecube) { uint meshSize = meshHeader.Size / totalNumMeshes; reader.SeekBegin(meshHeader.Position + ((meshIndex + i) * meshSize)); } else { reader.SeekBegin(meshHeader.Position + ((meshIndex + i) * 48)); } var mesh = new MeshData(reader, IsGamecube); model.Meshes.Add(mesh); } meshIndex += numMeshes; } } if (SectionLookup.ContainsKey(SectionMagic.MatrixData)) { var matSection = SectionLookup[SectionMagic.MatrixData]; reader.SeekBegin(matSection.Position); TransformMatrix = reader.ReadMatrix4(true); } List <VertexAttribute> Pointers = new List <VertexAttribute>(); if (SectionLookup.ContainsKey(SectionMagic.VertexAttributePointerData)) { var pointerSection = SectionLookup[SectionMagic.VertexAttributePointerData]; reader.SeekBegin(pointerSection.Position); int attributeSize = 8; if (IsGamecube) { attributeSize = 6; } for (int i = 0; i < pointerSection.Size / attributeSize; i++) { VertexAttribute pointer = new VertexAttribute(); if (IsGamecube) { pointer.Offset = reader.ReadUInt32(); pointer.Type = reader.ReadByte(); pointer.Stride = reader.ReadByte(); } else { pointer.Offset = reader.ReadUInt32(); pointer.Type = reader.ReadByte(); pointer.Stride = reader.ReadByte(); reader.ReadUInt16(); } Pointers.Add(pointer); } } int pointerIndex = 0; foreach (var model in Models) { for (int i = 0; i < model.Meshes.Count; i++) { RenderableMeshWrapper mesh = new RenderableMeshWrapper(); model.Nodes.Add(mesh); Renderer.Meshes.Add(mesh); mesh.Text = model.Meshes[i].HashID.ToString("X"); if (HashList.ContainsKey(model.Meshes[i].HashID)) { mesh.Text = HashList[model.Meshes[i].HashID]; } string material = model.Meshes[i].MaterialHashID.ToString("X"); if (HashList.ContainsKey(model.Meshes[i].MaterialHashID)) { material = HashList[model.Meshes[i].MaterialHashID]; } mesh.Nodes.Add(material); var faceSecton = SectionLookup[SectionMagic.IndexData]; var vertexSecton = SectionLookup[SectionMagic.VertexData]; STGenericPolygonGroup polyGroup = new STGenericPolygonGroup(); mesh.PolygonGroups.Add(polyGroup); reader.SeekBegin(faceSecton.Position + model.Meshes[i].IndexStartOffset); List <int> faces = new List <int>(); for (int f = 0; f < model.Meshes[i].IndexCount; f++) { if (model.Meshes[i].IndexFormat == 0) { polyGroup.faces.Add(reader.ReadUInt16()); } else { polyGroup.faces.Add(reader.ReadByte()); } } if (model.Meshes[i].FaceType == MeshData.PolygonType.TriangleStrips) { polyGroup.PrimativeType = STPrimitiveType.TrangleStrips; } else { polyGroup.PrimativeType = STPrimitiveType.Triangles; } if (IsGamecube) { uint size = Pointers[pointerIndex + 1].Offset - Pointers[pointerIndex].Offset; model.Meshes[i].VertexCount = (ushort)(size / Pointers[pointerIndex].Stride); } Console.WriteLine($"mesh {mesh.Text} {model.Meshes[i].VertexCount}"); for (int v = 0; v < model.Meshes[i].VertexCount; v++) { Vertex vert = new Vertex(); mesh.vertices.Add(vert); for (int a = 0; a < model.Meshes[i].NumAttributePointers; a++) { var pointer = Pointers[pointerIndex + a]; reader.SeekBegin(vertexSecton.Position + pointer.Offset + (pointer.Stride * v)); if (pointer.Type == 0) { if (pointer.Stride == 6) { vert.pos = new Vector3(reader.ReadInt16() / 1024f, reader.ReadInt16() / 1024f, reader.ReadInt16() / 1024f); } else if (pointer.Stride == 12) { vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } // vert.pos = Vector3.TransformPosition(vert.pos, TransformMatrix); } if (pointer.Type == 1) { if (pointer.Stride == 3) { vert.nrm = Read_8_8_8_Snorm(reader).Normalized(); } else if (pointer.Stride == 12) { vert.nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } } if (pointer.Type == 3) { vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f); } if (pointer.Type == 0x67) { vert.pos = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } if (pointer.Type == 0xFE) { vert.nrm = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } if (pointer.Type == 0x26) { vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f); } if (pointer.Type == 0xCC) { vert.uv0 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f); } if (pointer.Type == 0x17) { vert.uv1 = new Vector2(reader.ReadUInt16() / 1024f, reader.ReadUInt16() / 1024f); } if (pointer.Type == 0xD4) { vert.boneIds = new List <int>() { reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte() }; } if (pointer.Type == 0xB0) { vert.boneWeights = new List <float>() { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }; } } } mesh.TransformPosition(new Vector3(0), new Vector3(-90, 0, 0), new Vector3(1)); pointerIndex += model.Meshes[i].NumAttributePointers; } for (int i = 0; i < model.Meshes.Count; i++) { if (IsGamecube) { var renderedMesh = (RenderableMeshWrapper)Renderer.Meshes[i]; renderedMesh.Material = new STGenericMaterial(); string diffuseName = model.Meshes[i].TexturHashID.ToString("X"); if (HashList.ContainsKey(model.Meshes[i].TexturHashID)) { diffuseName = HashList[model.Meshes[i].TexturHashID]; } var texUnit = 1; renderedMesh.Material.TextureMaps.Add(new STGenericMatTexture() { textureUnit = texUnit++, Type = STGenericMatTexture.TextureType.Diffuse, Name = diffuseName, }); } if (SectionLookup.ContainsKey(SectionMagic.MaterialData)) { var materialSecton = SectionLookup[SectionMagic.MaterialData]; reader.SeekBegin(materialSecton.Position + model.Meshes[i].MaterialOffset); var renderedMesh = (RenderableMeshWrapper)Renderer.Meshes[i]; renderedMesh.Material = new STGenericMaterial(); switch (model.Meshes[i].MaterailPreset) { case MaterailPresets.EnvDiffuseDamage: { uint diffuseMapHashID = reader.ReadUInt32(); uint diffuseMapParam = reader.ReadUInt32(); string diffuseName = diffuseMapHashID.ToString("X"); if (HashList.ContainsKey(diffuseMapHashID)) { diffuseName = HashList[diffuseMapHashID]; } var texUnit = 1; renderedMesh.Material.TextureMaps.Add(new STGenericMatTexture() { textureUnit = texUnit++, Type = STGenericMatTexture.TextureType.Diffuse, Name = diffuseName, }); } break; default: { uint diffuseMapHashID = reader.ReadUInt32(); string diffuseName = diffuseMapHashID.ToString("X"); if (HashList.ContainsKey(diffuseMapHashID)) { diffuseName = HashList[diffuseMapHashID]; } var texUnit = 1; renderedMesh.Material.TextureMaps.Add(new STGenericMatTexture() { textureUnit = texUnit++, Type = STGenericMatTexture.TextureType.Diffuse, Name = diffuseName, }); } break; } } } } List <BoneListEntry> BoneLists = new List <BoneListEntry>(); List <uint> boneHashOrder = new List <uint>(); TreeNode parentBoneList = new TreeNode("Bone List"); Nodes.Add(parentBoneList); if (SectionLookup.ContainsKey(SectionMagic.SkeletonData)) { var skeletonSection = SectionLookup[SectionMagic.SkeletonData]; reader.SeekBegin(skeletonSection.Position); //Read all sub sections while (reader.Position < skeletonSection.Position + skeletonSection.Size) { uint magic = reader.ReadUInt32(); uint sectionSize = reader.ReadUInt32(); long pos = reader.Position; BoneListEntry entry = new BoneListEntry(); BoneLists.Add(entry); //Bone hashes appear for each mesh if it uses rigging //Meshes index these lists for rigging if ((SectionMagic)magic == SectionMagic.BoneHashes) { TreeNode boneListNode = new TreeNode("Mesh Bone List"); parentBoneList.Nodes.Add(boneListNode); uint numHashes = sectionSize / 4; for (int i = 0; i < numHashes; i++) { entry.Hashes.Add(reader.ReadUInt32()); if (IsGamecube) { reader.ReadUInt32(); } string hashName = entry.Hashes[i].ToString("X"); if (HashList.ContainsKey(entry.Hashes[i])) { hashName = HashList[entry.Hashes[i]]; } boneListNode.Nodes.Add(hashName); } } if ((SectionMagic)magic == SectionMagic.BoneData) { uint numBones = sectionSize / 68; for (int i = 0; i < numBones; i++) { reader.SeekBegin(pos + i * 68); BoneEntry bone = new BoneEntry(); bone.HashID = reader.ReadUInt32(); reader.ReadUInt32(); //unk reader.ReadUInt32(); //unk reader.ReadUInt32(); //unk reader.ReadSingle(); //0 bone.Scale = new Vector3( reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.ReadSingle(); //0 bone.Rotate = new Vector3( reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.ReadSingle(); //0 bone.Translate = new Vector3( reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.ReadSingle(); //1 // bone.Translate = Vector3.TransformPosition(bone.Translate, TransformMatrix); entry.Bones.Add(bone); } } reader.SeekBegin(pos + sectionSize); } } List <BoneEntry> BoneListSorted = new List <BoneEntry>(); foreach (var hash in boneHashOrder) { foreach (var boneList in BoneLists) { foreach (var bone in boneList.Bones) { if (bone.HashID == hash) { BoneListSorted.Add(bone); } } } } STSkeleton skeleton = new STSkeleton(); DrawableContainer.Drawables.Add(skeleton); foreach (var boneList in BoneLists) { foreach (var bone in boneList.Bones) { STBone stBone = new STBone(skeleton); skeleton.bones.Add(stBone); stBone.Text = bone.HashID.ToString("X"); if (HashList.ContainsKey(bone.HashID)) { stBone.Text = HashList[bone.HashID]; } stBone.Position = bone.Translate; stBone.EulerRotation = bone.Rotate; stBone.Scale = new Vector3(0.2f, 0.2f, 0.2f); stBone.RotationType = STBone.BoneRotationType.Euler; } } skeleton.reset(); skeleton.update(); TreeNode skeletonNode = new TreeNode("Skeleton"); Nodes.Add(skeletonNode); foreach (var bone in skeleton.bones) { if (bone.Parent == null) { skeletonNode.Nodes.Add(bone); } } } } }
private void ReadChunkHeader(FileReader reader) { ushort flags = reader.ReadUInt16(); ushort magic = reader.ReadUInt16(); uint size = reader.ReadUInt32(); Console.WriteLine($"ChunkTypes {(ChunkTypes)magic}"); long pos = reader.Position; switch ((ChunkTypes)magic) { case ChunkTypes.AnimStart: CurrentAnimation = new AnimationHeader(); Animations.Add(CurrentAnimation); while (reader.Position < pos + size) { ReadChunkHeader(reader); } break; case ChunkTypes.AnimHeader: CurrentAnimation.ReadHeader(reader); break; case ChunkTypes.AnimName: CurrentAnimation.Name = reader.ReadString((int)size, true); Console.WriteLine($"AnimName {CurrentAnimation.Name}"); break; case ChunkTypes.TrackParam1: CurrentAnimation.Parameters1 = reader.ReadUInt32s((int)size / 4); break; case ChunkTypes.TrackParam2: CurrentAnimation.Parameters2 = reader.ReadUInt32s((int)size / 4); break; case ChunkTypes.TrackParam3: CurrentAnimation.Parameters3 = reader.ReadUInt32s((int)size / 4); break; case ChunkTypes.TrackParam4: CurrentAnimation.Parameters4 = reader.ReadUInt32s((int)size / 4); break; case ChunkTypes.UnknownKeyData: reader.ReadInt16s((int)size / 2); break; case ChunkTypes.UnknownKeyData2: reader.ReadSingles((int)size / 4); break; //Data sections //These are sub sections of the track data start case ChunkTypes.TrackDataStart: while (reader.Position < pos + size) { ReadChunkHeader(reader); } break; case ChunkTypes.RotationKey: for (int i = 0; i < size / 6; i++) { float X = reader.ReadInt16(); float Y = reader.ReadInt16(); float Z = reader.ReadInt16(); } break; case ChunkTypes.TranslationKey: for (int i = 0; i < size / 12; i++) { float X = reader.ReadSingle(); float Y = reader.ReadSingle(); float Z = reader.ReadSingle(); // Console.WriteLine($"key {i} v0 {v0} s0 {s0} s1 {s1}"); } break; case ChunkTypes.IndexedData: break; } reader.SeekBegin(pos + size); reader.Align(4); }
private void Read(FileReader reader) { reader.SetByteOrder(false); reader.ReadSignature(4, "csab"); uint FileSize = reader.ReadUInt32(); uint versionNum = reader.ReadUInt32(); if (versionNum == 5) { Version = GameVersion.MM3D; } else if (versionNum == 3) { Version = GameVersion.OOT3D; } else { Version = GameVersion.LM3DS; } uint padding = reader.ReadUInt32(); //Unsure if (Version >= GameVersion.MM3D) { uint unknown = reader.ReadUInt32(); //0x42200000 uint unknown2 = reader.ReadUInt32(); //0x42200000 uint unknown3 = reader.ReadUInt32(); //0x42200000 } uint numAnimations = reader.ReadUInt32(); //Unsure uint location = reader.ReadUInt32(); //Unsure uint unknown4 = reader.ReadUInt32(); //0x00 uint unknown5 = reader.ReadUInt32(); //0x00 uint unknown6 = reader.ReadUInt32(); //0x00 uint unknown7 = reader.ReadUInt32(); //0x00 uint duration = reader.ReadUInt32(); uint unknown9 = reader.ReadUInt32();//1 uint nodeCount = reader.ReadUInt32(); uint boneCount = reader.ReadUInt32(); ushort[] BoneIndexTable = reader.ReadUInt16s((int)boneCount); reader.Align(4); uint[] nodeOffsets = reader.ReadUInt32s((int)nodeCount); FrameCount = duration; Console.WriteLine($"duration {duration}"); Console.WriteLine($"boneCount {boneCount}"); uint nodeSize = 0x18; if (Version >= GameVersion.MM3D) { nodeSize = 0x24; } for (int i = 0; i < nodeCount; i++) { reader.SeekBegin(nodeOffsets[i] + nodeSize); AnimationNode node = new AnimationNode(); node.Read(reader, Version); AnimGroups.Add(node); } }