private void UpdateTexture(int num_tex, int num_pal) { sBTX0.Texture.TextInfo texInfo = (sBTX0.Texture.TextInfo)btx0.texture.texInfo.infoBlock.infoData[num_tex]; sBTX0.Texture.PalInfo palInfo = (sBTX0.Texture.PalInfo)btx0.texture.palInfo.infoBlock.infoData[num_pal]; // Get texture data BinaryReader br = new BinaryReader(File.OpenRead(btx0.file)); if (texInfo.format != 5) { br.BaseStream.Position = texInfo.tex_offset * 8 + btx0.header.offset[0] + btx0.texture.header.textData_offset; } else { br.BaseStream.Position = btx0.header.offset[0] + btx0.texture.header.textCompressedData_offset + texInfo.tex_offset * 8; } Byte[] tile_data = br.ReadBytes((int)(texInfo.width * texInfo.height * texInfo.depth / 8)); // Get palette data br.BaseStream.Position = btx0.header.offset[0] + btx0.texture.header.paletteData_offset; br.BaseStream.Position += palInfo.palette_offset * 8; Byte[] palette_data = br.ReadBytes((int)PaletteSize[texInfo.format]); Color[] palette = Actions.BGR555ToColor(palette_data); br.Close(); picTex.Image = Draw_Texture(tile_data, texInfo, palette); Clipboard.SetImage(picTex.Image); PaletteBase p = new RawPalette(new Color[][] { palette }, false, ColorFormat.colors256); picPalette.Image = p.Get_Image(0); pluginHost.Set_Palette(p); Info(num_tex, num_pal); }
private void Info(int num_tex, int num_pal) { for (int i = 1; i < 11; i++) { if (listProp.Items[i].SubItems.Count > 1) { listProp.Items[i].SubItems.RemoveAt(1); } } if (listProp.Items[12].SubItems.Count > 1) { listProp.Items[12].SubItems.RemoveAt(1); } sBTX0.Texture.TextInfo texInfo = (sBTX0.Texture.TextInfo)btx0.texture.texInfo.infoBlock.infoData[num_tex]; listProp.Items[1].SubItems.Add((texInfo.tex_offset * 8).ToString("x")); listProp.Items[2].SubItems.Add(texInfo.repeat_X.ToString()); listProp.Items[3].SubItems.Add(texInfo.repeat_Y.ToString()); listProp.Items[4].SubItems.Add(texInfo.flip_X.ToString()); listProp.Items[5].SubItems.Add(texInfo.flip_Y.ToString()); listProp.Items[6].SubItems.Add(texInfo.width.ToString()); listProp.Items[7].SubItems.Add(texInfo.height.ToString()); listProp.Items[8].SubItems.Add(texInfo.format.ToString() + " (" + (TextureFormat)texInfo.format + ')'); listProp.Items[9].SubItems.Add(texInfo.color0.ToString()); listProp.Items[10].SubItems.Add(texInfo.coord_transf.ToString() + " (" + (TextureCoordTransf)texInfo.coord_transf + ')'); sBTX0.Texture.PalInfo palInfo = (sBTX0.Texture.PalInfo)btx0.texture.palInfo.infoBlock.infoData[num_pal]; int palOffset = palInfo.palette_offset; palOffset *= (texInfo.format == 2 ? 8 : 16); listProp.Items[12].SubItems.Add(palOffset.ToString("x")); listProp.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); }
private void button1_Click(object sender, EventArgs e) { int num_tex = listTextures.SelectedIndex; int num_pal = listPalettes.SelectedIndex; sBTX0.Texture.TextInfo texInfo = (sBTX0.Texture.TextInfo)btx0.texture.texInfo.infoBlock.infoData[num_tex]; sBTX0.Texture.PalInfo palInfo = (sBTX0.Texture.PalInfo)btx0.texture.palInfo.infoBlock.infoData[num_pal]; // Get palette data BinaryReader br = new BinaryReader(File.OpenRead(btx0.file)); br.BaseStream.Position = btx0.header.offset[0] + btx0.texture.header.paletteData_offset; br.BaseStream.Position += palInfo.palette_offset * 8; Byte[] palette_data = br.ReadBytes((int)PaletteSize[texInfo.format]); Color[] palette = Actions.BGR555ToColor(palette_data); br.Close(); SaveFileDialog o = new SaveFileDialog(); o.AddExtension = true; o.CheckPathExists = true; o.DefaultExt = ".pal"; o.Filter = "Windows Palette for Gimp 2.8 (*.pal)|*.pal|" + "Windows Palette (*.pal)|*.pal|" + "Portable Network Graphics (*.png)|*.png|" + "Adobe COlor (*.aco)|*.aco"; o.OverwritePrompt = true; if (o.ShowDialog() != DialogResult.OK) { return; } if (o.FilterIndex == 3) { RawPalette p = new RawPalette(palette, false, ColorFormat.colors256); p.Get_Image(0).Save(o.FileName, System.Drawing.Imaging.ImageFormat.Png); } else if (o.FilterIndex == 1 || o.FilterIndex == 2) { Ekona.Images.Formats.PaletteWin palwin = new Ekona.Images.Formats.PaletteWin(palette); if (o.FilterIndex == 1) { palwin.Gimp_Error = true; } palwin.Write(o.FileName); } else if (o.FilterIndex == 4) { Ekona.Images.Formats.ACO palaco = new Ekona.Images.Formats.ACO(palette); palaco.Write(o.FileName); } o.Dispose(); }
private static void Write_Info(sBTX0 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("S00").Value + "</b>"); Console.WriteLine(xml.Element("S01").Value); Console.WriteLine("<u>" + xml.Element("S02").Value + "</u>"); Console.WriteLine(xml.Element("S03").Value, btx0.texture.header.textInfo_offset.ToString("x")); Console.WriteLine(xml.Element("S04").Value, btx0.texture.header.textData_offset.ToString("x")); Console.WriteLine(xml.Element("S05").Value, btx0.texture.header.textData_size.ToString("x")); Console.WriteLine(xml.Element("S06").Value, btx0.texture.header.textCompressedData_offset.ToString("x")); Console.WriteLine(xml.Element("S07").Value, btx0.texture.header.textCompressedData_size.ToString("x")); Console.WriteLine(xml.Element("S08").Value, btx0.texture.header.textCompressedInfo_offset.ToString("x")); Console.WriteLine(xml.Element("S09").Value, btx0.texture.header.textCompressedInfoData_offset.ToString("x")); Console.WriteLine(xml.Element("S0A").Value, btx0.texture.header.paletteData_offset.ToString("x")); Console.WriteLine(xml.Element("S0B").Value, btx0.texture.header.paletteData_offset.ToString("x")); Console.WriteLine(xml.Element("S0C").Value, btx0.texture.header.paletteInfo_offset.ToString("x")); Console.WriteLine("<u>" + xml.Element("S0D").Value + "</u>"); for (int i = 0; i < btx0.texture.texInfo.num_objs; i++) { sBTX0.Texture.TextInfo texInfo = (sBTX0.Texture.TextInfo)btx0.texture.texInfo.infoBlock.infoData[i]; Console.WriteLine(xml.Element("S0E").Value, i.ToString(), btx0.texture.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.texture.palInfo.num_objs; i++) { sBTX0.Texture.PalInfo palInfo = (sBTX0.Texture.PalInfo)btx0.texture.palInfo.infoBlock.infoData[i]; Console.WriteLine(xml.Element("S19").Value, i.ToString(), btx0.texture.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 Bitmap GetTexture(IPluginHost pluginHost, sBTX0 btx0, int num_tex, int num_pal) { sBTX0.Texture.TextInfo texInfo = (sBTX0.Texture.TextInfo)btx0.texture.texInfo.infoBlock.infoData[num_tex]; sBTX0.Texture.PalInfo palInfo = (sBTX0.Texture.PalInfo)btx0.texture.palInfo.infoBlock.infoData[num_pal]; // Get texture data BinaryReader br = new BinaryReader(File.OpenRead(btx0.file)); if (texInfo.format != 5) { br.BaseStream.Position = texInfo.tex_offset * 8 + btx0.header.offset[0] + btx0.texture.header.textData_offset; } else { br.BaseStream.Position = btx0.header.offset[0] + btx0.texture.header.textCompressedData_offset + texInfo.tex_offset * 8; } Byte[] tile_data = br.ReadBytes((int)(texInfo.width * texInfo.height * texInfo.depth / 8)); // Get palette data br.BaseStream.Position = btx0.header.offset[0] + btx0.texture.header.paletteData_offset; br.BaseStream.Position += palInfo.palette_offset * 8; Byte[] palette_data = br.ReadBytes((int)PaletteSize[texInfo.format]); Color[] palette = Actions.BGR555ToColor(palette_data); br.Close(); Bitmap tex; if (texInfo.format != 5) { tex = Draw_Texture(pluginHost, btx0, tile_data, texInfo, palette); } else { tex = Draw_CompressedTexture(pluginHost, btx0, tile_data, texInfo, num_pal); } return(tex); }
private Bitmap Draw_CompressedTexture(byte[] data, sBTX0.Texture.TextInfo info) { sBTX0.Texture.PalInfo palInfo = (sBTX0.Texture.PalInfo)btx0.texture.palInfo.infoBlock.infoData[listPalettes.SelectedIndex]; BinaryReader br = new BinaryReader(File.OpenRead(btx0.file)); br.BaseStream.Position = btx0.header.offset[0] + btx0.texture.header.textCompressedInfoData_offset + info.compressedDataStart; Bitmap image = new Bitmap(info.width, info.height); for (int h = 0; h < info.height; h += 4) { for (int w = 0; w < info.width; w += 4) { uint texData = BitConverter.ToUInt32(data, w + h * info.width / 4); // Get palette data for this block ushort pal_info = br.ReadUInt16(); int pal_offset = pal_info & 0x3FFF; int pal_mode = (pal_info >> 14); long currPos = br.BaseStream.Position; br.BaseStream.Position = btx0.header.offset[0] + btx0.texture.header.paletteData_offset + palInfo.palette_offset * 8; br.BaseStream.Position += pal_offset * 4; if (br.BaseStream.Position >= br.BaseStream.Length) { br.BaseStream.Position -= pal_offset * 4; } Color[] palette = Actions.BGR555ToColor(br.ReadBytes(0x08)); br.BaseStream.Position = currPos; for (int hTex = 0; hTex < 4; hTex++) { byte texel_row = (byte)((texData >> (hTex * 8)) & 0xFF); for (int wTex = 0; wTex < 4; wTex++) { byte texel = (byte)((texel_row >> (wTex * 2)) & 0x3); #region Get color from Texel and mode values Color color = Color.Black; if (palette.Length < 4 && pal_mode != 1 && pal_mode != 3) { goto Draw; } switch (pal_mode) { case 0: if (texel == 0) { color = palette[0]; } else if (texel == 1) { color = palette[1]; } else if (texel == 2) { color = palette[2]; } else if (texel == 3) { color = Color.FromArgb(0, 0, 0, 0); // Transparent color } break; case 1: if (texel == 0) { color = palette[0]; } else if (texel == 1) { color = palette[1]; } else if (texel == 2) { color = SumColors(palette[0], palette[1], 1, 1); } else if (texel == 3) { color = Color.FromArgb(0, 0, 0, 0); // Transparent color } break; case 2: if (texel == 0) { color = palette[0]; } else if (texel == 1) { color = palette[1]; } else if (texel == 2) { color = palette[2]; } else if (texel == 3) { color = palette[3]; } break; case 3: if (texel == 0) { color = palette[0]; } else if (texel == 1) { color = palette[1]; } else if (texel == 2) { color = SumColors(palette[0], palette[1], 5, 3); } else if (texel == 3) { color = SumColors(palette[0], palette[1], 3, 5); } break; } #endregion Draw: image.SetPixel( w + wTex, h + hTex, color); } } } } br.Close(); return(image); }
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; }