private void DisplaySelectedImage() { if (lbImages.SelectedItem != null) { MK64Image selectedImage = (MK64Image)lbImages.SelectedItem; ActiveControlTypes newType; if (selectedImage.TKMKReference != null) { newType = ActiveControlTypes.TKMK; } else if (selectedImage.Format == Cereal64.Microcodes.F3DEX.DataElements.Texture.ImageFormat.CI) { newType = ActiveControlTypes.CI; } else { newType = ActiveControlTypes.Others; } if (newType != _activeControlType || ActiveControl == null) { SetActiveType(newType); } SetPreviewImage(selectedImage); } else { if (ActiveControl != null) { ActiveControl.Image = null; } } }
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; } } }
private void btnAdd_Click(object sender, EventArgs e) { if (openPortraitDialog.ShowDialog() == DialogResult.OK) { foreach (string file in openPortraitDialog.FileNames) { if (lbPortraits.Items.Count >= 17) { break; } Image img = Bitmap.FromFile(file); if (img.Width != 64 || img.Height != 64) { MessageBox.Show("Image must be 64x64!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (img != null) { //Create the new KartImage here byte[] imgData = TextureConversion.RGBA16ToBinary(new Bitmap(img)); Texture texture = new Texture(-1, imgData, Texture.ImageFormat.RGBA, Texture.PixelInfo.Size_16b, 64, 64); F3DEXImage image = new F3DEXImage(texture); MK64Image mkImage = new MK64Image(image, Path.GetFileNameWithoutExtension(file), true); Kart.AddPortrait(mkImage); lbPortraits.Items.Add(mkImage); } } UpdatePortraitCount(); UpdateButtonsEnabled(); } }
public bool RemoveKartImage(MK64Image image) { //Check that it exists if (!_kartImages.Contains(image)) { return(false); } //We're gonna lock those original images in, sorry if (image.IsOriginalImage) { return(false); } _kartImages.Remove(image); if (_sharedTextureImages.ContainsKey(image.ImageReference.Texture) && _sharedTextureImages[image.ImageReference.Texture].Contains(image)) { _sharedTextureImages[image.ImageReference.Texture].Remove(image); } foreach (Palette p in image.ImageReference.BasePalettes) { if (_sharedPaletteImages.ContainsKey(p) && _sharedPaletteImages[p].Contains(image)) { _sharedPaletteImages[p].Remove(image); } } return(true); }
public void LoadReferencesFromXML(XElement xml) { //Note: This does not create the N64DataElements, it merely finds them and associates them ClearTextureData(); foreach (XElement element in xml.Elements()) { if (element.Name.ToString() == IMAGES) { foreach (XElement imageEl in element.Elements()) { MK64Image image = new MK64Image(imageEl); AddImage(image); } } if (element.Name.ToString() == KART_IMAGES) { foreach (XElement imageEl in element.Elements()) { MK64Image image = new MK64Image(imageEl); AddKartImage(image); } } } }
private void btnReplaceWith_Click(object sender, EventArgs e) { //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; } if (!_image.TKMKReference.SetImage(bmp)) { MessageBox.Show("Error: Couldn't set image file! File might be too large to load in", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Image = _image; //Reset it ImageUpdated(); } }
public override void InitData() { _initializing = true; ResetTitleText(); MK64Image selectedImage = (MK64Image)lbPortraits.SelectedItem; ClearForm(); PopulatePortraitListBox(); if (Kart.Kart.KartPortraits.Count > 0) { if (selectedImage != null && lbPortraits.Items.Contains(selectedImage)) { lbPortraits.SelectedItem = selectedImage; } else { lbPortraits.SelectedIndex = 0; } } UpdatePortrait(); UpdatePortraitCount(); UpdateButtonsEnabled(); _initializing = false; }
private KartImage ConvertToKartImage(Bitmap bmp, string imageName) { if (bmp != null && Kart != null && Kart.Kart != null && Kart.Kart.KartImages.ImagePalette != null) { //Create the new KartImage here //byte[] imgData = TextureConversion.CI8ToBinary(bmp, Kart.Kart.KartImages.ImagePalette); //Texture texture = new Texture(-1, imgData, Texture.ImageFormat.CI, Texture.PixelInfo.Size_8b, 64, 64, Kart.Kart.KartImages.ImagePalette); // ImageMIO0Block block = new ImageMIO0Block(-1, imgData); // block.ImageName = imageName; // block.DecodedN64DataElement = texture; //byte[] blankPaletteData = new byte[0x40]; //Palette blankPalette = new Palette(-1, blankPaletteData); //KartImage newImage = new KartImage(block, blankPalette); //return newImage; int tempPalOffset = 0; byte[] imgData = TextureConversion.CI8ToBinary(bmp, Kart.Kart.KartImages.ImagePalette, ref tempPalOffset); Texture texture = new Texture(-1, imgData, Texture.ImageFormat.CI, Texture.PixelInfo.Size_8b, 64, 64); List <Palette> palettes = new List <Palette>(); palettes.Add(Kart.Kart.KartImages.ImagePalette); byte[] blankPaletteData = new byte[0x40]; palettes.Add(new Palette(-1, blankPaletteData)); F3DEXImage image = new F3DEXImage(texture, palettes); MK64Image mkImg = new MK64Image(image, imageName, true); KartImage newImage = new KartImage(new List <MK64Image>() { mkImg }); return(newImage); } return(null); }
public void SwapPortraits(int index1, int index2) { MK64Image temp = Kart.KartPortraits[index1]; Kart.KartPortraits[index1] = Kart.KartPortraits[index2]; Kart.KartPortraits[index2] = temp; IsModified = true; }
public KartInfo(XElement xml) { KartName = xml.Attribute(NAME).Value; OriginalKart = bool.Parse(xml.Attribute(ORIGINAL).Value); XElement imagePoolElement = xml.Element(KartImagePool.KART_IMAGE_POOL); if (imagePoolElement != null) { KartImages = new KartImagePool(imagePoolElement); } else { KartImages = new KartImagePool(); } KartAnimations = new List <KartAnimationSeries>(); KartPortraits = new List <MK64Image>(); XElement animations = xml.Element(ANIMATIONS); foreach (XElement animation in animations.Elements()) { string name = animation.Attribute(NAME).Value; KartAnimationSeries newAnim = new KartAnimationSeries(name); newAnim.KartAnimationType = int.Parse(animation.Attribute(ANIMATION_TYPE).Value); foreach (XElement image in animation.Elements()) { newAnim.OrderedImageNames.Add(image.Attribute(IMAGE_NAME).Value); } KartAnimations.Add(newAnim); } XElement portraits = xml.Element(PORTRAITS); foreach (XElement portrait in portraits.Elements()) { KartPortraits.Add(new MK64Image(portrait)); } XElement namePlate = xml.Element(NAME_PLATE); //byte[] namePlateData = Convert.FromBase64String(namePlate.Value); //ushort namePlateAlpha = ushort.Parse(namePlate.Attribute(NAME_PLATE_ALPHA).Value); KartNamePlate = new MK64Image(namePlate.Elements().First()); //if (RomProject.Instance.Files[0].HasElementExactlyAt(namePlateOffset)) //{ // N64DataElement element = RomProject.Instance.Files[0].GetElementAt(namePlateOffset); // if (element is TKMK00Block) // { // KartNamePlate = (TKMK00Block)element; // } //} }
public void AddKartImage(MK64Image image) { NewKartImages.Add(image); if (image.TextureEncoding != MK64Image.MK64ImageEncoding.TKMK00) { if (!ImagesByTexture.ContainsKey(image.ImageReference.Texture)) { ImagesByTexture.Add(image.ImageReference.Texture, new List <MK64Image>()); } ImagesByTexture[image.ImageReference.Texture].Add(image); } }
private void SetPreviewImage(MK64Image selectedImage) { if (selectedImage == null || selectedImage.Image == null) { imagePreviewControl.Image = null; } else { imagePreviewControl.Image = selectedImage.Image; imagePreviewControl.ImageName = selectedImage.ImageName; } ActiveControl.Image = selectedImage; }
public bool AddKartImage(MK64Image image) { if (!image.IsValidImage) { return(false); } if (_kartImages.Contains(image)) { return(false); } //To do: add extra checks here to make sure that the same texture/palette doesn't get added twice? _kartImages.Add(image); if (image.ImageReference != null) { if (!_sharedTextureImages.ContainsKey(image.ImageReference.Texture)) { _sharedTextureImages.Add(image.ImageReference.Texture, new List <MK64Image>()); } _sharedTextureImages[image.ImageReference.Texture].Add(image); if (image.Format == Texture.ImageFormat.CI) { foreach (Palette p in image.ImageReference.BasePalettes) { if (!_sharedPaletteImages.ContainsKey(p)) { _sharedPaletteImages.Add(p, new List <MK64Image>()); } _sharedPaletteImages[p].Add(image); } } } return(true); }
public static void ReadRom(BackgroundWorker worker, byte[] rawData, MarioKart64ReaderResults finalResults) { TextureReaderResults results = new TextureReaderResults(); //Here, load in the texture stuff ProgressService.SetMessage("Loading Textures and Palettes"); foreach (MarioKartRomInfo.MK64ImageInfo imageInfo in MarioKartRomInfo.ImageLocations) { MK64Image image = new MK64Image(imageInfo, rawData); if (image.IsValidImage) { results.AddImage(image); } else { throw new Exception(); } } ProgressService.SetMessage("Loading Kart Images"); foreach (MarioKartRomInfo.MK64ImageInfo imageInfo in KartImageInfo.ImageLocations) { MK64Image image = new MK64Image(imageInfo, rawData); if (image.IsValidImage) { results.AddKartImage(image); } else { throw new Exception(); } } finalResults.TextureResults = results; }
private void btnRemoveImage_Click(object sender, EventArgs e) { //Don't allow deleting original images!! if (SelectedImage == null) { MessageBox.Show("Error: No image selected!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (SelectedImage.IsOriginalImage) { MessageBox.Show("Error: Image is not custom, cannot delete!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } MK64Image image = SelectedImage; lbImages.SelectedIndex = lbImages.SelectedIndex - 1; MarioKart64ElementHub.Instance.TextureHub.RemoveImage(image); lbImages.Items.Remove(image); UpdateImageCount(); //Code here to remove the texture/palette if not used?? }
private void ReplaceTexture() { //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; } byte[] newData; byte[] newPaletteData = null; if (_image.Format == Texture.ImageFormat.CI) { Palette palette = new Palette(-1, new byte[_image.ImageReference.WorkingPalette.Colors.Length * 2]); newData = TextureConversion.ImageToBinary(_image.Format, _image.PixelSize, bmp, ref palette); newPaletteData = palette.RawData; } 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; 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; } Image = _image; //Reset it ImageUpdated(); } }
public KartPortraitTableEntry(int fileOffset, MK64Image image) : base(fileOffset, null) { ImageReference = image; }
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 InsertPortrait(int index, MK64Image image) { Kart.KartPortraits.Insert(index, image); IsModified = true; }
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(); } } }
public void RemovePortrait(MK64Image image) { Kart.KartPortraits.Remove(image); IsModified = true; }
public void AddPortrait(MK64Image image) { Kart.KartPortraits.Add(image); IsModified = true; }
public void SetNamePlate(MK64Image tkmkImage) { Kart.KartNamePlate = tkmkImage; IsModified = true; }
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); } } }
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; } } } }