Example #1
0
        private void btnImportNamePlate_Click(object sender, EventArgs e)
        {
            if (openNamePlateDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                //Open the file, load into the image place if it works, update the kart
                Image img = Bitmap.FromFile(openNamePlateDialog.FileName);
                if (img.Width != 64 || img.Height != 12)
                {
                    MessageBox.Show("Image must be 64x12!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (img != null)
                {
                    //Copy the old name plate to make the new one
                    byte[]      imgData = Cereal64.Microcodes.F3DEX.DataElements.TextureConversion.RGBA16ToBinary((Bitmap)img);
                    TKMK00Block tkmk    = new TKMK00Block(-1, Pitstop64.Services.TKMK00.Encode(imgData, img.Width, img.Height, 0), 0);

                    MK64Image image = new MK64Image(tkmk, Path.GetFileNameWithoutExtension(openNamePlateDialog.FileName));

                    Kart.SetNamePlate(image);

                    pbNamePlate.Image = tkmk.Image;
                }
            }
        }
        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);
                }
            }
        }