public void setSegment(uint index, uint segmentStart, uint segmentEnd, bool isMIO0, bool fakeMIO0, uint uncompressedOffset) { if (segmentStart > segmentEnd) { return; } if (!isMIO0) { segStart[index] = segmentStart; segIsMIO0[index] = false; uint size = segmentEnd - segmentStart; segData[index] = new byte[size]; for (uint i = 0; i < size; i++) { segData[index][i] = bytes[segmentStart + i]; } } else { if (fakeMIO0) { segStart[index] = segmentStart + uncompressedOffset; segIsMIO0[index] = false; } else { segIsMIO0[index] = true; } segData[index] = MIO0.mio0_decode(getSubArray(bytes, segmentStart, segmentEnd - segmentStart)); } }
public static ImageMIO0BlockINVALID ReadImageMIO0BlockFrom(byte[] data, int offset) { int mio0Length = MIO0.FindLengthOfMIO0Block(data, offset); byte[] mio0Data = new byte[mio0Length]; Array.Copy(data, offset, mio0Data, 0, mio0Length); return(new ImageMIO0BlockINVALID(offset.ToString("X8"), offset, mio0Data)); }
static void Test(byte[] bytes, Method method) { byte[] bytes2 = new byte[bytes.Length]; switch (method) { case Method.LZ10: bytes2 = LZ10.Decompress(new MemoryStream(LZ10.Compress(new MemoryStream(bytes))), bytes.Length); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.LZ11: bytes2 = LZ11.Decompress(new MemoryStream(LZ11.Compress(new MemoryStream(bytes))), bytes.Length); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.LZ40: bytes2 = LZ40.Decompress(new MemoryStream(LZ40.Compress(new MemoryStream(bytes))), bytes.Length); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.LZ77: bytes2 = LZ77.Decompress(new MemoryStream(LZ77.Compress(new MemoryStream(bytes)))); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.RevLZ77: bytes2 = RevLZ77.Decompress(new MemoryStream(RevLZ77.Compress(new MemoryStream(bytes)))); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.LZ4: bytes2 = LZ4.Decompress(new MemoryStream(LZ4.Compress(new MemoryStream(bytes)))); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.LZECD: bytes2 = LZECD.Decompress(new MemoryStream(LZECD.Compress(new MemoryStream(bytes)))); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.LZOvl: bytes2 = LZOvl.Decompress(new MemoryStream(LZOvl.Compress(new MemoryStream(bytes)))); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; case Method.MIO0: bytes2 = MIO0.Decompress(new MemoryStream(MIO0.Compress(new MemoryStream(bytes), ByteOrder.LittleEndian)), ByteOrder.LittleEndian); Assert.IsTrue(bytes.SequenceEqual(bytes2)); break; } }
public void setSegment(uint index, uint segmentStart, uint segmentEnd, bool isMIO0, bool fakeMIO0, uint uncompressedOffset, byte?areaID) { if (segmentStart > segmentEnd) { return; } SegBank seg = new SegBank(); seg.SegID = (byte)index; if (!isMIO0) { seg.SegStart = segmentStart; seg.IsMIO0 = false; uint size = segmentEnd - segmentStart; seg.Data = new byte[size]; for (uint i = 0; i < size; i++) { seg.Data[i] = bytes[segmentStart + i]; } } else { if (fakeMIO0) { seg.SegStart = segmentStart + uncompressedOffset; seg.IsMIO0 = false; } else { seg.IsMIO0 = true; } seg.Data = MIO0.mio0_decode(getSubArray_safe(bytes, segmentStart, segmentEnd - segmentStart)); } setSegment(index, seg, areaID); }
public static void Compress(object sender, EventArgs e) { var tsi = sender as ToolStripMenuItem; if (!Shared.PrepareFiles("Open a decompressed " + tsi?.Tag + "file...", "Save your compressed file...", ".decomp", out var openFile, out var saveFile, true)) { return; } try { using (openFile) using (var outFs = new BinaryWriterX(saveFile)) switch (tsi?.Tag) { case Compression.L5LZ10: outFs.Write(Level5.Compress(openFile, Level5.Method.LZ10)); break; case Compression.L5Huff4: outFs.Write(Level5.Compress(openFile, Level5.Method.Huffman4Bit)); break; case Compression.L5Huff8: outFs.Write(Level5.Compress(openFile, Level5.Method.Huffman8Bit)); break; case Compression.L5RLE: outFs.Write(Level5.Compress(openFile, Level5.Method.RLE)); break; case Compression.NLZ10: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.LZ10)); break; case Compression.NLZ11: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.LZ11)); break; case Compression.NLZ60: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.LZ60)); break; case Compression.NHuff4: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.Huff4)); break; case Compression.NHuff8: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.Huff8)); break; case Compression.NRLE: outFs.Write(Nintendo.Compress(openFile, Nintendo.Method.RLE)); break; case Compression.LZ77: outFs.Write(LZ77.Compress(openFile)); break; case Compression.RevLZ77: outFs.Write(RevLZ77.Compress(openFile)); break; case Compression.LZOvl: outFs.Write(LZOvl.Compress(openFile)); break; case Compression.LZ4: outFs.Write(Kontract.Compression.LZ4.Compress(openFile)); break; case Compression.MIO0LE: outFs.Write(MIO0.Compress(openFile, ByteOrder.LittleEndian)); break; case Compression.MIO0BE: outFs.Write(MIO0.Compress(openFile, ByteOrder.BigEndian)); break; case Compression.Yay0LE: outFs.Write(Yay0.Compress(openFile, ByteOrder.LittleEndian)); break; case Compression.Yay0BE: outFs.Write(Yay0.Compress(openFile, ByteOrder.BigEndian)); break; case Compression.Yaz0LE: outFs.Write(Yaz0.Compress(openFile, ByteOrder.LittleEndian)); break; case Compression.Yaz0BE: outFs.Write(Yaz0.Compress(openFile, ByteOrder.BigEndian)); break; case Compression.GZip: outFs.Write(GZip.Compress(openFile)); break; case Compression.ZLib: outFs.Write(ZLib.Compress(openFile)); break; case Compression.PSVSpikeChun: outFs.Write(PSVSpikeChun.Compress(openFile)); break; } } catch (Exception ex) { MessageBox.Show(ex.ToString(), tsi?.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } MessageBox.Show($"Successfully compressed {Path.GetFileName(openFile.Name)}.", tsi.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); }
public static void Decompress(object sender, EventArgs e) { var tsi = sender as ToolStripMenuItem; if (!Shared.PrepareFiles("Open a " + tsi?.Tag + " compressed file...", "Save your decompressed file...", ".decomp", out var openFile, out var saveFile)) { return; } try { using (openFile) using (var outFs = new BinaryWriterX(saveFile)) switch (tsi?.Tag) { case Compression.Level5: outFs.Write(Level5.Decompress(openFile)); break; case Compression.Nintendo: outFs.Write(Nintendo.Decompress(openFile)); break; case Compression.LZ77: outFs.Write(LZ77.Decompress(openFile)); break; case Compression.RevLZ77: outFs.Write(RevLZ77.Decompress(openFile)); break; case Compression.LZOvl: outFs.Write(LZOvl.Decompress(openFile)); break; case Compression.LZ4: outFs.Write(Kontract.Compression.LZ4.Decompress(openFile)); break; case Compression.MIO0LE: outFs.Write(MIO0.Decompress(openFile, ByteOrder.LittleEndian)); break; case Compression.MIO0BE: outFs.Write(MIO0.Decompress(openFile, ByteOrder.BigEndian)); break; case Compression.Yay0LE: outFs.Write(Yay0.Decompress(openFile, ByteOrder.LittleEndian)); break; case Compression.Yay0BE: outFs.Write(Yay0.Decompress(openFile, ByteOrder.BigEndian)); break; case Compression.Yaz0LE: outFs.Write(Yaz0.Decompress(openFile, ByteOrder.LittleEndian)); break; case Compression.Yaz0BE: outFs.Write(Yaz0.Decompress(openFile, ByteOrder.BigEndian)); break; case Compression.LZECD: outFs.Write(LZECD.Decompress(openFile)); break; case Compression.LZ10VLE: outFs.Write(LZSSVLE.Decompress(openFile)); break; case Compression.GZip: outFs.Write(GZip.Decompress(openFile)); break; case Compression.ZLib: outFs.Write(ZLib.Decompress(openFile)); break; case Compression.PSVSpikeChun: outFs.Write(PSVSpikeChun.Decompress(openFile)); break; } } catch (Exception ex) { MessageBox.Show(ex.ToString(), tsi?.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } MessageBox.Show($"Successfully decompressed {Path.GetFileName(openFile.Name)}.", tsi.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); }
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(); } }
private int parseLevelScriptTemporarlyForSegments(byte[][] segments, uint[] segmentStarts, bool[] segmentsAreMIO0, byte seg, uint off) { ROM rom = ROM.Instance; byte[] data = segments[seg]; bool end = false; int endCmd = 0; byte l_seg; uint l_start, l_end, l_off; while (!end) { byte cmdLen = data[off + 1]; byte[] cmd = rom.getSubArray_safe(data, off, cmdLen); //rom.printArray(cmd, cmdLen); switch (cmd[0]) { case 0x00: case 0x01: { l_seg = cmd[3]; l_start = bytesToInt(cmd, 4, 4); l_end = bytesToInt(cmd, 8, 4); l_off = bytesToInt(cmd, 13, 3); segmentStarts[l_seg] = l_start; segments[l_seg] = rom.getROMSection(l_start, l_end); int end_r = parseLevelScriptTemporarlyForSegments(segments, segmentStarts, segmentsAreMIO0, l_seg, l_off); if (end_r == 0x02) { end = true; endCmd = 2; } } break; case 0x02: endCmd = 2; end = true; break; case 0x05: l_seg = cmd[4]; l_off = bytesToInt(cmd, 5, 3); if (l_seg == seg) { if ((long)l_off - (long)off == -4) { //Console.WriteLine("Infinite loop detected!"); return(0x02); } } endCmd = parseLevelScriptTemporarlyForSegments(segments, segmentStarts, segmentsAreMIO0, l_seg, l_off); end = true; break; case 0x06: l_seg = cmd[4]; l_off = bytesToInt(cmd, 5, 3); int end_ret = parseLevelScriptTemporarlyForSegments(segments, segmentStarts, segmentsAreMIO0, l_seg, l_off); if (end_ret == 0x02) { end = true; endCmd = 2; } break; case 0x07: end = true; endCmd = 0x07; break; case 0x17: l_seg = cmd[3]; l_start = bytesToInt(cmd, 4, 4); l_end = bytesToInt(cmd, 8, 4); if (l_start < l_end) { segmentStarts[l_seg] = l_start; segments[l_seg] = rom.getROMSection(l_start, l_end); } //rom.setSegment(seg, start, end, false); break; case 0x18: case 0x1A: l_seg = cmd[3]; l_start = bytesToInt(cmd, 4, 4); l_end = bytesToInt(cmd, 8, 4); if (l_start < l_end) { byte[] MIO0_header = rom.getSubArray_safe(rom.Bytes, l_start, 0x10); if (bytesToInt(MIO0_header, 0, 4) == 0x4D494F30) // Check MIO0 signature { int compressedOffset = (int)bytesToInt(MIO0_header, 0x8, 4); int uncompressedOffset = (int)bytesToInt(MIO0_header, 0xC, 4); bool isFakeMIO0 = rom.testIfMIO0IsFake(l_start, compressedOffset, uncompressedOffset); segmentsAreMIO0[l_seg] = !isFakeMIO0; if (isFakeMIO0) { segmentStarts[l_seg] = l_start + (uint)uncompressedOffset; } segments[l_seg] = MIO0.mio0_decode(rom.getROMSection(l_start, l_end)); } } break; case 0x1D: end = true; endCmd = 0x02; break; } off += cmdLen; } return(endCmd); }
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; } } } }
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(); } } }