public static Frame ParseFrame(RomData romData, BitmapTexture[,] bitmapFrame)
        {
            var frame = new Frame();

            // parse palettes and textures
            GBPalette[,] palettes = new GBPalette[Frame.Height, Frame.Width];
            GBTexture[,] textures = new GBTexture[Frame.Height, Frame.Width];

            var pushedPalettes = new List <int>();
            var pushedTextures = new List <int>();

            foreach (var vec in ArrayUtility.ForEach(Frame.Height, Frame.Width))
            {
                var palette = GetPalette(bitmapFrame[vec.y, vec.x]);
                var texture = GetTexture(bitmapFrame[vec.y, vec.x], palette);

                palettes[vec.y, vec.x] = GetPalette(bitmapFrame[vec.y, vec.x]);
                textures[vec.y, vec.x] = GetTexture(bitmapFrame[vec.y, vec.x], palettes[vec.y, vec.x]);

                // Add Palette / Texture to rom
                var paletteIndex = romData.UpsertPalette(palette, pushedPalettes);
                var textureIndex = romData.UpsertTexture(texture, pushedTextures);

                // Add tile to frame
                var tile = new GBTile();
                tile.Palette = romData.PaletteData[paletteIndex];
                tile.Texture = romData.TextureData[textureIndex];
                frame.TileUpdates[vec.y, vec.x] = tile;
            }

            foreach (var vec in ArrayUtility.ForEach(Frame.Height, Frame.Width))
            {
                var index = romData.TextureData.IndexOf(frame.TileUpdates[vec.y, vec.x].Texture);
                if (index == -1)
                {
                    throw new Exception("Texture missing at " + vec.x + ", " + vec.y);
                }
            }

            pushedPalettes.Sort();
            pushedTextures.Sort();

            // palettes changes
            frame.PaletteUpdates = pushedPalettes.ToDictionary(i => i, i => romData.PaletteData[i]);

            // texture changes
            frame.LoadOrders = GetLoads(pushedTextures).ToList();

            return(frame);
        }
        public static List <BitmapTexture[, ]> FromBitmap(System.Drawing.Bitmap bitmap, bool includeScroll = false)
        {
            int offsetScroll = includeScroll ? 0 : 1;

            var frames = new List <BitmapTexture[, ]>();

            for (int xFramePixel = 0; xFramePixel < bitmap.Width; xFramePixel += FramePixelWidth)
            {
                var bitmapTextures = new BitmapTexture[Frame.Height, Frame.Width];

                foreach (var vec3 in ArrayUtility.ForEach(Frame.Height - offsetScroll, Frame.Width - offsetScroll))
                {
                    var xPixelOffset = xFramePixel + (vec3.x * BitmapTexture.WidthPx);
                    var yPixelOffset = (vec3.y * BitmapTexture.WidthPx);

                    bitmapTextures[vec3.y, vec3.x] = BitmapTexture.FromBitmap(bitmap, xPixelOffset, yPixelOffset);
                }

                frames.Add(bitmapTextures);
            }

            return(frames);
        }