Inheritance: MonoBehaviour
Example #1
0
        private void btnImportKart_Click(object sender, EventArgs e)
        {
            if (openKartDialog.ShowDialog() == DialogResult.OK)
            {
                List <KartInfo> karts = KartInfo.LoadFromFile(openKartDialog.FileName);

                int addedKarts = 0;

                foreach (KartInfo kart in karts)
                {
                    if (MarioKart64ElementHub.Instance.Karts.SingleOrDefault(k => k.KartName == kart.KartName) == null)
                    {
                        MarioKart64ElementHub.Instance.Karts.Add(kart);
                        RomProject.Instance.AddRomItem(kart);
                        addedKarts++;
                    }
                }


                if (addedKarts > 0)
                {
                    if (karts.Count == 1)
                    {
                        //Single kart, success
                        MessageBox.Show("Kart loaded");
                    }
                    else
                    {
                        if (addedKarts != karts.Count)
                        {
                            //Some failure
                            MessageBox.Show("Failed to load some karts (kart name already exists)");
                        }
                        else
                        {
                            MessageBox.Show("Karts loaded");
                        }
                    }
                    UpdateReferences();
                }
                else
                {
                    if (karts.Count == 0)
                    {
                        //No karts from start
                        MessageBox.Show("No karts found!");
                    }
                    else if (karts.Count == 1)
                    {
                        //Single kart, name taken
                        MessageBox.Show("Kart failed to load (kart name already exists)");
                    }
                    else
                    {
                        //Multi karts, all names taken
                        MessageBox.Show("All karts failed to loaded (kart names already exist)");
                    }
                }
            }
        }
Example #2
0
        private void UpdateSelectedKartList()
        {
            KartInfo selectedKart = (KartInfo)lbKarts.SelectedItem;

            lbKarts.Items.Clear();
            cbKartList.Items.Clear();

            if (MarioKart64ElementHub.Instance.Karts.Count == 0)
            {
                return;
            }

            foreach (KartInfo kart in MarioKart64ElementHub.Instance.SelectedKarts)
            {
                lbKarts.Items.Add(kart);
            }

            foreach (KartInfo kart in MarioKart64ElementHub.Instance.Karts)
            {
                cbKartList.Items.Add(kart);
            }

            if (selectedKart != null && cbKartList.Items.Contains(selectedKart))
            {
                cbKartList.SelectedItem = selectedKart;
            }
            else if (cbKartList.Items.Count > 0)
            {
                cbKartList.SelectedIndex = 0;
            }

            UpdateSelectedKartButtons();
        }
Example #3
0
 public KartWrapper(KartWrapper kartWrapper, string newName)
 {
     OriginalKart          = new KartInfo(kartWrapper.Kart); //Lose the original kart data
     OriginalKart.KartName = newName;
     CopyFromOriginal();
     NewImages = new List <BitmapWrapper>();
 }
Example #4
0
        public static void LoadReferenceKart()
        {
            if (LoadedReferenceKart != null)
            {
                ReferenceKart = LoadedReferenceKart;
            }
            else if (File.Exists(REF_KART_FILE))
            {
                List <KartInfo> karts = null;
                try
                {
                    karts = KartInfo.LoadFromFile(REF_KART_FILE);
                }
                catch
                {
                }

                if (karts == null || karts.Count == 0)
                {
                    LoadedReferenceKart = null;
                }
                else
                {
                    LoadedReferenceKart = new KartWrapper(karts[0]);
                }

                ReferenceKart = LoadedReferenceKart;
                ChompShopAlerts.UpdateReferenceKart(ReferenceKart);
            }
        }
 private MarioKart64ElementHub()
 {
     Karts                 = new List <KartInfo>();
     SelectedKarts         = new KartInfo[8];
     TurnKartPaletteBlocks = new List <KartPaletteBlock>();
     SpinKartPaletteBlocks = new List <KartPaletteBlock>();
     //Tracks = new List<TrackData>();
     //SelectedTracks = new TrackData[MarioKartRomInfo.TrackCount];
     TextureHub       = new TextureHub();
     NewElementOffset = BASE_FILE_END_OFFSET;
 }
Example #6
0
        private void btnKartDown_Click(object sender, EventArgs e)
        {
            //Move the selected kart down
            if (lbKarts.SelectedIndex != lbKarts.Items.Count - 1)
            {
                KartInfo tempKart = (KartInfo)lbKarts.SelectedItem;
                lbKarts.Items[lbKarts.SelectedIndex]     = lbKarts.Items[lbKarts.SelectedIndex + 1];
                lbKarts.Items[lbKarts.SelectedIndex + 1] = tempKart;

                SettingsChanged = true;
                lbKarts.SelectedIndex++;
            }
        }
