public System.Windows.Forms.Control Show_Info(sFile file) { BinaryReader br = new BinaryReader(File.OpenRead(file.path)); string ext = new String(br.ReadChars(4)); br.Close(); if (ext == "BTX0") { btx = BTX0.Read(file.path, file.id, pluginHost); return(new TextureControl(pluginHost, btx)); } else if (ext == "BMD0") { sBMD0 bmd = BMD0.Read(file.path, file.id, pluginHost); if (bmd.header.numSect == 2) { return(new ModelControl(pluginHost, bmd)); } else if (btx.texture.texInfo.num_objs != 0) { return(new ModelControl(pluginHost, bmd, btx)); } else { System.Windows.Forms.MessageBox.Show("There aren't textures."); } } return(new System.Windows.Forms.Control()); }
public static System.Drawing.Bitmap GetTexture(IPluginHost pluginHost, sBTX0 btx0, int num) { if (num >= btx0.texture.texInfo.names.Length) { num = 0; } int num_pal; bool foundPal = false; for (num_pal = 0; num_pal < btx0.texture.palInfo.num_objs; num_pal++) { if (btx0.texture.palInfo.names[num_pal] == btx0.texture.texInfo.names[num]) { foundPal = true; break; } else if (btx0.texture.palInfo.names[num_pal].Replace("_pl", "") == btx0.texture.texInfo.names[num]) { foundPal = true; break; } } if (!foundPal) { num_pal = 0; } return(GetTexture(pluginHost, btx0, num, num_pal)); }
public TextureControl(IPluginHost pluginHost, sBTX0 btx0) { InitializeComponent(); 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); }
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); }
public void Read(sFile file) { BinaryReader br = new BinaryReader(File.OpenRead(file.path)); string ext = new String(br.ReadChars(4)); br.Close(); if (ext == "BTX0") { sBTX0 btx = BTX0.Read(file.path, file.id, pluginHost); Bitmap[] tex = new Bitmap[btx.texture.texInfo.num_objs]; for (int i = 0; i < btx.texture.texInfo.num_objs; i++) { string fileOut = pluginHost.Get_TempFolder() + Path.DirectorySeparatorChar + file.name + '_' + btx.texture.texInfo.names[i] + ".png"; if (File.Exists(fileOut)) { fileOut = pluginHost.Get_TempFolder() + Path.DirectorySeparatorChar + Path.GetRandomFileName() + '_' + btx.texture.texInfo.names[i] + ".png"; } tex[i] = BTX0.GetTexture(pluginHost, btx, i); tex[i].Save(fileOut); } pluginHost.Set_Object(tex); } }
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); }
public ModelControl(IPluginHost pluginHost, sBMD0 model, sBTX0 tex) { InitializeComponent(); this.pluginHost = pluginHost; this.model = model; this.tex = tex; Get_TexIDS(); numericPoly.Maximum = model.model.mdlData[0].polygon.header.num_objs - 1; }
public ModelControl(IPluginHost pluginHost, sBMD0 model) { InitializeComponent(); this.pluginHost = pluginHost; this.model = model; this.tex = Get_BTX0(); Get_TexIDS(); numericPoly.Maximum = model.model.mdlData[0].polygon.header.num_objs - 1; }
private sBTX0 Get_BTX0() { sBTX0 btx0 = new sBTX0(); btx0.texture = model.texture; btx0.file = model.filePath; btx0.header.offset = new uint[1]; btx0.header.offset[0] = model.header.offset[1]; return(btx0); }
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 TextureControl(IPluginHost pluginHost, sBTX0 btx0) { InitializeComponent(); 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); }
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_Texture(byte[] data, sBTX0.Texture.TextInfo info, Color[] palette) { if (info.format == 5) return Draw_CompressedTexture(data, info); Bitmap imagen = new Bitmap(info.width, info.height); if (info.format == 3) // 16-color 4 bits data = Ekona.Helper.BitsConverter.BytesToBit4(data); else if (info.format == 2) // 4-color 2 bits data = Bit8ToBit2(data); for (int h = 0; h < info.height; h++) { for (int w = 0; w < info.width; w++) { Color color = Color.Black; try { if (info.format == 2 || info.format == 3 || info.format == 4) // 2-4-8 bits per color color = palette[data[w + h * info.width]]; else if (info.format == 1) // A3I5 8-bit { int colorIndex = data[w + h * info.width] & 0x1F; int alpha = (data[w + h * info.width] >> 5); alpha = ((alpha * 4) + (alpha / 2)) * 8; color = Color.FromArgb(alpha, palette[colorIndex].R, palette[colorIndex].G, palette[colorIndex].B); } else if (info.format == 6) // A5I3 8-bit { int colorIndex = data[w + h * info.width] & 0x7; int alpha = (data[w + h * info.width] >> 3); alpha *= 8; color = Color.FromArgb(alpha, palette[colorIndex].R, palette[colorIndex].G, palette[colorIndex].B); } else if (info.format == 7) // Direct texture 16-bit (not tested) { ushort byteColor = BitConverter.ToUInt16(data, (w + h * info.width) * 2); color = Color.FromArgb( (byteColor >> 15) * 255, (byteColor & 0x1F) * 8, ((byteColor >> 5) & 0x1F) * 8, ((byteColor >> 10) & 0x1F) * 8); } } catch { } imagen.SetPixel(w, h, color); } } if (info.color0 == 1) imagen.MakeTransparent(palette[0]); return imagen; }
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; }
private sBTX0 Get_BTX0() { sBTX0 btx0 = new sBTX0(); btx0.texture = model.texture; btx0.file = model.filePath; btx0.header.offset = new uint[1]; btx0.header.offset[0] = model.header.offset[1]; return btx0; }
public System.Windows.Forms.Control Show_Info(sFile file) { BinaryReader br = new BinaryReader(File.OpenRead(file.path)); string ext = new String(br.ReadChars(4)); br.Close(); if (ext == "BTX0") { btx = BTX0.Read(file.path, file.id, pluginHost); return new TextureControl(pluginHost, btx); } else if (ext == "BMD0") { sBMD0 bmd = BMD0.Read(file.path, file.id, pluginHost); if (bmd.header.numSect == 2) return new ModelControl(pluginHost, bmd); else if (btx.texture.texInfo.num_objs != 0) return new ModelControl(pluginHost, bmd, btx); else System.Windows.Forms.MessageBox.Show("There aren't textures."); } return new System.Windows.Forms.Control(); }
private static Bitmap Draw_CompressedTexture(IPluginHost pluginHost, sBTX0 btx0, byte[] data, sBTX0.Texture.TextInfo info, int num_pal) { sBTX0.Texture.PalInfo palInfo = (sBTX0.Texture.PalInfo)btx0.texture.palInfo.infoBlock.infoData[num_pal]; 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); }
private static Bitmap Draw_Texture(IPluginHost pluginHost, sBTX0 btx0, byte[] data, sBTX0.Texture.TextInfo info, Color[] palette) { Bitmap imagen = new Bitmap(info.width, info.height); if (info.format == 3) // 16-color 4 bits { data = Ekona.Helper.BitsConverter.BytesToBit4(data); } else if (info.format == 2) // 4-color 2 bits { data = Bit8ToBit2(data); } for (int h = 0; h < info.height; h++) { for (int w = 0; w < info.width; w++) { Color color = Color.Black; try { if (info.format == 2 || info.format == 3 || info.format == 4) // 2-4-8 bits per color { color = palette[data[w + h * info.width]]; } else if (info.format == 1) // A3I5 8-bit { int colorIndex = data[w + h * info.width] & 0x1F; int alpha = (data[w + h * info.width] >> 5); alpha = ((alpha * 4) + (alpha / 2)) * 8; color = Color.FromArgb(alpha, palette[colorIndex].R, palette[colorIndex].G, palette[colorIndex].B); } else if (info.format == 6) // A5I3 8-bit { int colorIndex = data[w + h * info.width] & 0x7; int alpha = (data[w + h * info.width] >> 3); alpha *= 8; color = Color.FromArgb(alpha, palette[colorIndex].R, palette[colorIndex].G, palette[colorIndex].B); } else if (info.format == 7) // Direct texture 16-bit (not tested) { ushort byteColor = BitConverter.ToUInt16(data, (w + h * info.width) * 2); color = Color.FromArgb( (byteColor >> 15) * 255, (byteColor & 0x1F) * 8, ((byteColor >> 5) & 0x1F) * 8, ((byteColor >> 10) & 0x1F) * 8); } } catch { } imagen.SetPixel(w, h, color); } } if (info.color0 == 1) { imagen.MakeTransparent(palette[0]); } return(imagen); }
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 System.Drawing.Bitmap GetTexture(IPluginHost pluginHost, sBTX0 btx0, int num) { if (num >= btx0.texture.texInfo.names.Length) num = 0; int num_pal; bool foundPal = false; for (num_pal = 0; num_pal < btx0.texture.palInfo.num_objs; num_pal++) { if (btx0.texture.palInfo.names[num_pal] == btx0.texture.texInfo.names[num]) { foundPal = true; break; } else if (btx0.texture.palInfo.names[num_pal].Replace("_pl", "") == btx0.texture.texInfo.names[num]) { foundPal = true; break; } } if (!foundPal) num_pal = 0; return GetTexture(pluginHost, btx0, num, num_pal); }
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; }
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; }
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"); } }