//Constructors to add a new image in without needing an offset (NO MIO0 ENCODING FOR THIS YET) public MK64Image(F3DEXImage image, string name, bool encodeTextureInMIO0 = false) { TextureOffset = -1; TextureEncoding = (encodeTextureInMIO0 ? MK64ImageEncoding.MIO0 : MK64ImageEncoding.Raw); TextureBlockOffset = 0; PaletteOffset = image.BasePalettes.Select <Palette, int>(p => p.FileOffset).ToList(); PaletteEncoding = Enumerable.Repeat(MK64ImageEncoding.Raw, image.BasePalettes.Count).ToList(); PaletteBlockOffset = Enumerable.Repeat((int)0, image.BasePalettes.Count).ToList(); PaletteColorCount = image.BasePalettes.Select <Palette, int>(p => p.Colors.Length).ToList(); PaletteColorOffset = Enumerable.Repeat((int)0, image.BasePalettes.Count).ToList(); TKMKLength = 0; TKMKAlphaColor = 0; Format = image.Texture.Format; PixelSize = image.Texture.PixelSize; Width = image.Texture.Width; Height = image.Texture.Height; IsOriginalImage = false; if (string.IsNullOrWhiteSpace(name)) { ImageName = TextureOffset.ToString("X"); } else { ImageName = name; } ImageReference = image; IsValidImage = image.ValidImage; }
private void btnAdd_Click(object sender, EventArgs e) { if (openPortraitDialog.ShowDialog() == DialogResult.OK) { foreach (string file in openPortraitDialog.FileNames) { if (lbPortraits.Items.Count >= 17) { break; } Image img = Bitmap.FromFile(file); if (img.Width != 64 || img.Height != 64) { MessageBox.Show("Image must be 64x64!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (img != null) { //Create the new KartImage here byte[] imgData = TextureConversion.RGBA16ToBinary(new Bitmap(img)); Texture texture = new Texture(-1, imgData, Texture.ImageFormat.RGBA, Texture.PixelInfo.Size_16b, 64, 64); F3DEXImage image = new F3DEXImage(texture); MK64Image mkImage = new MK64Image(image, Path.GetFileNameWithoutExtension(file), true); Kart.AddPortrait(mkImage); lbPortraits.Items.Add(mkImage); } } UpdatePortraitCount(); UpdateButtonsEnabled(); } }
private KartImage ConvertToKartImage(Bitmap bmp, string imageName) { if (bmp != null && Kart != null && Kart.Kart != null && Kart.Kart.KartImages.ImagePalette != null) { //Create the new KartImage here //byte[] imgData = TextureConversion.CI8ToBinary(bmp, Kart.Kart.KartImages.ImagePalette); //Texture texture = new Texture(-1, imgData, Texture.ImageFormat.CI, Texture.PixelInfo.Size_8b, 64, 64, Kart.Kart.KartImages.ImagePalette); // ImageMIO0Block block = new ImageMIO0Block(-1, imgData); // block.ImageName = imageName; // block.DecodedN64DataElement = texture; //byte[] blankPaletteData = new byte[0x40]; //Palette blankPalette = new Palette(-1, blankPaletteData); //KartImage newImage = new KartImage(block, blankPalette); //return newImage; int tempPalOffset = 0; byte[] imgData = TextureConversion.CI8ToBinary(bmp, Kart.Kart.KartImages.ImagePalette, ref tempPalOffset); Texture texture = new Texture(-1, imgData, Texture.ImageFormat.CI, Texture.PixelInfo.Size_8b, 64, 64); List <Palette> palettes = new List <Palette>(); palettes.Add(Kart.Kart.KartImages.ImagePalette); byte[] blankPaletteData = new byte[0x40]; palettes.Add(new Palette(-1, blankPaletteData)); F3DEXImage image = new F3DEXImage(texture, palettes); MK64Image mkImg = new MK64Image(image, imageName, true); KartImage newImage = new KartImage(new List <MK64Image>() { mkImg }); return(newImage); } return(null); }
public MK64Image(XElement xml, Palette existingPalette = null) { TextureOffset = int.Parse(xml.Attribute(TEXTURE_OFFSET).Value.ToString()); TextureEncoding = (MK64ImageEncoding)Enum.Parse(typeof(MK64ImageEncoding), xml.Attribute(TEXTURE_ENCODING).Value.ToString()); TextureBlockOffset = int.Parse(xml.Attribute(TEXTURE_BLOCK_OFFSET).Value.ToString()); XElement palettesXML = xml.Element(PALETTES); PaletteOffset = new List <int>(); PaletteEncoding = new List <MK64ImageEncoding>(); PaletteBlockOffset = new List <int>(); PaletteColorCount = new List <int>(); PaletteColorOffset = new List <int>(); foreach (XElement paletteXml in palettesXML.Elements()) { PaletteOffset.Add(int.Parse(paletteXml.Attribute(PALETTE_OFFSET).Value.ToString())); PaletteEncoding.Add((MK64ImageEncoding)Enum.Parse(typeof(MK64ImageEncoding), paletteXml.Attribute(PALETTE_ENCODING).Value.ToString())); PaletteBlockOffset.Add(int.Parse(paletteXml.Attribute(PALETTE_BLOCK_OFFSET).Value.ToString())); PaletteColorCount.Add(int.Parse(paletteXml.Attribute(PALETTE_COLOR_COUNT).Value.ToString())); PaletteColorOffset.Add(int.Parse(paletteXml.Attribute(PALETTE_COLOR_OFFSET).Value.ToString())); } TKMKLength = int.Parse(xml.Attribute(TKMK_LENGTH).Value.ToString()); TKMKAlphaColor = ushort.Parse(xml.Attribute(TKMK_ALPHA_COLOR).Value.ToString()); Format = (Texture.ImageFormat)Enum.Parse(typeof(Texture.ImageFormat), xml.Attribute(FORMAT).Value.ToString()); PixelSize = (Texture.PixelInfo)Enum.Parse(typeof(Texture.PixelInfo), xml.Attribute(PIXEL_SIZE).Value.ToString()); Width = int.Parse(xml.Attribute(WIDTH).Value.ToString()); Height = int.Parse(xml.Attribute(HEIGHT).Value.ToString()); IsOriginalImage = bool.Parse(xml.Attribute(IS_ORIGINAL_IMAGE).Value.ToString()); ImageName = xml.Attribute(IMAGE_NAME).Value.ToString(); if (xml.Element(typeof(TKMK00Block).ToString()) != null) { //load TKMK00 reference here if (!FindExistingTKMK00()) { TKMKReference = new TKMK00Block(xml.Element(typeof(TKMK00Block).ToString())); } } else if (xml.Element(F3DEXImage.F3DEXIMAGE) != null) { //load f3deximage reference F3DEXImage newImage = new F3DEXImage(xml.Element(F3DEXImage.F3DEXIMAGE), existingPalette); if (!FindExistingF3DEXImage(newImage.Texture, newImage.BasePalettes)) { ImageReference = newImage; } } else { LoadImageData(); } }
private void LoadImageData(byte[] rawData = null) { IsValidImage = false; //Check that the format is correct (ex. CI & palette offsets are valid) int maxTextureLocation = (rawData != null ? rawData.Length - 1 : RomProject.Instance.Files[0].FileLength - 1); if (TextureOffset < 0 || TextureOffset > maxTextureLocation || (Format == Texture.ImageFormat.CI && PaletteOffset.Count == 0)) { return; } if (!TextureConversion.IsValidFormatCombo(Format, PixelSize)) { return; } //Try to load the texture, palette & image here N64DataElement element; Palette paletteRef = null; List <Palette> paletteRefs = new List <Palette>(); if (Format == Texture.ImageFormat.CI) //If CI format, we need to get the palette too { for (int i = 0; i < PaletteOffset.Count; i++) { paletteRef = null; if (RomProject.Instance.Files[0].HasElementExactlyAt(PaletteOffset[i], out element) && element.FileOffset == PaletteOffset[i] && !(element is UnknownData)) { switch (PaletteEncoding[i]) { case MK64ImageEncoding.Raw: //Needs to be a raw palette if (!(element is Palette)) { return; } paletteRef = (Palette)element; break; case MK64ImageEncoding.MIO0: //Needs to be a mio0 block if (!(element is MIO0Block)) { return; } MIO0Block block = (MIO0Block)element; //System.IO.File.WriteAllBytes("test.bin",block.DecodedData); //now to search inside if (block.Elements.FirstOrDefault(e => e.FileOffset == PaletteBlockOffset[i]) != null) { N64DataElement paletteEl = block.Elements.First(e => e.FileOffset == PaletteBlockOffset[i]); if (paletteEl is Palette) { paletteRef = (Palette)paletteEl; } } else { //Create the palette! byte[] data = new byte[PaletteColorCount[i] * 2]; Array.Copy(block.DecodedData, PaletteBlockOffset[i], data, 0, data.Length); Palette pal = new Palette(PaletteBlockOffset[i], data); if (block.AddElement(pal)) { paletteRef = pal; } } break; } } else { //AVOID THIS AS MUCH AS POSSIBLE, IT WILL SLOW EVERYTHING DOWN TREMENDOUSLY!! if (rawData == null) { rawData = RomProject.Instance.Files[0].GetAsBytes(); } //Create the palette! switch (PaletteEncoding[i]) { case MK64ImageEncoding.Raw: //Create the palette! byte[] data = new byte[PaletteColorCount[i] * 2]; Array.Copy(rawData, PaletteOffset[i], data, 0, data.Length); Palette pal = new Palette(PaletteOffset[i], data); if (RomProject.Instance.Files[0].AddElement(pal)) { paletteRef = pal; } break; case MK64ImageEncoding.MIO0: //Create the MIO0 block! MIO0Block block = MIO0Block.ReadMIO0BlockFrom(rawData, PaletteOffset[i]); //System.IO.File.WriteAllBytes("test.bin",block.DecodedData); if (RomProject.Instance.Files[0].AddElement(block)) { //Create the palette in the MIO0 block! byte[] mioData = new byte[PaletteColorCount[i] * 2]; Array.Copy(block.DecodedData, PaletteBlockOffset[i], mioData, 0, mioData.Length); Palette palette = new Palette(PaletteBlockOffset[i], mioData); if (block.AddElement(palette)) { paletteRef = palette; } else { throw new Exception(); } } break; } } paletteRefs.Add(paletteRef); } } Texture textureRef = null; TKMK00Block tkmkRef = null; if (RomProject.Instance.Files[0].HasElementExactlyAt(TextureOffset, out element) && element.FileOffset == TextureOffset && !(element is UnknownData)) { switch (TextureEncoding) { case MK64ImageEncoding.Raw: //Needs to be a raw texture if (!(element is Texture)) { return; } textureRef = (Texture)element; break; case MK64ImageEncoding.MIO0: //Needs to be a mio0 block if (!(element is MIO0Block)) { return; } MIO0Block block = (MIO0Block)element; //now to search inside if (block.Elements.FirstOrDefault(e => e.FileOffset == TextureBlockOffset) != null) { N64DataElement textureEl = block.Elements.First(e => e.FileOffset == TextureBlockOffset); if (textureEl is Texture) { textureRef = (Texture)textureEl; } } else { //Create the texture here //Create the palette! double byteSize = 1; switch (PixelSize) { case Texture.PixelInfo.Size_4b: byteSize = 0.5; break; case Texture.PixelInfo.Size_16b: byteSize = 2; break; case Texture.PixelInfo.Size_32b: byteSize = 4; break; } byte[] data = new byte[(int)Math.Round(Width * Height * byteSize)]; Array.Copy(block.DecodedData, TextureBlockOffset, data, 0, data.Length); Texture text = new Texture(TextureBlockOffset, data, Format, PixelSize, Width, Height); if (block.AddElement(text)) { textureRef = text; } } break; case MK64ImageEncoding.TKMK00: //Needs to be a tkmk00 block if (!(element is TKMK00Block)) { return; } tkmkRef = (TKMK00Block)element; break; } } else //NEED TO CREATE IT HERE! { //AVOID THIS AS MUCH AS POSSIBLE, IT WILL SLOW EVERYTHING DOWN TREMENDOUSLY!! if (rawData == null) { rawData = RomProject.Instance.Files[0].GetAsBytes(); } switch (TextureEncoding) { case MK64ImageEncoding.Raw: //Just create the new texture image! double byteSize = 1; switch (PixelSize) { case Texture.PixelInfo.Size_4b: byteSize = 0.5; break; case Texture.PixelInfo.Size_16b: byteSize = 2; break; case Texture.PixelInfo.Size_32b: byteSize = 4; break; } byte[] data = new byte[(int)Math.Round(Width * Height * byteSize)]; Array.Copy(rawData, TextureOffset, data, 0, data.Length); Texture texture = new Texture(TextureOffset, data, Format, PixelSize, Width, Height); //Add to the rom project if (RomProject.Instance.Files[0].AddElement(texture)) { textureRef = texture; } break; case MK64ImageEncoding.MIO0: //Since no MIO0 block was found, it needs to be created MIO0Block block = MIO0Block.ReadMIO0BlockFrom(rawData, TextureOffset); if (RomProject.Instance.Files[0].AddElement(block)) { double ByteSize = 1; switch (PixelSize) { case Texture.PixelInfo.Size_4b: ByteSize = 0.5; break; case Texture.PixelInfo.Size_16b: ByteSize = 2; break; case Texture.PixelInfo.Size_32b: ByteSize = 4; break; } byte[] textData = new byte[(int)Math.Round(Width * Height * ByteSize)]; Array.Copy(block.DecodedData, TextureBlockOffset, textData, 0, textData.Length); Texture text = new Texture(TextureBlockOffset, textData, Format, PixelSize, Width, Height); if (block.AddElement(text)) { textureRef = text; } } break; case MK64ImageEncoding.TKMK00: //Need to create the TKMK00Block, and it'll handle the rest TKMK00Block tkmk; byte[] bytes = new byte[TKMKLength]; Array.Copy(rawData, TextureOffset, bytes, 0, TKMKLength); tkmk = new TKMK00Block(TextureOffset, bytes, TKMKAlphaColor); if (RomProject.Instance.Files[0].AddElement(tkmk)) { tkmkRef = tkmk; } break; } } if ((textureRef == null && tkmkRef == null) || (Format == Texture.ImageFormat.CI && (paletteRefs.Count == 0 || paletteRefs.Contains(null)))) { return; } //Test to make sure the texture matches the format and such if (textureRef != null && Format != textureRef.Format) { return; } //Successfully found the palette, set the references TKMKReference = tkmkRef; if (TextureEncoding == MK64ImageEncoding.TKMK00) { IsValidImage = (TKMKReference != null); return; } F3DEXImage image = new F3DEXImage(textureRef, paletteRefs); ImageReference = image; IsValidImage = image.ValidImage; }
private bool FindExistingF3DEXImage(Texture newTexture, List <Palette> newPalettes) { if (RomProject.Instance.Files.Count == 0) { return(false); } //Look for the TKMK00 bool changesMade = false; N64DataElement element; Palette paletteRef = null; List <Palette> paletteRefs = new List <Palette>(); if (Format == Texture.ImageFormat.CI) //If CI format, we need to get the palette too { for (int i = 0; i < PaletteOffset.Count; i++) { paletteRef = null; if (RomProject.Instance.Files[0].HasElementExactlyAt(PaletteOffset[i], out element) && element.FileOffset == TextureOffset && !(element is UnknownData)) { switch (PaletteEncoding[i]) { case MK64ImageEncoding.Raw: //Needs to be a raw palette if (!(element is Palette)) { break; } paletteRef = (Palette)element; break; case MK64ImageEncoding.MIO0: //Needs to be a mio0 block if (!(element is MIO0Block)) { break; } MIO0Block block = (MIO0Block)element; //System.IO.File.WriteAllBytes("test.bin",block.DecodedData); //now to search inside if (block.Elements.FirstOrDefault(e => e.FileOffset == PaletteBlockOffset[i]) != null) { N64DataElement paletteEl = block.Elements.First(e => e.FileOffset == PaletteBlockOffset[i]); if (paletteEl is Palette) { paletteRef = (Palette)paletteEl; } } break; } } if (paletteRef != null) { newPalettes[i] = paletteRef; changesMade = true; } } } //Now texture Texture textureRef = null; if (RomProject.Instance.Files[0].HasElementExactlyAt(TextureOffset, out element) && element.FileOffset == TextureOffset && !(element is UnknownData)) { switch (TextureEncoding) { case MK64ImageEncoding.Raw: //Needs to be a raw texture if (!(element is Texture)) { break; } textureRef = (Texture)element; break; case MK64ImageEncoding.MIO0: //Needs to be a mio0 block if (!(element is MIO0Block)) { break; } MIO0Block block = (MIO0Block)element; //now to search inside if (block.Elements.FirstOrDefault(e => e.FileOffset == TextureBlockOffset) != null) { N64DataElement textureEl = block.Elements.First(e => e.FileOffset == TextureBlockOffset); if (textureEl is Texture) { textureRef = (Texture)textureEl; } } break; } } if (textureRef != null) { newTexture = textureRef; changesMade = true; } if (changesMade) { ImageReference = new F3DEXImage(newTexture, newPalettes); IsValidImage = ImageReference.ValidImage; return(true); } return(false); }