Example #7
0
        private void btnKartUp_Click(object sender, EventArgs e)
        {
            //Move the selected kart up
            if (lbKarts.SelectedIndex != 0)
            {
                KartInfo tempKart = (KartInfo)lbKarts.SelectedItem;
                lbKarts.Items[lbKarts.SelectedIndex]     = lbKarts.Items[lbKarts.SelectedIndex - 1];
                lbKarts.Items[lbKarts.SelectedIndex - 1] = tempKart;

                SettingsChanged = true;
                lbKarts.SelectedIndex--;
            }
        }
Example #8
0
        private static void LoadKartsPayload(object sender, DoWorkEventArgs args)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            string[]        kartPaths = (string[])args.Argument;
            List <KartInfo> karts     = new List <KartInfo>();

            foreach (string kartPath in kartPaths)
            {
                karts.AddRange(KartInfo.LoadFromFile(kartPath));
            }

            args.Result = karts;
        }
        public MarioKart64ElementHub(XElement xml)
        {
            Karts                 = new List <KartInfo>();
            SelectedKarts         = new KartInfo[8];
            TurnKartPaletteBlocks = new List <KartPaletteBlock>();
            SpinKartPaletteBlocks = new List <KartPaletteBlock>();
            //Tracks = new List<TrackData>();
            //SelectedTracks = new TrackData[MarioKartRomInfo.TrackCount];
            TextureHub = new TextureHub();

            _instance = this;

            _loadedXml = xml; //Actually load the xml data at a later date (WRONG)
            LoadFromXML();
        }
Example #10
0
        private void UpdateKartList()
        {
            KartInfo SelectedKart = SelectedKartInfo;

            lbAllKarts.Items.Clear();

            foreach (KartInfo kart in MarioKart64ElementHub.Instance.Karts)
            {
                lbAllKarts.Items.Add(kart);
            }

            if (SelectedKart != null && lbAllKarts.Items.Contains(SelectedKart))
            {
                lbAllKarts.SelectedItem = SelectedKart;
            }
            else if (lbAllKarts.Items.Count > 0)
            {
                lbAllKarts.SelectedIndex = 0;
            }
        }
