using System; using System.Drawing; namespace SpriteWave { public enum Translation { Left, Right, Horizontal, Vertical } public abstract class Tile : IPiece { // Implements IPiece.EdgeKind public virtual EdgeKind EdgeKind { get { return EdgeKind.None; } } protected byte[] _data = {}; public byte[] Data { get { return _data; } } public abstract int Width { get; } public abstract int Height { get; } public abstract int BytesPP { get; } // If the return value is less than or equal to the offset value, it means there was an error public abstract int Import(byte[] input, int offset); public abstract void ExtractRow(byte[] line, int offset, int y, byte[] palBGRA); public Tile Clone() { // Uses funky business since 'Tile' is an abstract class (need the derived type, eg. NESTile) Tile t = Activator.CreateInstance(this.GetType()) as Tile; Buffer.BlockCopy(_data, 0, t.Data, 0, Width * Height * BytesPP); return t; } public void ApplyTo(byte[] canvas, int offset, int width, byte[] palBGRA) { for (int i = 0; i < Height; i++) { ExtractRow(canvas, offset, i, palBGRA); offset += width * Utils.cLen; } } public Bitmap ToBitmap(byte[] activeColors) { byte[] pixels = new byte[Width * Height * Utils.cLen]; ApplyTo(pixels, 0, Width, activeColors); return Utils.BitmapFrom(pixels, Width, Height); } public void Translate(Translation t) { var image = new byte[Width * Height * BytesPP]; int idx = 0; for (int i = 0; i < Height; i++) { for (int j = 0; j < Width; j++) { int y, x; switch (t) { case Translation.Left: y = Width-j-1; x = i; break; case Translation.Right: y = j; x = Height-i-1; break; case Translation.Horizontal: y = i; x = Width-j-1; break; case Translation.Vertical: y = Height-i-1; x = j; break; default: throw new ArgumentException(); } int off = (y * Width + x) * BytesPP; for (int k = 0; k < BytesPP; k++) { image[off + k] = _data[idx + k]; } idx += BytesPP; } } _data = image; } public bool IsBlank() { int idx = 0; for (int i = 0; i < Height; i++) { for (int j = 0; j < Width; j++) { for (int k = 0; k < BytesPP; k++) { if (_data[idx] != 0) return false; idx++; } } } return true; } } }