Пример #1
0
        //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;
        }
Пример #2
0
        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();
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
        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();
            }
        }
Пример #5
0
        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;
        }
Пример #6
0
        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);
        }