Exemple #1
0
        public void UpdateControl()
        {
            cb1MIO0Data.Items.Clear();

            if (RomProject.Instance.Files.Count > 0)
            {
                btnResizeRom.Enabled = true;
                txtRomSize.Enabled   = true;
                txtRomSize.Text      = ((int)Math.Round(RomProject.Instance.Files[0].FileLength / 1048576.0)).ToString();

                //Update the MIO0 stuff
                foreach (N64DataElement element in RomProject.Instance.Files[0].Elements)
                {
                    if (element is MIO0Block)
                    {
                        MIO0Block block = (MIO0Block)element;
                        if (block.Elements.Count > 1)
                        {
                            cb1MIO0Data.Items.Add(block);
                        }
                    }
                }

                bool mioEnabled = cb1MIO0Data.Items.Count > 0;

                btnExportMIO0.Enabled = mioEnabled;
                cb1MIO0Data.Enabled   = mioEnabled;
                if (mioEnabled)
                {
                    cb1MIO0Data.SelectedIndex = 0;
                }
            }
            else
            {
                btnResizeRom.Enabled  = false;
                txtRomSize.Enabled    = false;
                txtRomSize.Text       = string.Empty;
                btnExportMIO0.Enabled = false;
                cb1MIO0Data.Enabled   = false;
            }
        }
        private void ReplaceMIO0()
        {
            //Attempt to load in a new texture and replace. Will not work if the texture size is larger than the one it's replacing
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                Bitmap bmp = (Bitmap)Bitmap.FromFile(openFileDialog.FileName);
                if (bmp == null)
                {
                    MessageBox.Show("Error: Couldn't load image file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (bmp.Height != _image.Height ||
                    bmp.Width != _image.Width)
                {
                    MessageBox.Show("Error: New image must be same size!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                //Think hard about this. If you're compressing the image and/or palette into MIO0, you need to test against that.
                // Also a form if there's more than one image being affected by this change? Before/afters?


                //So we need some way to change an F3DEXImage to a new bitmap. but it needs to change texture and palette appropriately,
                // and most importantly it needs to be able to stop halfway to see how it will affect other images. But if we want to change
                // the lakitu images, which will change the palette, you'd have to change all of the images at once, right? So how the hell
                // is this going to work out??

                //Also palette editing

                byte[] newData;
                byte[] newPaletteData = null;
                if (_image.Format == Texture.ImageFormat.CI)
                {
                    Palette palette = new Palette(-1, new byte[(_image.ImageReference.WorkingPalette.Colors.Length * 2) - 200]);
                    newData        = TextureConversion.ImageToBinary(_image.Format, _image.PixelSize, bmp, ref palette);
                    newPaletteData = palette.RawData;
                    if (newPaletteData.Length < (_image.ImageReference.WorkingPalette.Colors.Length * 2))
                    {
                        newPaletteData = Cereal64.Common.Utils.ByteHelper.CombineIntoBytes(newPaletteData, new byte[(_image.ImageReference.WorkingPalette.Colors.Length * 2) - newPaletteData.Length]);
                    }
                }
                else
                {
                    newData = TextureConversion.ImageToBinary(_image.Format, _image.PixelSize, bmp);
                }

                if (newData == null || newData.Length == 0)
                {
                    MessageBox.Show("Error: Couldn't convert image file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                byte[] oldData        = _image.ImageReference.Texture.RawData;
                byte[] oldPaletteData = null;
                if (_image.Format == Texture.ImageFormat.CI)
                {
                    oldPaletteData = _image.ImageReference.BasePalettes[0].RawData;
                }

                _image.ImageReference.Texture.RawData = newData;
                if (_image.Format == Texture.ImageFormat.CI)
                {
                    _image.ImageReference.BasePalettes[0].RawData = newPaletteData;
                }

                _image.ImageReference.UpdateImage();

                if (!_image.IsValidImage)
                {
                    _image.ImageReference.Texture.RawData = oldData;
                    _image.ImageReference.UpdateImage();

                    MessageBox.Show("Error: Couldn't set image file! File might be too large to load in", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                byte[] oldMIO0RefData = null;

                N64DataElement el;

                if (_image.TextureEncoding == MK64Image.MK64ImageEncoding.MIO0)
                {
                    if (!RomProject.Instance.Files[0].HasElementAt(_image.TextureOffset, out el))
                    {
                        MessageBox.Show("Error: Couldn't set image file! Could not find MIO0 block.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    MIO0Block block = (MIO0Block)el;

                    byte[] oldMIO0Data = block.DecodedData;
                    oldMIO0RefData = oldMIO0Data;

                    if (_specialMIO0Length == -1 && block.FileOffset == 0x132B50)
                    {
                        _specialMIO0Length = block.RawDataSize;
                    }

                    Array.Copy(newData, 0, oldMIO0Data, _image.TextureBlockOffset, newData.Length);

                    byte[] compressedNewMIO0 = MIO0.Encode(oldMIO0Data);

                    int sizeCompare = (_specialMIO0Length != -1 && block.FileOffset == 0x132B50 ? _specialMIO0Length : block.RawDataSize);

                    if (compressedNewMIO0.Length > sizeCompare)
                    {
                        _image.ImageReference.Texture.RawData = oldData;
                        if (_image.Format == Texture.ImageFormat.CI)
                        {
                            _image.ImageReference.BasePalettes[0].RawData = oldPaletteData;
                        }
                        _image.ImageReference.UpdateImage();

                        MessageBox.Show("Error: Couldn't set image file! File might be too large to load in", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    block.RawData = compressedNewMIO0;
                }

                if (_image.Format == Texture.ImageFormat.CI && _image.PaletteEncoding[0] == MK64Image.MK64ImageEncoding.MIO0)
                {
                    if (!RomProject.Instance.Files[0].HasElementAt(_image.TextureOffset, out el))
                    {
                        MessageBox.Show("Error: Couldn't set image file! Could not find MIO0 block.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    MIO0Block block = (MIO0Block)el;

                    byte[] oldMIO0Data = block.DecodedData;

                    Array.Copy(newPaletteData, 0, oldMIO0Data, _image.PaletteBlockOffset[0], newPaletteData.Length);

                    byte[] compressedNewMIO0 = MIO0.Encode(oldMIO0Data);

                    int sizeCompare = (_specialMIO0Length != -1 && block.FileOffset == 0x132B50 ? _specialMIO0Length : block.RawDataSize);

                    if (compressedNewMIO0.Length > sizeCompare)
                    {
                        _image.ImageReference.Texture.RawData = oldData;
                        if (_image.Format == Texture.ImageFormat.CI)
                        {
                            _image.ImageReference.BasePalettes[0].RawData = oldPaletteData;
                        }
                        _image.ImageReference.UpdateImage();

                        //Revert texture
                        if (_image.TextureEncoding == MK64Image.MK64ImageEncoding.MIO0)
                        {
                            N64DataElement element;
                            if (!RomProject.Instance.Files[0].HasElementExactlyAt(_image.TextureOffset, out element))
                            {
                                throw new Exception();
                            }
                            MIO0Block blockText = (MIO0Block)element;

                            blockText.RawData = oldMIO0RefData;
                        }

                        MessageBox.Show("Error: Couldn't set image file! File might be too large to load in", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    block.RawData = compressedNewMIO0;
                }

                Image = _image; //Reset it
                ImageUpdated();
            }
        }
        public void SaveKartInfo()
        {
            if (KartGraphicsBlock == null)
            {
                return;
            }

            //These hold the palette blocks associated with each animation
            Dictionary <KartAnimationSeries, KartPaletteBlock> TurnPaletteBlocks =
                new Dictionary <KartAnimationSeries, KartPaletteBlock>();
            Dictionary <KartAnimationSeries, KartPaletteBlock> SpinPaletteBlocks =
                new Dictionary <KartAnimationSeries, KartPaletteBlock>();
            int turnPaletteBlockIndex = 0;
            int spinPaletteBlockIndex = 0;

            for (int i = 0; i < MarioKart64ElementHub.Instance.SelectedKarts.Length; i++)
            {
                KartInfo kart = MarioKart64ElementHub.Instance.SelectedKarts[i];

                //Save the main palette
                if (kart.KartImages.ImagePalette.FileOffset == -1)
                {
                    kart.KartImages.ImagePalette.FileOffset = NewElementOffset;
                    AdvanceNewElementOffset(kart.KartImages.ImagePalette);
                    RomProject.Instance.Files[0].AddElement(kart.KartImages.ImagePalette);
                }

                KartGraphicsBlock.CharacterPaletteReferences[i] = new DmaAddress(0x0F, kart.KartImages.ImagePalette.FileOffset - KartGraphicsReferenceBlock.DMA_SEGMENT_OFFSET);
                KartGraphicsBlock.CharacterPaletteReferences[i].ReferenceElement = kart.KartImages.ImagePalette;

                //Save the kart palettes in BLOCKS!
                //but first, assign each unique animation its own PaletteBlock, adding new ones as necessary

                //Backwards, so the order is preserved
                for (int h = kart.KartAnimations.Count - 1; h >= 0; h--)
                {
                    KartAnimationSeries anim = kart.KartAnimations[h];
                    if (anim.IsTurnAnim)
                    {
                        if (!TurnPaletteBlocks.ContainsKey(anim))
                        {
                            while (this.TurnKartPaletteBlocks.Count <= turnPaletteBlockIndex)
                            {
                                byte[]           newPaletteBlockData = new byte[0x40 * 2 * 20 * 4];
                                KartPaletteBlock block = new KartPaletteBlock(this.NewElementOffset, newPaletteBlockData);
                                foreach (Palette palette in block.Palettes)
                                {
                                    RomProject.Instance.Files[0].AddElement(palette);
                                }
                                this.AdvanceNewElementOffset(block);
                                this.TurnKartPaletteBlocks.Add(block);
                            }

                            TurnPaletteBlocks.Add(anim, this.TurnKartPaletteBlocks[turnPaletteBlockIndex]);
                            turnPaletteBlockIndex++;

                            byte[] testingBytes = anim.GenerateKartAnimationPaletteData(
                                kart.KartImages, true);

                            TurnPaletteBlocks[anim].RawData = testingBytes;
                        }
                    }

                    if (anim.IsSpinAnim)
                    {
                        if (!SpinPaletteBlocks.ContainsKey(anim))
                        {
                            while (this.SpinKartPaletteBlocks.Count <= spinPaletteBlockIndex)
                            {
                                byte[]           newPaletteBlockData = new byte[0x40 * 2 * 20 * 4];
                                KartPaletteBlock block = new KartPaletteBlock(this.NewElementOffset, newPaletteBlockData);
                                foreach (Palette palette in block.Palettes)
                                {
                                    RomProject.Instance.Files[0].AddElement(palette);
                                }
                                this.AdvanceNewElementOffset(block);
                                this.SpinKartPaletteBlocks.Add(block);
                            }

                            SpinPaletteBlocks.Add(anim, this.SpinKartPaletteBlocks[spinPaletteBlockIndex]);
                            spinPaletteBlockIndex++;

                            SpinPaletteBlocks[anim].RawData = anim.GenerateKartAnimationPaletteData(
                                kart.KartImages, false);
                        }
                    }
                }

                List <int> setAnimPaletteBlock = new List <int>();

                for (int j = 0; j < KartGraphicsBlock.CharacterTurnReferences[i].Length; j++)
                {
                    int  animFlag;
                    int  frameIndex; //Theres a function for this in KartReader?
                    bool isTurnAnim = true;

                    if (j < KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT * KartGraphicsReferenceBlock.FULL_TURN_REF_COUNT)
                    {
                        animFlag   = (int)Math.Round(Math.Pow(2, j / KartGraphicsReferenceBlock.FULL_TURN_REF_COUNT));
                        frameIndex = j - (j / KartGraphicsReferenceBlock.FULL_TURN_REF_COUNT) * KartGraphicsReferenceBlock.FULL_TURN_REF_COUNT;

                        //The last 14 values of the turn animation are from the spin one, actually
                        if (frameIndex >= KartGraphicsReferenceBlock.HALF_TURN_REF_COUNT)
                        {
                            animFlag  <<= 9;     //Make it spin anim, not turn anim
                            frameIndex -= 15;
                            isTurnAnim  = false; //Don't do palette block stuff for this one
                        }
                    }
                    else
                    {
                        animFlag   = (int)Math.Round(Math.Pow(2, (j - KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT * KartGraphicsReferenceBlock.FULL_TURN_REF_COUNT) / KartGraphicsReferenceBlock.FULL_SPIN_REF_COUNT + KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT));
                        frameIndex = j - (KartGraphicsReferenceBlock.FULL_TURN_REF_COUNT * KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT) - ((j - KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT * KartGraphicsReferenceBlock.FULL_TURN_REF_COUNT) / KartGraphicsReferenceBlock.FULL_SPIN_REF_COUNT) * KartGraphicsReferenceBlock.FULL_SPIN_REF_COUNT;
                        isTurnAnim = false;
                    }

                    KartAnimationSeries anim = kart.KartAnimations.FirstOrDefault(f => (f.KartAnimationType & animFlag) != 0);
                    if (anim != null)
                    {
                        //Need to replace animIndex with GetIndexfor(animIndex), but we need a better spin/turn/crash test
                        string imageName;
                        if (anim.IsTurnAnim)
                        {
                            imageName = anim.OrderedImageNames[anim.GetImageIndexForTurnFrame(frameIndex)];
                        }
                        else //if (anim.IsSpinAnim)
                        {
                            imageName = anim.OrderedImageNames[anim.GetImageIndexForSpinFrame(frameIndex)];
                        }

                        MK64Image mkImage = kart.KartImages.Images[imageName].Images[0];

                        //Save the image
                        if (mkImage.TextureOffset == -1)
                        {
                            //It has to be an MIO0 block
                            foreach (MK64Image editThisImage in kart.KartImages.Images[imageName].Images)
                            {
                                editThisImage.TextureBlockOffset = 0;
                                editThisImage.TextureOffset      = NewElementOffset;
                            }
                            mkImage.ImageReference.Texture.FileOffset = 0;
                            MIO0Block newBlock = new MIO0Block(NewElementOffset, mkImage.ImageReference.Texture.RawData);
                            AdvanceNewElementOffset(newBlock);
                            RomProject.Instance.Files[0].AddElement(newBlock);
                        }

                        DmaAddress     address = new DmaAddress(0x0F, mkImage.TextureOffset - KartGraphicsReferenceBlock.DMA_SEGMENT_OFFSET);
                        N64DataElement blockEl;

                        if (!RomProject.Instance.Files[0].HasElementAt(mkImage.TextureOffset, out blockEl))
                        {
                            throw new Exception();
                        }
                        MIO0Block block = (MIO0Block)blockEl;
                        address.ReferenceElement = block;
                        KartGraphicsBlock.CharacterTurnReferences[i][j] = address;

                        int animIndex;
                        if (animFlag == 0)
                        {
                            animIndex = 0;
                        }
                        else
                        {
                            animIndex = (int)Math.Round(Math.Log(animFlag, 2));
                        }

                        //inverse the animation index
                        if (animIndex < 9)
                        {
                            animIndex = 8 - animIndex;
                        }
                        else
                        {
                            animIndex = (8 - (animIndex - 9)) + 9;
                        }

                        if (!setAnimPaletteBlock.Contains(animIndex))
                        {
                            if (isTurnAnim)
                            {
                                KartGraphicsBlock.WheelPaletteReferences[i][animIndex] = new DmaAddress(0x0F, TurnPaletteBlocks[anim].FileOffset - KartGraphicsReferenceBlock.DMA_SEGMENT_OFFSET);
                            }
                            else
                            {
                                KartGraphicsBlock.WheelPaletteReferences[i][animIndex] = new DmaAddress(0x0F, SpinPaletteBlocks[anim].FileOffset - KartGraphicsReferenceBlock.DMA_SEGMENT_OFFSET);
                            }
                            setAnimPaletteBlock.Add(animIndex);
                        }
                    }
                }

                for (int j = 0; j < KartGraphicsBlock.CharacterCrashReferences[i].Length; j++)
                {
                    KartAnimationSeries anim = kart.KartAnimations.FirstOrDefault(f => (f.KartAnimationType & (int)KartAnimationSeries.KartAnimationTypeFlag.Crash) != 0);
                    if (anim != null)
                    {
                        MK64Image mkImage = kart.KartImages.Images[anim.OrderedImageNames[anim.GetImageIndexForCrashFrame(j)]].Images[0];

                        if (mkImage.TextureOffset == -1)
                        {
                            foreach (MK64Image editThisImage in kart.KartImages.Images[anim.OrderedImageNames[anim.GetImageIndexForCrashFrame(j)]].Images)
                            {
                                editThisImage.TextureBlockOffset = 0;
                                editThisImage.TextureOffset      = NewElementOffset;
                            }
                            mkImage.ImageReference.Texture.FileOffset = 0;
                            MIO0Block newBlock = new MIO0Block(NewElementOffset, mkImage.ImageReference.Texture.RawData);
                            AdvanceNewElementOffset(newBlock);
                            RomProject.Instance.Files[0].AddElement(newBlock);
                        }

                        N64DataElement element;
                        if (!RomProject.Instance.Files[0].HasElementExactlyAt(mkImage.TextureOffset, out element))
                        {
                            throw new Exception();
                        }
                        MIO0Block block = (MIO0Block)element;

                        //Save the image
                        if (block.FileOffset == -1)
                        {
                            block.FileOffset = NewElementOffset;
                            AdvanceNewElementOffset(block);
                            RomProject.Instance.Files[0].AddElement(block);
                        }

                        DmaAddress address = new DmaAddress(0x0F, block.FileOffset - KartGraphicsReferenceBlock.DMA_SEGMENT_OFFSET);
                        address.ReferenceElement = block;
                        KartGraphicsBlock.CharacterCrashReferences[i][j] = address;
                    }
                }

                for (int j = 0; j < kart.KartPortraits.Count; j++)
                {
                    if (kart.KartPortraits[j].TextureOffset == -1)
                    {
                        kart.KartPortraits[j].TextureBlockOffset = 0;
                        kart.KartPortraits[j].TextureOffset      = NewElementOffset;
                        kart.KartPortraits[j].ImageReference.Texture.FileOffset = 0;
                        MIO0Block newBlock = new MIO0Block(NewElementOffset, kart.KartPortraits[j].ImageReference.Texture.RawData);
                        AdvanceNewElementOffset(newBlock);
                        RomProject.Instance.Files[0].AddElement(newBlock);
                    }

                    KartPortraitTableEntry entry = new KartPortraitTableEntry(kart.KartPortraits[j].TextureOffset, kart.KartPortraits[j]);
                    KartPortraitsTable.Entries[i][j] = entry;
                }

                N64DataElement tkmk;
                if (RomProject.Instance.Files[0].HasElementExactlyAt(MarioKartRomInfo.CharacterNameplateReference[i], out tkmk) && tkmk  is TKMK00Block)
                {
                    TKMK00Block oldTkmk = (TKMK00Block)tkmk;
                    oldTkmk.ImageAlphaColor = kart.KartNamePlate.TKMKAlphaColor;
                    oldTkmk.SetImage(kart.KartNamePlate.Image);
                }
            }
        }
Exemple #4
0
        private void btnApply_Click(object sender, EventArgs e)
        {
            bool hasChanges = false;

            for (int i = 0; i < lbBefore.Items.Count; i++)
            {
                if (lbBefore.Items[i] != lbAfter.Items[i])
                {
                    hasChanges = true;
                    break;
                }
            }

            if (!hasChanges) //Quit out if no changes
            {
                this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
                return;
            }

            //if the mode is texture, then do something new.
            //if the mode is palette, then generate the palette BEFORE making the image

            if (Mode == SharedMode.Texture)
            {
                //IDEA: AVERAGE ALL THE IMAGES TOGETHER, THEN MAKE A CI PALETTE/TEXTURE FROM THAT. THEN WE HAVE OUR TEXTURE.
                //       AFTER THAT, WE NEED TO ASSIGN PALETTES TO IT. I GUESS WE CAN AVERAGE ALL COLORS THAT HIT EACH POINT
                //       FOR EACH IMAGE

                //Slow process
                Bitmap refImage = new Bitmap(Images[0].Image);

                int width      = Images[0].Image.Width;
                int height     = Images[0].Height;
                int pixelCount = width * height;
                int imageCount = lbAfter.Items.Count;
                int colorCount = Images[0].ImageReference.BasePalettes[0].Colors.Length;

                int[] redCount   = new int[pixelCount];
                int[] blueCount  = new int[pixelCount];
                int[] greenCount = new int[pixelCount];
                int[] alphaCount = new int[pixelCount];

                foreach (BitmapWrapper wrapper in lbAfter.Items)
                {
                    for (int j = 0; j < width; j++)
                    {
                        for (int i = 0; i < height; i++)
                        {
                            Color pixel = wrapper.BMP.GetPixel(i, j);
                            redCount[i + j * wrapper.BMP.Width]   += pixel.R;
                            greenCount[i + j * wrapper.BMP.Width] += pixel.G;
                            blueCount[i + j * wrapper.BMP.Width]  += pixel.B;
                            alphaCount[i + j * wrapper.BMP.Width] += pixel.A;
                        }
                    }
                }

                for (int j = 0; j < height; j++)
                {
                    for (int i = 0; i < width; i++)
                    {
                        refImage.SetPixel(i, j,
                                          Color.FromArgb(alphaCount[i + j * width] / imageCount,
                                                         redCount[i + j * width] / imageCount,
                                                         greenCount[i + j * width] / imageCount,
                                                         blueCount[i + j * width] / imageCount));
                    }
                }

                //Now do the set-texture palette search method
                Palette tempPalette      = new Palette(-1, new byte[colorCount * 2]);
                byte[]  finalTextureData = TextureConversion.ImageToBinary(Images[0].Format, Images[0].PixelSize, refImage, ref tempPalette, true);
                Images[0].ImageReference.Texture.RawData = finalTextureData;

                //Now take this and do some stupid shit
                for (int k = 0; k < imageCount; k++)
                {
                    redCount   = new int[colorCount];
                    greenCount = new int[colorCount];
                    blueCount  = new int[colorCount];
                    alphaCount = new int[colorCount];

                    Bitmap img = (Bitmap)lbAfter.Items[k];

                    for (int j = 0; j < height; j++)
                    {
                        for (int i = 0; i < width; i++)
                        {
                            Color color = img.GetPixel(i, j);

                            int textureNum = 0;
                            if (Images[k].PixelSize == Texture.PixelInfo.Size_8b)
                            {
                                textureNum = finalTextureData[i + j * height];
                            }
                            else
                            {
                                byte val = finalTextureData[(i + j * height) / 2];
                                if ((i + j * height) % 2 == 0)
                                {
                                    textureNum = val >> 4;
                                }
                                else
                                {
                                    textureNum = val & 0xF;
                                }
                            }

                            redCount[textureNum]   += color.R;
                            greenCount[textureNum] += color.G;
                            blueCount[textureNum]  += color.B;
                            alphaCount[textureNum] += color.A;
                        }
                    }

                    //Now that we have the colors added up, we calculate the new colors and that's our new palette!
                    Color[] colors = new Color[colorCount];

                    for (int i = 0; i < colorCount; i++)
                    {
                        colors[i] = Color.FromArgb(alphaCount[i] / imageCount,
                                                   redCount[i] / imageCount,
                                                   greenCount[i] / imageCount,
                                                   blueCount[i] / imageCount);
                    }

                    byte[] newPaletteData = TextureConversion.PaletteToBinary(colors);
                    Images[k].ImageReference.BasePalettes[0].RawData = newPaletteData;
                }
            }
            else
            {
                PaletteMedianCutAnalyzer paletteMaker = new PaletteMedianCutAnalyzer();
                foreach (BitmapWrapper wrapper in lbAfter.Items)
                {
                    for (int i = 0; i < wrapper.BMP.Width; i++)
                    {
                        for (int j = 0; j < wrapper.BMP.Height; j++)
                        {
                            paletteMaker.AddColor(wrapper.BMP.GetPixel(i, j));
                        }
                    }
                }

                Color[] colors         = paletteMaker.GetPalette(Images[0].ImageReference.BasePalettes[0].Colors.Length);
                byte[]  paletteData    = TextureConversion.PaletteToBinary(colors);
                Palette palette        = new Palette(-1, paletteData);
                byte[]  newPaletteData = palette.RawData;
                Images[0].ImageReference.BasePalettes[0].RawData = newPaletteData;

                if (Images[0].PaletteEncoding[0] == MK64Image.MK64ImageEncoding.MIO0)
                {
                    N64DataElement element;
                    if (!RomProject.Instance.Files[0].HasElementExactlyAt(Images[0].PaletteOffset[0], out element))
                    {
                        throw new Exception();
                    }
                    MIO0Block block       = (MIO0Block)element;
                    byte[]    oldMIO0Data = block.DecodedData;

                    Array.Copy(newPaletteData, 0, oldMIO0Data, Images[0].PaletteBlockOffset[0], newPaletteData.Length);

                    byte[] compressedNewMIO0 = MIO0.Encode(oldMIO0Data);

                    block.RawData = compressedNewMIO0;
                }

                //Now generate the images
                for (int i = 0; i < Images.Count; i++)
                {
                    MK64Image image   = Images[i];
                    Bitmap    bmp     = ((BitmapWrapper)lbAfter.Items[i]).BMP;
                    byte[]    newData = TextureConversion.ImageToBinary(image.Format, image.PixelSize, bmp, ref palette, false);

                    if (newData == null || newData.Length == 0)
                    {
                        MessageBox.Show("Error: Couldn't convert image file!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    image.ImageReference.Texture.RawData = newData;
                    image.ImageReference.UpdateImage();

                    if (image.TextureEncoding == MK64Image.MK64ImageEncoding.MIO0)
                    {
                        N64DataElement element;
                        if (!RomProject.Instance.Files[0].HasElementExactlyAt(image.TextureOffset, out element))
                        {
                            throw new Exception();
                        }
                        MIO0Block block = (MIO0Block)element;

                        byte[] MIO0Data = block.DecodedData;

                        Array.Copy(newData, 0, MIO0Data, image.TextureBlockOffset, newData.Length);

                        byte[] compressedNewMIO0 = MIO0.Encode(MIO0Data);

                        block.RawData = compressedNewMIO0;
                    }
                }
            }
        }
Exemple #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;
        }
Exemple #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);
        }
Exemple #7
0
        private static void LoadKartInfo(KartGraphicsReferenceBlock block, KartPortraitTable portraits, BackgroundWorker worker, byte[] data, TextureReaderResults textureResults, KartReaderResults results)
        {
            for (int i = 0; i < KartGraphicsReferenceBlock.CHARACTER_COUNT; i++)
            {
                string kartName = Enum.GetName(typeof(MarioKartRomInfo.OriginalCharacters), i);

                KartInfo newKart = new KartInfo(kartName, (Palette)block.CharacterPaletteReferences[i].ReferenceElement, true);

                KartAnimationSeries[] turnAnims = new KartAnimationSeries[KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT];
                KartAnimationSeries[] spinAnims = new KartAnimationSeries[KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT];
                KartAnimationSeries   crashAnim;

                MIO0Block[][] turnBlocks = new MIO0Block[KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT][];
                for (int k = 0; k < KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT; k++)
                {
                    turnBlocks[k] = new MIO0Block[KartGraphicsReferenceBlock.HALF_TURN_REF_COUNT];
                }

                MIO0Block[][] spinBlocks = new MIO0Block[KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT][];
                for (int k = 0; k < KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT; k++)
                {
                    spinBlocks[k] = new MIO0Block[KartGraphicsReferenceBlock.FULL_SPIN_REF_COUNT];
                }

                DmaAddress[] wheelPaletteReferences = block.WheelPaletteReferences[i];

                turnAnims[0] = new KartAnimationSeries(kartName + " Turn Down 25");
                turnAnims[0].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.RearTurnDown25;
                turnAnims[1] = new KartAnimationSeries(kartName + " Turn Down 19");
                turnAnims[1].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.RearTurnDown19;
                turnAnims[2] = new KartAnimationSeries(kartName + " Turn Down 12");
                turnAnims[2].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.RearTurnDown12;
                turnAnims[3] = new KartAnimationSeries(kartName + " Turn Down 6");
                turnAnims[3].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.RearTurnDown6;
                turnAnims[4] = new KartAnimationSeries(kartName + " Turn 0");
                turnAnims[4].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.RearTurn0;
                turnAnims[5] = new KartAnimationSeries(kartName + " Turn Up 6");
                turnAnims[5].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.RearTurnUp6;
                turnAnims[6] = new KartAnimationSeries(kartName + " Turn Up 12");
                turnAnims[6].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.RearTurnUp12;
                turnAnims[7] = new KartAnimationSeries(kartName + " Turn Up 19");
                turnAnims[7].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.RearTurnUp19;
                turnAnims[8] = new KartAnimationSeries(kartName + " Turn Up 25");
                turnAnims[8].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.RearTurnUp25;

                spinAnims[0] = new KartAnimationSeries(kartName + " Spin Down 25");
                spinAnims[0].KartAnimationType = (int)(KartAnimationSeries.KartAnimationTypeFlag.FullSpinDown25 |
                                                       KartAnimationSeries.KartAnimationTypeFlag.FullSpinDown19);
                spinAnims[1] = spinAnims[0];
                spinAnims[2] = new KartAnimationSeries(kartName + " Spin Down 12");
                spinAnims[2].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.FullSpinDown12;
                spinAnims[3] = new KartAnimationSeries(kartName + " Spin 0");
                spinAnims[3].KartAnimationType = (int)(KartAnimationSeries.KartAnimationTypeFlag.FullSpinDown6 |
                                                       KartAnimationSeries.KartAnimationTypeFlag.FullSpin0 | KartAnimationSeries.KartAnimationTypeFlag.FullSpinUp6);
                spinAnims[4] = spinAnims[3];
                spinAnims[5] = spinAnims[3];
                spinAnims[6] = new KartAnimationSeries(kartName + " Spin Up 12");
                spinAnims[6].KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.FullSpinUp12;
                spinAnims[7] = new KartAnimationSeries(kartName + " Spin Up 25");
                spinAnims[7].KartAnimationType = (int)(KartAnimationSeries.KartAnimationTypeFlag.FullSpinUp19 |
                                                       KartAnimationSeries.KartAnimationTypeFlag.FullSpinUp25);
                spinAnims[8] = spinAnims[7];

                crashAnim = new KartAnimationSeries(kartName + " Crash");
                crashAnim.KartAnimationType = (int)KartAnimationSeries.KartAnimationTypeFlag.Crash;

                //use to generate the ordered image names
                Dictionary <MIO0Block, string> MioToImageName = new Dictionary <MIO0Block, string>();

                //Work backwards, to help with image naming
                for (short j = 0; j < KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT * KartGraphicsReferenceBlock.FULL_TURN_REF_COUNT + KartGraphicsReferenceBlock.ANIMATION_ANGLE_COUNT * KartGraphicsReferenceBlock.FULL_SPIN_REF_COUNT; j++)
                {
                    MIO0Block imageBlock = (MIO0Block)block.CharacterTurnReferences[i][j].ReferenceElement;
                    Texture   texture    = (Texture)imageBlock.Element;

                    List <MK64Image> images;
                    if (textureResults.ImagesByTexture.ContainsKey(texture))
                    {
                        images = new List <MK64Image>(textureResults.ImagesByTexture[texture]);
                    }
                    else if (MarioKart64ElementHub.Instance.TextureHub.HasImagesForTexture(texture))
                    {
                        images = MarioKart64ElementHub.Instance.TextureHub.ImagesForTexture(texture);
                    }
                    else
                    {
                        throw new Exception();
                    }

                    string imageName = images[0].ImageName;

                    //Jump out if the image block has already been handled
                    if (!string.IsNullOrWhiteSpace(imageName) && newKart.KartImages.Images.ContainsKey(imageName))
                    {
                        continue;
                    }

                    int  animIndex, frameIndex;
                    bool isTurnAnim;

                    GetAnimationFrameIndices(j, out animIndex, out frameIndex, out isTurnAnim);

                    if (isTurnAnim)
                    {
                        if (turnBlocks[animIndex][frameIndex] == null)
                        {
                            turnBlocks[animIndex][frameIndex] = imageBlock;
                        }
                    }
                    else
                    {
                        if (spinBlocks[animIndex][frameIndex] == null)
                        {
                            spinBlocks[animIndex][frameIndex] = imageBlock;
                        }
                    }

                    if (!newKart.KartImages.Images.ContainsKey(imageName))
                    {
                        newKart.KartImages.Images.Add(imageName, new KartImage(images));
                    }

                    MioToImageName.Add(imageBlock, imageName);
                }

                for (int j = 0; j < spinBlocks.Length; j++)
                {
                    //Don't deal with duplicate animations
                    if (j != 0 && spinAnims[j] == spinAnims[j - 1])
                    {
                        continue;
                    }

                    for (int k = 0; k < spinBlocks[j].Length; k++)
                    {
                        if (spinBlocks[j][k] != null)
                        {
                            spinAnims[j].OrderedImageNames.Add(MioToImageName[spinBlocks[j][k]]);
                        }
                    }
                }

                for (int j = 0; j < turnBlocks.Length; j++)
                {
                    for (int k = 0; k < turnBlocks[j].Length; k++)
                    {
                        if (turnBlocks[j][k] != null)
                        {
                            turnAnims[j].OrderedImageNames.Add(MioToImageName[turnBlocks[j][k]]);
                        }
                    }
                }

                for (int j = 0; j < block.CharacterCrashReferences[i].Length; j++)
                {
                    MIO0Block imageBlock = (MIO0Block)block.CharacterCrashReferences[i][j].ReferenceElement;
                    Texture   texture    = (Texture)imageBlock.Element;

                    List <MK64Image> images;
                    if (textureResults.ImagesByTexture.ContainsKey(texture))
                    {
                        images = new List <MK64Image>(textureResults.ImagesByTexture[texture]);
                    }
                    else if (MarioKart64ElementHub.Instance.TextureHub.HasImagesForTexture(texture))
                    {
                        images = MarioKart64ElementHub.Instance.TextureHub.ImagesForTexture(texture);
                    }
                    else
                    {
                        throw new Exception();
                    }

                    string imageName = images[0].ImageName;

                    crashAnim.OrderedImageNames.Add(imageName);

                    if (!newKart.KartImages.Images.ContainsKey(imageName))
                    {
                        newKart.KartImages.Images.Add(imageName, new KartImage(images));
                    }
                }

                for (int j = 0; j < turnAnims.Length; j++)
                {
                    newKart.KartAnimations.Add(turnAnims[j]);
                }

                for (int j = 0; j < spinAnims.Length; j++)
                {
                    //Don't store duplicate animations
                    if (j != 0 && spinAnims[j] == spinAnims[j - 1])
                    {
                        continue;
                    }

                    newKart.KartAnimations.Add(spinAnims[j]);
                }

                newKart.KartAnimations.Add(crashAnim);

                for (int j = 0; j < portraits.Entries[i].Count; j++)
                {
                    newKart.KartPortraits.Add(portraits.Entries[i][j].ImageReference);
                }

                //Find the tkmk block in either the new images or in the hub
                MK64Image img;
                if ((img = MarioKart64ElementHub.Instance.TextureHub.Images.SingleOrDefault(im => im.ImageName == TextureNames.PORTAIT_NAME_ARRAY[i])) != null)
                {
                    newKart.KartNamePlate = img;
                }
                else if ((img = textureResults.NewImages.SingleOrDefault(im => im.ImageName == TextureNames.PORTAIT_NAME_ARRAY[i])) != null)
                {
                    newKart.KartNamePlate = img;
                }
                else
                {
                    throw new Exception();
                }

                MarioKart64ElementHub.Instance.Karts.Add(newKart);
                MarioKart64ElementHub.Instance.SelectedKarts[i] = newKart;
                RomProject.Instance.AddRomItem(newKart);
            }
        }
Exemple #8
0
        private void btnAddImage_Click(object sender, EventArgs e)
        {
            if (_newImageForm == null)
            {
                _newImageForm = new NewMK64ImageForm();
            }

            if (_newImageForm.ShowDialog() == DialogResult.OK)
            {
                List <MK64Image> newImages = new List <MK64Image>();
                foreach (string FileName in _newImageForm.FileNames)
                {
                    //To do: make it load multiple at a time!
                    Bitmap bmp = (Bitmap)Bitmap.FromFile(FileName);

                    if (bmp == null)
                    {
                        MessageBox.Show("Could not load image:\n" + FileName, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        continue;
                    }

                    byte[] imageData;

                    Texture texture;
                    Palette palette = null;

                    if (_newImageForm.Format == Texture.ImageFormat.CI)
                    {
                        byte[] paletteData = new byte[2 * _newImageForm.PaletteColorCount];
                        palette   = new Palette(-1, paletteData);
                        imageData = TextureConversion.ImageToBinary(_newImageForm.Format, _newImageForm.PixelSize, bmp,
                                                                    ref palette, true);
                    }
                    else
                    {
                        imageData = TextureConversion.ImageToBinary(_newImageForm.Format, _newImageForm.PixelSize, bmp);
                    }

                    texture = new Texture(-1, imageData, _newImageForm.Format, _newImageForm.PixelSize,
                                          bmp.Width, bmp.Height);

                    //Now, if necessary, encode the texture!!
                    MIO0Block textureBlock = null, paletteBlock = null;
                    if (_newImageForm.EncodeTexture)
                    {
                        byte[] encodedData = MIO0.Encode(texture.RawData);
                        textureBlock = new MIO0Block(-1, encodedData);
                        textureBlock.AddElement(texture);
                        texture.FileOffset = 0;
                    }

                    if (palette != null && _newImageForm.EncodePalette)
                    {
                        byte[] encodedData = MIO0.Encode(palette.RawData);
                        paletteBlock = new MIO0Block(-1, encodedData);
                        paletteBlock.AddElement(palette);
                        palette.FileOffset = 0;
                    }

                    //Add in the texture/palette to the new data location
                    if (textureBlock != null)
                    {
                        textureBlock.FileOffset = MarioKart64ElementHub.Instance.NewElementOffset;
                        RomProject.Instance.Files[0].AddElement(textureBlock);
                        MarioKart64ElementHub.Instance.AdvanceNewElementOffset(textureBlock);
                    }
                    else
                    {
                        texture.FileOffset = MarioKart64ElementHub.Instance.NewElementOffset;
                        RomProject.Instance.Files[0].AddElement(texture);
                        MarioKart64ElementHub.Instance.AdvanceNewElementOffset(texture);
                    }

                    if (palette != null)
                    {
                        if (paletteBlock != null)
                        {
                            paletteBlock.FileOffset = MarioKart64ElementHub.Instance.NewElementOffset;
                            RomProject.Instance.Files[0].AddElement(paletteBlock);
                            MarioKart64ElementHub.Instance.AdvanceNewElementOffset(paletteBlock);
                        }
                        else
                        {
                            palette.FileOffset = MarioKart64ElementHub.Instance.NewElementOffset;
                            RomProject.Instance.Files[0].AddElement(palette);
                            MarioKart64ElementHub.Instance.AdvanceNewElementOffset(palette);
                        }
                    }

                    //Add in the new MK64Image
                    int tFileOffset = (textureBlock == null ? texture.FileOffset : textureBlock.FileOffset);
                    MK64Image.MK64ImageEncoding tEncoding = (textureBlock == null ? MK64Image.MK64ImageEncoding.Raw : MK64Image.MK64ImageEncoding.MIO0);
                    int        tBlockOffset  = (textureBlock == null ? -1 : texture.FileOffset);
                    List <int> PaletteOffset = new List <int>();
                    List <MK64Image.MK64ImageEncoding> PaletteEncodings = new List <MK64Image.MK64ImageEncoding>();
                    List <int> PaletteBlockOffset = new List <int>();
                    List <int> PaletteColorCount  = new List <int>();
                    List <int> PaletteColorOffset = new List <int>();
                    if (palette != null)
                    {
                        PaletteOffset.Add(paletteBlock == null ? palette.FileOffset : paletteBlock.FileOffset);
                        PaletteEncodings.Add(paletteBlock == null ? MK64Image.MK64ImageEncoding.Raw : MK64Image.MK64ImageEncoding.MIO0);
                        PaletteBlockOffset.Add(paletteBlock == null ? -1 : palette.FileOffset);
                        PaletteColorCount.Add(palette.Colors.Length);
                        PaletteColorOffset.Add(0);
                    }

                    MK64Image newImage = new MK64Image(tFileOffset,
                                                       tEncoding,
                                                       tBlockOffset,
                                                       _newImageForm.Format,
                                                       _newImageForm.PixelSize,
                                                       bmp.Width,
                                                       bmp.Height,
                                                       false,
                                                       PaletteOffset,
                                                       PaletteEncodings,
                                                       PaletteBlockOffset,
                                                       PaletteColorCount,
                                                       PaletteColorOffset,
                                                       0, 0, Path.GetFileNameWithoutExtension(FileName));

                    MarioKart64ElementHub.Instance.TextureHub.AddImage(newImage);
                    newImages.Add(newImage);
                }

                if (newImages.Count > 1)
                {
                    MessageBox.Show(string.Format("{0} images loaded!", newImages.Count), "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }

                if (newImages.Count > 0)
                {
                    int newSelectedIndex = lbImages.Items.Count;
                    lbImages.Items.AddRange(newImages.ToArray());

                    //Update the image count & selected
                    lbImages.SelectedIndex = newSelectedIndex;
                    UpdateImageCount();
                }
            }
        }