예제 #1
0
        /// <summary>
        /// Creates a new <see cref="Sprite"/> from an indexed bitmap.
        /// </summary>
        /// <param name="bmp"></param>
        public Sprite(Bitmap bmp)
        {
            // TODO: maybe help the user out and index their image for them
            if (bmp.PixelFormat != PixelFormat.Format4bppIndexed && bmp.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                throw new Exception($"Source image is not indexed! {bmp.PixelFormat}");
            }

            // ensure bitmap size
            if (bmp.Width % 8 != 0 || bmp.Height % 8 != 0)
            {
                throw new Exception("Source image dimensions are not divisible by 8!");
            }

            // lock the bits of the bitmap
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat);

            // create tiles
            int width  = bmp.Width / 8;
            int height = bmp.Height / 8;

            tiles = new Tile[width * height];
            for (int i = 0; i < tiles.Length; i++)
            {
                tiles[i] = new Tile();
            }

            // copy pixel data
            if (bmp.PixelFormat == PixelFormat.Format4bppIndexed)
            {
                //palette = new Palette(16);
                bitDepth = BitDepth.Four;

                // copy the source data to a byte buffer
                byte[] buffer = new byte[bmp.Width * bmp.Height / 2];
                Marshal.Copy(bmpData.Scan0, buffer, 0, buffer.Length);

                // copy pixel data
                int x = 0;  // current x-position in tile
                int y = 0;  // current y-position in tile
                int a = 0;  // current x-position of tile
                int b = 0;  // current y-position of tile

                for (int i = 0; i < bmp.Width * bmp.Height / 2; i++)
                {
                    // 4BPP: two pixels per byte
                    tiles[a + b * width].SetPixel(x++, y, buffer[i] >> 4);  // left
                    tiles[a + b * width].SetPixel(x++, y, buffer[i] & 0xF); // right

                    // move forward positions
                    if (x >= 8)
                    {
                        x = 0;
                        a++;
                    }

                    if (a >= width)
                    {
                        a = 0;
                        y++;
                    }

                    if (y >= 8)
                    {
                        y = 0;
                        b++;
                    }
                }
            }
            else if (bmp.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                // above, modified for 8BPP (one pixel per byte)
                //palette = new Palette(256);
                bitDepth = BitDepth.Eight;

                byte[] buffer = new byte[bmp.Width * bmp.Height];
                Marshal.Copy(bmpData.Scan0, buffer, 0, buffer.Length);

                int x = 0;
                int y = 0;
                int a = 0;
                int b = 0;

                for (int i = 0; i < bmp.Width * bmp.Height; i++)
                {
                    tiles[a + b * width].SetPixel(x++, y, buffer[i]);

                    if (x >= 8)
                    {
                        x = 0;
                        a++;
                    }

                    if (a >= width)
                    {
                        a = 0;
                        y++;
                    }

                    if (y >= 8)
                    {
                        y = 0;
                        b++;
                    }
                }
            }

            // unlock the bitmap
            bmp.UnlockBits(bmpData);
        }
예제 #2
0
 /// <summary>
 /// Creates a new <see cref="Sprite"/> of the given size (in tiles) and bit depth.
 /// </summary>
 /// <param name="width">The width in tiles.</param>
 /// <param name="height">The height in tiles.</param>
 /// <param name="bitDepth">The bit depth.</param>
 public Sprite(int width, int height, BitDepth bitDepth)
 {
     this.tiles    = new Tile[width * height];
     this.bitDepth = bitDepth;
 }
예제 #3
0
 /// <summary>
 /// Creates a new <see cref="Sprite"/> for the given tiles and bit depth.
 /// </summary>
 /// <param name="tiles">The source tile data.</param>
 /// <param name="bitDepth">The bit depth.</param>
 public Sprite(Tile[] tiles, BitDepth bitDepth)
 {
     this.tiles    = tiles;
     this.bitDepth = bitDepth;
 }
예제 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Palette"/> class
 /// for the specified bit depth.
 /// </summary>
 /// <param name="color">The color to repeat.</param>
 /// <param name="bitDepth">The bit depth.</param>
 public Palette(GbaColor color, BitDepth bitDepth)
     : this(color, (int)bitDepth)
 {
 }