public TextureControl(IPluginHost pluginHost, sBTX0.Texture tex, uint texOffset, string filePath) { InitializeComponent(); sBTX0 btx0 = new sBTX0(); btx0.texture = tex; btx0.file = filePath; btx0.header.offset = new uint[1]; btx0.header.offset[0] = texOffset; this.pluginHost = pluginHost; this.btx0 = btx0; ReadLanguage(); for (int i = 0; i < btx0.texture.texInfo.num_objs; i++) { listTextures.Items.Add(String.Format("{0}: {1}", i.ToString(), btx0.texture.texInfo.names[i])); } for (int i = 0; i < btx0.texture.palInfo.num_objs; i++) { listPalettes.Items.Add(String.Format("{0}: {1}", i.ToString(), btx0.texture.palInfo.names[i])); } listTextures.SelectedIndex = 0; listPalettes.SelectedIndex = 0; listTextures.SelectedIndexChanged += new EventHandler(listTextures_SelectedIndexChanged); listPalettes.SelectedIndexChanged += new EventHandler(listPalettes_SelectedIndexChanged); UpdateTexture(0, 0); }
private static void Write_Info(sBTX0.Texture btx0, string lang) { try { System.Xml.Linq.XElement xml = System.Xml.Linq.XElement.Load(Application.StartupPath + Path.DirectorySeparatorChar + "Plugins" + Path.DirectorySeparatorChar + "3DModelsLang.xml"); xml = xml.Element(lang).Element("BTX0"); Console.WriteLine("<pre><b>" + xml.Element("S01").Value + "</b>"); Console.WriteLine("<u>" + xml.Element("S0D").Value + "</u>"); for (int i = 0; i < btx0.texInfo.num_objs; i++) { sBTX0.Texture.TextInfo texInfo = (sBTX0.Texture.TextInfo)btx0.texInfo.infoBlock.infoData[i]; Console.WriteLine(xml.Element("S0E").Value, i.ToString(), btx0.texInfo.names[i].Trim('\x0')); Console.WriteLine(xml.Element("S0F").Value, texInfo.tex_offset.ToString("x")); Console.WriteLine(xml.Element("S10").Value, texInfo.parameters.ToString("x")); Console.Write(xml.Element("S11").Value, texInfo.repeat_X.ToString(), texInfo.repeat_Y.ToString()); Console.Write(xml.Element("S12").Value, texInfo.flip_X.ToString(), texInfo.flip_Y.ToString()); Console.Write(xml.Element("S13").Value, texInfo.width.ToString(), texInfo.height.ToString()); Console.Write(xml.Element("S14").Value, texInfo.format.ToString(), (TextureFormat)texInfo.format); Console.WriteLine(xml.Element("S15").Value, texInfo.color0.ToString()); Console.Write(xml.Element("S16").Value, texInfo.coord_transf.ToString(), (TextureCoordTransf)texInfo.coord_transf); Console.WriteLine(xml.Element("S17").Value, texInfo.unknown.ToString(), texInfo.unknown2.ToString(), texInfo.unknown3.ToString()); } Console.WriteLine("<u>" + xml.Element("S18").Value + "</u>"); for (int i = 0; i < btx0.palInfo.num_objs; i++) { sBTX0.Texture.PalInfo palInfo = (sBTX0.Texture.PalInfo)btx0.palInfo.infoBlock.infoData[i]; Console.WriteLine(xml.Element("S19").Value, i.ToString(), btx0.palInfo.names[i].Trim('\x0')); Console.Write(xml.Element("S1A").Value, palInfo.palette_offset.ToString("x")); Console.WriteLine(); } Console.WriteLine(xml.Element("S1B").Value + "</pre>"); } catch { throw new NotSupportedException("There was an error reading the language file"); } }
public static void Find_IDs(out int num_tex, out int num_pal, string tex_name, string pal_name, sBTX0.Texture texture) { num_tex = num_pal = 0; for (int i = 0; i < texture.texInfo.num_objs; i++) { if (texture.texInfo.names[i] == tex_name) { num_tex = i; } } for (int i = 0; i < texture.palInfo.num_objs; i++) { if (texture.palInfo.names[i] == pal_name) { num_pal = i; } } }
public static sBTX0 Read(string file, int id, IPluginHost pluginHost) { BinaryReader br = new BinaryReader(File.OpenRead(file)); sBTX0 btx = new sBTX0(); btx.id = id; btx.file = Path.GetTempFileName(); File.Copy(file, btx.file, true); // Read header btx.header.type = br.ReadChars(4); btx.header.constant = br.ReadUInt32(); btx.header.file_size = br.ReadUInt32(); btx.header.header_size = br.ReadUInt16(); btx.header.num_sections = br.ReadUInt16(); btx.header.offset = new uint[btx.header.num_sections]; for (int i = 0; i < btx.header.num_sections; i++) { btx.header.offset[i] = br.ReadUInt32(); } if (btx.header.num_sections > 1) { MessageBox.Show("There are more than one section?\nPlease, report this file"); } #region Read texture sections br.BaseStream.Position = btx.header.offset[0]; sBTX0.Texture tex = new sBTX0.Texture(); // Header tex.header.type = br.ReadChars(4); tex.header.section_size = br.ReadUInt32(); tex.header.padding = br.ReadUInt32(); tex.header.textData_size = br.ReadUInt16(); tex.header.textInfo_offset = br.ReadUInt16(); tex.header.padding2 = br.ReadUInt32(); tex.header.textData_offset = br.ReadUInt32(); tex.header.padding3 = br.ReadUInt32(); tex.header.textCompressedData_size = (ushort)(br.ReadUInt16() << 3); tex.header.textCompressedInfo_offset = br.ReadUInt16(); tex.header.padding4 = br.ReadUInt32(); tex.header.textCompressedData_offset = br.ReadUInt32(); tex.header.textCompressedInfoData_offset = br.ReadUInt32(); tex.header.padding5 = br.ReadUInt32(); tex.header.paletteData_size = (uint)(br.ReadUInt32() << 3); tex.header.paletteInfo_offset = br.ReadUInt32(); tex.header.paletteData_offset = br.ReadUInt32(); #region Texture Info br.BaseStream.Position = btx.header.offset[0] + tex.header.textInfo_offset; // Header tex.texInfo.dummy = br.ReadByte(); tex.texInfo.num_objs = br.ReadByte(); tex.texInfo.section_size = br.ReadUInt16(); // Unknown block tex.texInfo.unknownBlock.header_size = br.ReadUInt16(); tex.texInfo.unknownBlock.section_size = br.ReadUInt16(); tex.texInfo.unknownBlock.constant = br.ReadUInt32(); tex.texInfo.unknownBlock.unknown1 = new ushort[tex.texInfo.num_objs]; tex.texInfo.unknownBlock.unknown2 = new ushort[tex.texInfo.num_objs]; for (int i = 0; i < tex.texInfo.num_objs; i++) { tex.texInfo.unknownBlock.unknown1[i] = br.ReadUInt16(); tex.texInfo.unknownBlock.unknown2[i] = br.ReadUInt16(); } // Info block tex.texInfo.infoBlock.header_size = br.ReadUInt16(); tex.texInfo.infoBlock.data_size = br.ReadUInt16(); tex.texInfo.infoBlock.infoData = new object[tex.texInfo.num_objs]; tex.texture_data = new byte[tex.texInfo.num_objs][]; uint compressedStartOffset = 0x00; for (int i = 0; i < tex.texInfo.num_objs; i++) { sBTX0.Texture.TextInfo texInfo = new sBTX0.Texture.TextInfo(); texInfo.tex_offset = br.ReadUInt16(); texInfo.parameters = br.ReadUInt16(); texInfo.width2 = br.ReadByte(); texInfo.unknown = br.ReadByte(); texInfo.unknown2 = br.ReadByte(); texInfo.unknown3 = br.ReadByte(); texInfo.coord_transf = (byte)(texInfo.parameters & 14); texInfo.color0 = (byte)((texInfo.parameters >> 13) & 1); texInfo.format = (byte)((texInfo.parameters >> 10) & 7); texInfo.height = (byte)(8 << ((texInfo.parameters >> 7) & 7)); texInfo.width = (byte)(8 << ((texInfo.parameters >> 4) & 7)); texInfo.flip_Y = (byte)((texInfo.parameters >> 3) & 1); texInfo.flip_X = (byte)((texInfo.parameters >> 2) & 1); texInfo.repeat_Y = (byte)((texInfo.parameters >> 1) & 1); texInfo.repeat_X = (byte)(texInfo.parameters & 1); if (texInfo.width == 0x00) { switch (texInfo.unknown & 0x3) { case 2: texInfo.width = 0x200; break; default: texInfo.width = 0x100; break; } } if (texInfo.height == 0x00) { switch ((texInfo.unknown >> 4) & 0x3) { case 2: texInfo.height = 0x200; break; default: texInfo.height = 0x100; break; } } texInfo.depth = FormatDepth[texInfo.format]; if (texInfo.format == 5) { texInfo.compressedDataStart = compressedStartOffset; compressedStartOffset += (uint)(texInfo.width * texInfo.height / 8); } tex.texInfo.infoBlock.infoData[i] = texInfo; } tex.texInfo.names = new string[tex.texInfo.num_objs]; for (int i = 0; i < tex.texInfo.num_objs; i++) { tex.texInfo.names[i] = new String(br.ReadChars(0x10)).Replace("\0", ""); } #endregion #region Palette Info br.BaseStream.Position = btx.header.offset[0] + tex.header.paletteInfo_offset; // Header tex.palInfo.dummy = br.ReadByte(); tex.palInfo.num_objs = br.ReadByte(); tex.palInfo.section_size = br.ReadUInt16(); // Unknown block tex.palInfo.unknownBlock.header_size = br.ReadUInt16(); tex.palInfo.unknownBlock.section_size = br.ReadUInt16(); tex.palInfo.unknownBlock.constant = br.ReadUInt32(); tex.palInfo.unknownBlock.unknown1 = new ushort[tex.palInfo.num_objs]; tex.palInfo.unknownBlock.unknown2 = new ushort[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { tex.palInfo.unknownBlock.unknown1[i] = br.ReadUInt16(); tex.palInfo.unknownBlock.unknown2[i] = br.ReadUInt16(); } // Info block tex.palInfo.infoBlock.header_size = br.ReadUInt16(); tex.palInfo.infoBlock.data_size = br.ReadUInt16(); tex.palette_data = new byte[tex.palInfo.num_objs][]; tex.palInfo.infoBlock.infoData = new object[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { sBTX0.Texture.PalInfo palInfo = new sBTX0.Texture.PalInfo(); palInfo.palette_offset = (ushort)(br.ReadUInt16() & 0x1FFF); palInfo.unknown1 = br.ReadUInt16(); // Not used tex.palInfo.infoBlock.infoData[i] = palInfo; } tex.palInfo.names = new string[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { tex.palInfo.names[i] = new String(br.ReadChars(0x10)).Replace("\0", ""); } #endregion btx.texture = tex; #endregion Write_Info(btx, pluginHost.Get_Language()); br.Close(); return(btx); }
public static sBTX0.Texture Read_Section(ref BinaryReader br, uint texOffset, string lang) { sBTX0.Texture tex = new sBTX0.Texture(); // Header tex.header.type = br.ReadChars(4); tex.header.section_size = br.ReadUInt32(); tex.header.padding = br.ReadUInt32(); tex.header.textData_size = br.ReadUInt16(); tex.header.textInfo_offset = br.ReadUInt16(); tex.header.padding2 = br.ReadUInt32(); tex.header.textData_offset = br.ReadUInt32(); tex.header.padding3 = br.ReadUInt32(); tex.header.textCompressedData_size = (ushort)(br.ReadUInt16() << 3); tex.header.textCompressedInfo_offset = br.ReadUInt16(); tex.header.padding4 = br.ReadUInt32(); tex.header.textCompressedData_offset = br.ReadUInt32(); tex.header.textCompressedInfoData_offset = br.ReadUInt32(); tex.header.padding5 = br.ReadUInt32(); tex.header.paletteData_size = (uint)(br.ReadUInt32() << 3); tex.header.paletteInfo_offset = br.ReadUInt32(); tex.header.paletteData_offset = br.ReadUInt32(); #region Texture Info br.BaseStream.Position = texOffset + tex.header.textInfo_offset; // Header tex.texInfo.dummy = br.ReadByte(); tex.texInfo.num_objs = br.ReadByte(); tex.texInfo.section_size = br.ReadUInt16(); // Unknown block tex.texInfo.unknownBlock.header_size = br.ReadUInt16(); tex.texInfo.unknownBlock.section_size = br.ReadUInt16(); tex.texInfo.unknownBlock.constant = br.ReadUInt32(); tex.texInfo.unknownBlock.unknown1 = new ushort[tex.texInfo.num_objs]; tex.texInfo.unknownBlock.unknown2 = new ushort[tex.texInfo.num_objs]; for (int i = 0; i < tex.texInfo.num_objs; i++) { tex.texInfo.unknownBlock.unknown1[i] = br.ReadUInt16(); tex.texInfo.unknownBlock.unknown2[i] = br.ReadUInt16(); } // Info block tex.texInfo.infoBlock.header_size = br.ReadUInt16(); tex.texInfo.infoBlock.data_size = br.ReadUInt16(); tex.texInfo.infoBlock.infoData = new object[tex.texInfo.num_objs]; tex.texture_data = new byte[tex.texInfo.num_objs][]; uint compressedStartOffset = 0x00; for (int i = 0; i < tex.texInfo.num_objs; i++) { sBTX0.Texture.TextInfo texInfo = new sBTX0.Texture.TextInfo(); texInfo.tex_offset = br.ReadUInt16(); texInfo.parameters = br.ReadUInt16(); texInfo.width2 = br.ReadByte(); texInfo.unknown = br.ReadByte(); texInfo.unknown2 = br.ReadByte(); texInfo.unknown3 = br.ReadByte(); texInfo.coord_transf = (byte)(texInfo.parameters & 14); texInfo.color0 = (byte)((texInfo.parameters >> 13) & 1); texInfo.format = (byte)((texInfo.parameters >> 10) & 7); texInfo.height = (byte)(8 << ((texInfo.parameters >> 7) & 7)); texInfo.width = (byte)(8 << ((texInfo.parameters >> 4) & 7)); texInfo.flip_Y = (byte)((texInfo.parameters >> 3) & 1); texInfo.flip_X = (byte)((texInfo.parameters >> 2) & 1); texInfo.repeat_Y = (byte)((texInfo.parameters >> 1) & 1); texInfo.repeat_X = (byte)(texInfo.parameters & 1); if (texInfo.width == 0x00) { switch (texInfo.unknown & 0x3) { case 2: texInfo.width = 0x200; break; default: texInfo.width = 0x100; break; } } if (texInfo.height == 0x00) { switch ((texInfo.unknown >> 4) & 0x3) { case 2: texInfo.height = 0x200; break; default: texInfo.height = 0x100; break; } } texInfo.depth = FormatDepth[texInfo.format]; if (texInfo.format == 5) { texInfo.compressedDataStart = compressedStartOffset; compressedStartOffset += (uint)(texInfo.width * texInfo.height / 8); } tex.texInfo.infoBlock.infoData[i] = texInfo; } tex.texInfo.names = new string[tex.texInfo.num_objs]; for (int i = 0; i < tex.texInfo.num_objs; i++) { tex.texInfo.names[i] = new String(br.ReadChars(0x10)).Replace("\0", ""); } #endregion #region Palette Info br.BaseStream.Position = texOffset + tex.header.paletteInfo_offset; // Header tex.palInfo.dummy = br.ReadByte(); tex.palInfo.num_objs = br.ReadByte(); tex.palInfo.section_size = br.ReadUInt16(); // Unknown block tex.palInfo.unknownBlock.header_size = br.ReadUInt16(); tex.palInfo.unknownBlock.section_size = br.ReadUInt16(); tex.palInfo.unknownBlock.constant = br.ReadUInt32(); tex.palInfo.unknownBlock.unknown1 = new ushort[tex.palInfo.num_objs]; tex.palInfo.unknownBlock.unknown2 = new ushort[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { tex.palInfo.unknownBlock.unknown1[i] = br.ReadUInt16(); tex.palInfo.unknownBlock.unknown2[i] = br.ReadUInt16(); } // Info block tex.palInfo.infoBlock.header_size = br.ReadUInt16(); tex.palInfo.infoBlock.data_size = br.ReadUInt16(); tex.palette_data = new byte[tex.palInfo.num_objs][]; tex.palInfo.infoBlock.infoData = new object[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { sBTX0.Texture.PalInfo palInfo = new sBTX0.Texture.PalInfo(); palInfo.palette_offset = (ushort)(br.ReadUInt16() & 0x1FFF); palInfo.unknown1 = br.ReadUInt16(); // Not used tex.palInfo.infoBlock.infoData[i] = palInfo; } tex.palInfo.names = new string[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { tex.palInfo.names[i] = new String(br.ReadChars(0x10)).Replace("\0", ""); } #endregion Write_Info(tex, lang); return(tex); }
public static sBTX0.Texture Read_Section(ref BinaryReader br, uint texOffset, string lang) { sBTX0.Texture tex = new sBTX0.Texture(); // Header tex.header.type = br.ReadChars(4); tex.header.section_size = br.ReadUInt32(); tex.header.padding = br.ReadUInt32(); tex.header.textData_size = br.ReadUInt16(); tex.header.textInfo_offset = br.ReadUInt16(); tex.header.padding2 = br.ReadUInt32(); tex.header.textData_offset = br.ReadUInt32(); tex.header.padding3 = br.ReadUInt32(); tex.header.textCompressedData_size = (ushort)(br.ReadUInt16() << 3); tex.header.textCompressedInfo_offset = br.ReadUInt16(); tex.header.padding4 = br.ReadUInt32(); tex.header.textCompressedData_offset = br.ReadUInt32(); tex.header.textCompressedInfoData_offset = br.ReadUInt32(); tex.header.padding5 = br.ReadUInt32(); tex.header.paletteData_size = (uint)(br.ReadUInt32() << 3); tex.header.paletteInfo_offset = br.ReadUInt32(); tex.header.paletteData_offset = br.ReadUInt32(); #region Texture Info br.BaseStream.Position = texOffset + tex.header.textInfo_offset; // Header tex.texInfo.dummy = br.ReadByte(); tex.texInfo.num_objs = br.ReadByte(); tex.texInfo.section_size = br.ReadUInt16(); // Unknown block tex.texInfo.unknownBlock.header_size = br.ReadUInt16(); tex.texInfo.unknownBlock.section_size = br.ReadUInt16(); tex.texInfo.unknownBlock.constant = br.ReadUInt32(); tex.texInfo.unknownBlock.unknown1 = new ushort[tex.texInfo.num_objs]; tex.texInfo.unknownBlock.unknown2 = new ushort[tex.texInfo.num_objs]; for (int i = 0; i < tex.texInfo.num_objs; i++) { tex.texInfo.unknownBlock.unknown1[i] = br.ReadUInt16(); tex.texInfo.unknownBlock.unknown2[i] = br.ReadUInt16(); } // Info block tex.texInfo.infoBlock.header_size = br.ReadUInt16(); tex.texInfo.infoBlock.data_size = br.ReadUInt16(); tex.texInfo.infoBlock.infoData = new object[tex.texInfo.num_objs]; tex.texture_data = new byte[tex.texInfo.num_objs][]; uint compressedStartOffset = 0x00; for (int i = 0; i < tex.texInfo.num_objs; i++) { sBTX0.Texture.TextInfo texInfo = new sBTX0.Texture.TextInfo(); texInfo.tex_offset = br.ReadUInt16(); texInfo.parameters = br.ReadUInt16(); texInfo.width2 = br.ReadByte(); texInfo.unknown = br.ReadByte(); texInfo.unknown2 = br.ReadByte(); texInfo.unknown3 = br.ReadByte(); texInfo.coord_transf = (byte)(texInfo.parameters & 14); texInfo.color0 = (byte)((texInfo.parameters >> 13) & 1); texInfo.format = (byte)((texInfo.parameters >> 10) & 7); texInfo.height = (byte)(8 << ((texInfo.parameters >> 7) & 7)); texInfo.width = (byte)(8 << ((texInfo.parameters >> 4) & 7)); texInfo.flip_Y = (byte)((texInfo.parameters >> 3) & 1); texInfo.flip_X = (byte)((texInfo.parameters >> 2) & 1); texInfo.repeat_Y = (byte)((texInfo.parameters >> 1) & 1); texInfo.repeat_X = (byte)(texInfo.parameters & 1); if (texInfo.width == 0x00) switch (texInfo.unknown & 0x3) { case 2: texInfo.width = 0x200; break; default: texInfo.width = 0x100; break; } if (texInfo.height == 0x00) switch ((texInfo.unknown >> 4) & 0x3) { case 2: texInfo.height = 0x200; break; default: texInfo.height = 0x100; break; } texInfo.depth = FormatDepth[texInfo.format]; if (texInfo.format == 5) { texInfo.compressedDataStart = compressedStartOffset; compressedStartOffset += (uint)(texInfo.width * texInfo.height / 8); } tex.texInfo.infoBlock.infoData[i] = texInfo; } tex.texInfo.names = new string[tex.texInfo.num_objs]; for (int i = 0; i < tex.texInfo.num_objs; i++) { tex.texInfo.names[i] = new String(br.ReadChars(0x10)).Replace("\0", ""); } #endregion #region Palette Info br.BaseStream.Position = texOffset + tex.header.paletteInfo_offset; // Header tex.palInfo.dummy = br.ReadByte(); tex.palInfo.num_objs = br.ReadByte(); tex.palInfo.section_size = br.ReadUInt16(); // Unknown block tex.palInfo.unknownBlock.header_size = br.ReadUInt16(); tex.palInfo.unknownBlock.section_size = br.ReadUInt16(); tex.palInfo.unknownBlock.constant = br.ReadUInt32(); tex.palInfo.unknownBlock.unknown1 = new ushort[tex.palInfo.num_objs]; tex.palInfo.unknownBlock.unknown2 = new ushort[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { tex.palInfo.unknownBlock.unknown1[i] = br.ReadUInt16(); tex.palInfo.unknownBlock.unknown2[i] = br.ReadUInt16(); } // Info block tex.palInfo.infoBlock.header_size = br.ReadUInt16(); tex.palInfo.infoBlock.data_size = br.ReadUInt16(); tex.palette_data = new byte[tex.palInfo.num_objs][]; tex.palInfo.infoBlock.infoData = new object[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { sBTX0.Texture.PalInfo palInfo = new sBTX0.Texture.PalInfo(); palInfo.palette_offset = (ushort)(br.ReadUInt16() & 0x1FFF); palInfo.unknown1 = br.ReadUInt16(); // Not used tex.palInfo.infoBlock.infoData[i] = palInfo; } tex.palInfo.names = new string[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) tex.palInfo.names[i] = new String(br.ReadChars(0x10)).Replace("\0", ""); #endregion Write_Info(tex, lang); return tex; }
public static sBTX0 Read(string file, int id, IPluginHost pluginHost) { BinaryReader br = new BinaryReader(File.OpenRead(file)); sBTX0 btx = new sBTX0(); btx.id = id; btx.file = Path.GetTempFileName(); File.Copy(file, btx.file, true); // Read header btx.header.type = br.ReadChars(4); btx.header.constant = br.ReadUInt32(); btx.header.file_size = br.ReadUInt32(); btx.header.header_size = br.ReadUInt16(); btx.header.num_sections = br.ReadUInt16(); btx.header.offset = new uint[btx.header.num_sections]; for (int i = 0; i < btx.header.num_sections; i++) btx.header.offset[i] = br.ReadUInt32(); if (btx.header.num_sections > 1) MessageBox.Show("There are more than one section?\nPlease, report this file"); #region Read texture sections br.BaseStream.Position = btx.header.offset[0]; sBTX0.Texture tex = new sBTX0.Texture(); // Header tex.header.type = br.ReadChars(4); tex.header.section_size = br.ReadUInt32(); tex.header.padding = br.ReadUInt32(); tex.header.textData_size = br.ReadUInt16(); tex.header.textInfo_offset = br.ReadUInt16(); tex.header.padding2 = br.ReadUInt32(); tex.header.textData_offset = br.ReadUInt32(); tex.header.padding3 = br.ReadUInt32(); tex.header.textCompressedData_size = (ushort)(br.ReadUInt16() << 3); tex.header.textCompressedInfo_offset = br.ReadUInt16(); tex.header.padding4 = br.ReadUInt32(); tex.header.textCompressedData_offset = br.ReadUInt32(); tex.header.textCompressedInfoData_offset = br.ReadUInt32(); tex.header.padding5 = br.ReadUInt32(); tex.header.paletteData_size = (uint)(br.ReadUInt32() << 3); tex.header.paletteInfo_offset = br.ReadUInt32(); tex.header.paletteData_offset = br.ReadUInt32(); #region Texture Info br.BaseStream.Position = btx.header.offset[0] + tex.header.textInfo_offset; // Header tex.texInfo.dummy = br.ReadByte(); tex.texInfo.num_objs = br.ReadByte(); tex.texInfo.section_size = br.ReadUInt16(); // Unknown block tex.texInfo.unknownBlock.header_size = br.ReadUInt16(); tex.texInfo.unknownBlock.section_size = br.ReadUInt16(); tex.texInfo.unknownBlock.constant = br.ReadUInt32(); tex.texInfo.unknownBlock.unknown1 = new ushort[tex.texInfo.num_objs]; tex.texInfo.unknownBlock.unknown2 = new ushort[tex.texInfo.num_objs]; for (int i = 0; i < tex.texInfo.num_objs; i++) { tex.texInfo.unknownBlock.unknown1[i] = br.ReadUInt16(); tex.texInfo.unknownBlock.unknown2[i] = br.ReadUInt16(); } // Info block tex.texInfo.infoBlock.header_size = br.ReadUInt16(); tex.texInfo.infoBlock.data_size = br.ReadUInt16(); tex.texInfo.infoBlock.infoData = new object[tex.texInfo.num_objs]; tex.texture_data = new byte[tex.texInfo.num_objs][]; uint compressedStartOffset = 0x00; for (int i = 0; i < tex.texInfo.num_objs; i++) { sBTX0.Texture.TextInfo texInfo = new sBTX0.Texture.TextInfo(); texInfo.tex_offset = br.ReadUInt16(); texInfo.parameters = br.ReadUInt16(); texInfo.width2 = br.ReadByte(); texInfo.unknown = br.ReadByte(); texInfo.unknown2 = br.ReadByte(); texInfo.unknown3 = br.ReadByte(); texInfo.coord_transf = (byte)(texInfo.parameters & 14); texInfo.color0 = (byte)((texInfo.parameters >> 13) & 1); texInfo.format = (byte)((texInfo.parameters >> 10) & 7); texInfo.height = (byte)(8 << ((texInfo.parameters >> 7) & 7)); texInfo.width = (byte)(8 << ((texInfo.parameters >> 4) & 7)); texInfo.flip_Y = (byte)((texInfo.parameters >> 3) & 1); texInfo.flip_X = (byte)((texInfo.parameters >> 2) & 1); texInfo.repeat_Y = (byte)((texInfo.parameters >> 1) & 1); texInfo.repeat_X = (byte)(texInfo.parameters & 1); if (texInfo.width == 0x00) switch (texInfo.unknown & 0x3) { case 2: texInfo.width = 0x200; break; default: texInfo.width = 0x100; break; } if (texInfo.height == 0x00) switch ((texInfo.unknown >> 4) & 0x3) { case 2: texInfo.height = 0x200; break; default: texInfo.height = 0x100; break; } texInfo.depth = FormatDepth[texInfo.format]; if (texInfo.format == 5) { texInfo.compressedDataStart = compressedStartOffset; compressedStartOffset += (uint)(texInfo.width * texInfo.height / 8); } tex.texInfo.infoBlock.infoData[i] = texInfo; } tex.texInfo.names = new string[tex.texInfo.num_objs]; for (int i = 0; i < tex.texInfo.num_objs; i++) tex.texInfo.names[i] = new String(br.ReadChars(0x10)).Replace("\0", ""); #endregion #region Palette Info br.BaseStream.Position = btx.header.offset[0] + tex.header.paletteInfo_offset; // Header tex.palInfo.dummy = br.ReadByte(); tex.palInfo.num_objs = br.ReadByte(); tex.palInfo.section_size = br.ReadUInt16(); // Unknown block tex.palInfo.unknownBlock.header_size = br.ReadUInt16(); tex.palInfo.unknownBlock.section_size = br.ReadUInt16(); tex.palInfo.unknownBlock.constant = br.ReadUInt32(); tex.palInfo.unknownBlock.unknown1 = new ushort[tex.palInfo.num_objs]; tex.palInfo.unknownBlock.unknown2 = new ushort[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { tex.palInfo.unknownBlock.unknown1[i] = br.ReadUInt16(); tex.palInfo.unknownBlock.unknown2[i] = br.ReadUInt16(); } // Info block tex.palInfo.infoBlock.header_size = br.ReadUInt16(); tex.palInfo.infoBlock.data_size = br.ReadUInt16(); tex.palette_data = new byte[tex.palInfo.num_objs][]; tex.palInfo.infoBlock.infoData = new object[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) { sBTX0.Texture.PalInfo palInfo = new sBTX0.Texture.PalInfo(); palInfo.palette_offset = (ushort)(br.ReadUInt16() & 0x1FFF); palInfo.unknown1 = br.ReadUInt16(); // Not used tex.palInfo.infoBlock.infoData[i] = palInfo; } tex.palInfo.names = new string[tex.palInfo.num_objs]; for (int i = 0; i < tex.palInfo.num_objs; i++) tex.palInfo.names[i] = new String(br.ReadChars(0x10)).Replace("\0", ""); #endregion btx.texture = tex; #endregion Write_Info(btx, pluginHost.Get_Language()); br.Close(); return btx; }