/// <summary> /// /// </summary> /// <param name="picture"></param> /// <param name="format"></param> /// <param name="allocator"></param> /// <param name="rom"></param> /// <returns> /// first is main portrait offset, /// second is miniportrait, /// third is palette and /// fourth is mouth frames if separate /// </returns> private static CanCauseError<ManagedPointer[]> WriteData(PortraitFormat format, Bitmap picture, IAllocator<ManagedPointer> allocator, IROM rom) { List<ManagedPointer> pointers = new List<ManagedPointer>(4); //Get palette Color[] palette; bool palettedBitmap = picture.PixelFormat.HasFlag(PixelFormat.Indexed); if (!palettedBitmap) { var colors = picture.GetColors(); colors = GBAPalette.GetGBAColors(colors); if (colors.Count > 16) { return CanCauseError<ManagedPointer[]>.Error("Over 16 colours."); } palette = colors.ToArray(); } else { palette = picture.Palette.Entries; } //Split to separate portraits Bitmap mainPortrait = new Bitmap( format.PortraitSize.Width, format.PortraitSize.Height, picture.PixelFormat); Move(picture, mainPortrait, format.PictureMapping); Bitmap mouthbm; if (format.SeparateMouthFrames) { mouthbm = new Bitmap(format.MouthSize.Width, format.MouthSize.Height, picture.PixelFormat); } else { mouthbm = mainPortrait; } Move(picture, mouthbm, format.MouthMapping); Bitmap mini = new Bitmap(format.MiniSize.Width, format.MiniSize.Height, picture.PixelFormat); Move(picture, mouthbm, format.MiniMapping); //Write data pointers.Add(Insert(mainPortrait, palette, format.BlockAdd, format.CompressedPortrait, rom, allocator)); pointers.Add(Insert(mini, palette, 0, format.CompressedMini, rom, allocator)); byte[] rawPalette = GBAPalette.toRawGBAPalette(palette); var ptr = allocator.Allocate(rawPalette.Length, 4); if (!ptr.IsNull) { rom.WriteData(ptr, rawPalette, 0, rawPalette.Length); } pointers.Add(ptr); if (mouthbm != mainPortrait) { pointers.Add(Insert(mouthbm, palette, 0, true, rom, allocator)); } return pointers.ToArray(); }
private static ManagedPointer Insert(Bitmap toInsert, Color[] palette, int blockAdded, bool compressed, IROM rom, IAllocator<ManagedPointer> allocator) { var bytes = GBAGraphics.ToGBARaw(toInsert, palette, GraphicsMode.Tile4bit); int insertedLength; int bytesAdded = blockAdded * 32; if (compressed) { bytes = LZ77.Compress(bytes, 0, bytes.Length - bytesAdded); insertedLength = bytes.Length; } else { insertedLength = bytes.Length - bytesAdded; } var ptr = allocator.Allocate(insertedLength, 4); if (!ptr.IsNull) { rom.WriteData(ptr, bytes, 0, insertedLength); } return ptr; }