Example #11
0
        public static void SaveKartToDisk(string kartPath, List <KartWrapper> karts, DialogResult forceSetting = DialogResult.Abort)
        {
            if (File.Exists(kartPath))
            {
                if (forceSetting == DialogResult.Abort)
                {
                    forceSetting = MessageBox.Show("Karts file already exists. Overwrite file? (Yes overwrites, No appends)",
                                                   "Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);
                }

                if (forceSetting == DialogResult.Yes)
                {
                    File.Delete(kartPath);
                }
                else if (forceSetting == DialogResult.Cancel)
                {
                    return;
                }
            }
            KartInfo.SaveKarts(kartPath, karts.ConvertAll <KartInfo>(k => k.Kart));
        }
Example #12
0
        private void btnExportKart_Click(object sender, EventArgs e)
        {
            //Export the kart to an external file here!

            if (saveKartDialog.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(saveKartDialog.FileName))
                {
                    DialogResult result = MessageBox.Show("Karts file already exists. Overwrite file? (Yes overwrites, No appends)",
                                                          "Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);

                    if (result == DialogResult.Yes)
                    {
                        File.Delete(saveKartDialog.FileName);
                    }
                    else if (result == DialogResult.Cancel)
                    {
                        return;
                    }
                }
                KartInfo.SaveKarts(saveKartDialog.FileName, AllSelectedKartInfos);
            }
        }
Example #13
0
 private void CopyToOriginal()
 {
     OriginalKart = new KartInfo(Kart);
 }
Example #14
0
 private void CopyFromOriginal()
 {
     Kart = new KartInfo(OriginalKart);
 }
Example #15
0
 public KartWrapper(KartInfo origKart)
 {
     OriginalKart = origKart;
     CopyFromOriginal();
     NewImages = new List <BitmapWrapper>();
 }
Example #16
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);
            }
        }
        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);
                }
            }
        }
        public void LoadFromXML()
        {
            //TextBank/TextReferences - Only use the offset currently being used
            //KartReference - Only use the names of the karts selected
            //MIOBlocks/TKMK00Bocks - Offsets for each one
            //Karts - Full listing of information

            //Elements should already have been cleared
            //ClearElements();

            NewElementOffset = int.Parse(_loadedXml.Attribute(NEW_ELEMENT_OFFSET).Value);

            //Before we start, load up all saved karts and tracks
            ProgressService.SetMessage("Loading Kart Resources");
            foreach (RomItem item in RomProject.Instance.Items)
            {
                //If the same name kart hasn't been loaded yet
                if (item is KartInfo && Karts.FirstOrDefault(k => k.KartName == ((KartInfo)item).KartName) == null)
                {
                    this.Karts.Add((KartInfo)item);
                }
                //else if is trackinfo
            }

            //Also the text bank is all elements, so we don't need an xml in here for it
            ProgressService.SetMessage("Loading Text Blocks");
            N64DataElement textRefEl, textBlockEl;

            if (RomProject.Instance.Files[0].HasElementExactlyAt(TextReferenceBlock.TEXT_REFERENCE_SECTION_1, out textRefEl) &&
                RomProject.Instance.Files[0].HasElementExactlyAt(TextBankBlock.TEXT_BLOCK_START, out textBlockEl))
            {
                TextReferenceBlock refBlock  = (TextReferenceBlock)textRefEl;
                TextBankBlock      bankBlock = (TextBankBlock)textBlockEl;

                TextBank = new TextBank(bankBlock, refBlock, true);
            }

            int            offset;
            int            count     = 0;
            int            fullCount = _loadedXml.Elements().Count();
            N64DataElement n64Element;

            foreach (XElement element in _loadedXml.Elements())
            {
                ProgressService.SetMessage(string.Format("Storing Special Elements {0:0.0}%", (double)count / fullCount));
                switch (element.Name.ToString())
                {
                case TURN_PALETTE_BLOCK:
                    foreach (XElement el in element.Elements())
                    {
                        offset = int.Parse(el.Value);
                        if (RomProject.Instance.Files[0].HasElementExactlyAt(offset, out n64Element))
                        {
                            int            paletteOffset = offset;
                            List <Palette> palettes      = new List <Palette>();
                            palettes.Add((Palette)n64Element);
                            paletteOffset += 0x40 * 2;

                            for (int i = 1; i < 84; i++)     //Make not hardcoded later
                            {
                                if (!RomProject.Instance.Files[0].HasElementAt(paletteOffset, out n64Element))
                                {
                                    throw new Exception();
                                }

                                palettes.Add((Palette)n64Element);
                                paletteOffset += 0x40 * 2;
                            }

                            KartPaletteBlock block = new KartPaletteBlock(offset, palettes);
                            TurnKartPaletteBlocks.Add(block);
                        }
                    }
                    break;

                case SPIN_PALETTE_BLOCK:
                    foreach (XElement el in element.Elements())
                    {
                        offset = int.Parse(el.Value);
                        if (RomProject.Instance.Files[0].HasElementExactlyAt(offset, out n64Element))
                        {
                            int            paletteOffset = offset;
                            List <Palette> palettes      = new List <Palette>();
                            palettes.Add((Palette)n64Element);
                            paletteOffset += 0x40 * 2;

                            for (int i = 1; i < 80; i++)     //Make not hardcoded later
                            {
                                if (!RomProject.Instance.Files[0].HasElementAt(paletteOffset, out n64Element))
                                {
                                    throw new Exception();
                                }

                                palettes.Add((Palette)n64Element);
                                paletteOffset += 0x40 * 2;
                            }

                            KartPaletteBlock block = new KartPaletteBlock(offset, palettes);
                            SpinKartPaletteBlocks.Add(block);
                        }
                    }
                    break;

                case KARTS_GRAPHICS_REFERENCE_BLOCK:
                    offset = int.Parse(element.Value);
                    if (RomProject.Instance.Files[0].HasElementExactlyAt(offset, out n64Element))
                    {
                        if (n64Element is KartGraphicsReferenceBlock)
                        {
                            KartGraphicsBlock = (KartGraphicsReferenceBlock)n64Element;
                            //KartReader.LoadKartGraphicDmaReferences(KartGraphicsBlock);
                        }
                    }
                    break;

                case KARTS_PORTRAITS_REFERENCE_TABLE:
                    offset = int.Parse(element.Value);
                    if (RomProject.Instance.Files[0].HasElementExactlyAt(offset, out n64Element))
                    {
                        if (n64Element is KartPortraitTable)
                        {
                            KartPortraitsTable = (KartPortraitTable)n64Element;
                            //KartReader.LoadKartPortraitDmaReferences(KartPortraitsTable);
                        }
                    }
                    break;

                case SELECTED_KARTS:
                    int kartIndex = 0;
                    foreach (XElement selKart in element.Elements())
                    {
                        KartInfo selectedKart = Karts.SingleOrDefault(k => k.KartName == selKart.Name);
                        if (selectedKart != null)
                        {
                            SelectedKarts[kartIndex] = selectedKart;
                        }
                        kartIndex++;
                    }
                    break;

                case TextureHub.TEXTURE_HUB:
                    TextureHub.LoadReferencesFromXML(element);
                    break;
                }
                count++;
            }
        }