bool SeparateMouthFrames; //Always decomp when separate #endregion Fields #region Constructors /// <summary> /// Initializes built-in formats /// </summary> static PortraitFormat() { //All positions and sizes in 8x8 tile coordinates Rectangle miniPortrait = new Rectangle(12, 2, 4, 4); Size genericCardSize = new Size(10, 9); FE6Format = new PortraitFormat(); FE6Format.PortraitSize = new Size(32, 5); FE6Format.BlockAdd = 24; FE6Format.MouthMapping = new Dictionary<Rectangle, Point>() { { new Rectangle(2, 0, 8, 4), new Point(0, 0) }, { new Rectangle(2, 4, 8, 4), new Point(8, 0) }, { new Rectangle(2, 8, 4, 2), new Point(16, 0) }, { new Rectangle(6, 8, 4, 2), new Point(16, 2) }, { new Rectangle(0, 6, 2, 4), new Point(20, 0) }, { new Rectangle(10, 6, 2, 4), new Point(22, 0) }, { new Rectangle(0, 10, 8, 4), new Point(24, 0) }, //Mouth frames { new Rectangle(8, 10, 4, 1), new Point(0, 4) }, { new Rectangle(8, 11, 4, 1), new Point(4, 4) }, }; FE6Format.CompressedPortrait = true; FE6Format.SeparateMouthFrames = false; FE6Format.MouthMapping = null; FE6Format.MiniMapping = new Dictionary<Rectangle, Point>() { { miniPortrait, new Point(0, 0) }, }; FE6Format.MiniSize = miniPortrait.Size; FE6Format.CompressedMini = false; FE6Format.GenericSize = genericCardSize; FE7Format = new PortraitFormat(); FE7Format.PictureMapping= new Dictionary<Rectangle, Point>() { { new Rectangle(2, 0, 8, 4), new Point(0, 0) }, { new Rectangle(2, 4, 8, 4), new Point(8, 0) }, { new Rectangle(2, 8, 4, 2), new Point(16, 0) }, { new Rectangle(6, 8, 4, 2), new Point(16, 2) }, { new Rectangle(0, 6, 2, 4), new Point(20, 0) }, { new Rectangle(10, 6, 2, 4), new Point(22, 0) }, { new Rectangle(12, 6, 4, 4), new Point(24, 0) },//Blinking frames { new Rectangle(12, 10, 4, 2), new Point(28, 0) },//The extra thing }; FE7Format.PortraitSize = new Size(32, 4); FE7Format.CompressedPortrait= true; FE7Format.BlockAdd = 0; FE7Format.SeparateMouthFrames = true; FE7Format.MouthMapping = new Dictionary<Rectangle, Point>() { { new Rectangle(0, 10, 4, 2), new Point(0, 0) }, { new Rectangle(4, 10, 4, 2), new Point(0, 2) }, { new Rectangle(8, 10, 4, 2), new Point(0, 4) }, { new Rectangle(0, 12, 4, 2), new Point(0, 6) }, { new Rectangle(4, 12, 4, 2), new Point(0, 8) }, { new Rectangle(8, 12, 4, 2), new Point(0, 10) }, }; FE7Format.MouthSize = new Size(4, 12); FE7Format.MiniMapping = new Dictionary<Rectangle, Point>() { { miniPortrait, new Point(0, 0) }, }; FE7Format.MiniSize = miniPortrait.Size; FE7Format.CompressedMini = true; FE7Format.GenericSize = genericCardSize; FE8Format = new PortraitFormat(); FE8Format.PictureMapping= new Dictionary<Rectangle, Point>() { { new Rectangle(2, 0, 8, 4), new Point(0, 0) }, { new Rectangle(2, 4, 8, 4), new Point(8, 0) }, { new Rectangle(2, 8, 4, 2), new Point(16, 0) }, { new Rectangle(6, 8, 4, 2), new Point(16, 2) }, { new Rectangle(0, 6, 2, 4), new Point(20, 0) }, { new Rectangle(10, 6, 2, 4), new Point(22, 0) }, { new Rectangle(12, 6, 4, 4), new Point(24, 0) },//Blinking frames { new Rectangle(12, 10, 4, 2), new Point(28, 0) },//The extra thing }; FE8Format.PortraitSize = new Size(32, 4); FE8Format.CompressedPortrait = false; FE8Format.BlockAdd = 0; FE8Format.SeparateMouthFrames = true; FE8Format.MouthMapping= new Dictionary<Rectangle, Point>() { { new Rectangle(0, 10, 4, 2), new Point(0, 0) }, { new Rectangle(4, 10, 4, 2), new Point(0, 2) }, { new Rectangle(8, 10, 4, 2), new Point(0, 4) }, { new Rectangle(0, 12, 4, 2), new Point(0, 6) }, { new Rectangle(4, 12, 4, 2), new Point(0, 8) }, { new Rectangle(8, 12, 4, 2), new Point(0, 10) }, };; FE8Format.MouthSize = new Size(4, 12); FE8Format.MiniMapping = new Dictionary<Rectangle, Point>() { { miniPortrait, new Point(0, 0) }, }; FE8Format.MiniSize = miniPortrait.Size; FE8Format.CompressedMini = true; FE8Format.GenericSize = genericCardSize; }
/// <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(); }