public static int[,] GetPixels(byte[] mapData, byte[] tiles, TilemapFormat format, int bytesPerTile) { var tileSize = format.BitsPerPixel * 8; var result = new int[format.TileWidth * 8, format.TileHeight * 8]; for (int y = 0; y < format.TileHeight; y++) { var yStart = y * 8; for (int x = 0; x < format.TileWidth; x++) { var(pal, hFlip, vFlip, tile) = ReadTileData(mapData, format.TileWidth * y + x, bytesPerTile); pal <<= 4; var tileStart = tile * tileSize; var pixels = SpriteRun.GetPixels(tiles, tileStart, 1, 1, format.BitsPerPixel); // TODO cache this during this method so we don't load the same tile more than once var xStart = x * 8; for (int yy = 0; yy < 8; yy++) { for (int xx = 0; xx < 8; xx++) { var inX = hFlip ? 7 - xx : xx; var inY = vFlip ? 7 - yy : yy; result[xStart + xx, yStart + yy] = pixels[inX, inY] + pal; } } } } return(result); }
public LzTilemapRun(TilemapFormat format, IDataModel data, int start, SortedSpan <int> sources = null) : base(data, start, allowLengthErrors: false, sources) { Format = format; BytesPerTile = 2; if (format.TileWidth * format.TileHeight * BytesPerTile > DecompressedLength) { BytesPerTile = 1; } }
public static bool TryParseTilemapFormat(string format, out TilemapFormat tilemapFormat) { tilemapFormat = default; if (!(format.StartsWith("`ucm") && format.EndsWith("`"))) { return(false); } format = format.Substring(4, format.Length - 5); return(LzTilemapRun.TryParseGeneralTilemapFormat(format, out tilemapFormat)); }
/// <summary> /// Initializes a new instance of the <see cref="Tilemap"/> class from the specified file. /// </summary> /// <param name="filename"></param> /// <param name="format"></param> /// <param name="width"></param> public Tilemap(string filename, TilemapFormat format, int width) { const int IndexMask = 0x3FF; const int FlipXMask = 0x400; const int FlipYMask = 0x800; const int PaletteMask = 0xF; using (var fs = File.OpenRead(filename)) using (var br = new BinaryReader(fs)) { // -------------------------------- var tileCount = (int)br.BaseStream.Length / (format == TilemapFormat.RotationScaling ? 1 : 2); // -------------------------------- this.width = width; this.height = tileCount / width; // -------------------------------- tiles = new TilemapEntry[width * height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (format == TilemapFormat.Text4) { var u = br.ReadUInt16(); tiles[x + y * width] = new TilemapEntry( (short)(u & IndexMask), (byte)((u >> 12) & PaletteMask), (u & FlipXMask) == FlipXMask, (u & FlipYMask) == FlipYMask ); } else if (format == TilemapFormat.Text8) { var u = br.ReadUInt16(); tiles[x + y * width] = new TilemapEntry( (short)(u & IndexMask), (u & FlipXMask) == FlipXMask, (u & FlipYMask) == FlipYMask ); } else // RotationScaling { tiles[x + y * width] = new TilemapEntry(br.ReadByte()); } } } } }
public static bool TryParseTilemapFormat(string format, out TilemapFormat tilemapFormat) { tilemapFormat = default; if (!(format.StartsWith("`lzm") && format.EndsWith("`"))) { return(false); } format = format.Substring(4, format.Length - 5); // parse the tilesetHint string hint = null, tableMember = null; var pipeIndex = format.IndexOf('|'); if (pipeIndex != -1) { hint = format.Substring(pipeIndex + 1); format = format.Substring(0, pipeIndex); pipeIndex = hint.IndexOf('|'); if (pipeIndex != -1) { tableMember = hint.Substring(pipeIndex + 1); hint = hint.Substring(0, pipeIndex); } } var parts = format.Split('x'); if (parts.Length != 3) { return(false); } if (!int.TryParse(parts[0], out int bits)) { return(false); } if (!int.TryParse(parts[1], out int width)) { return(false); } if (!int.TryParse(parts[2], out int height)) { return(false); } tilemapFormat = new TilemapFormat(bits, width, height, hint, tableMember); return(true); }
private void SaveGBA(Stream stream, TilemapFormat format, int padding) { using (var writer = new BinaryWriter(stream)) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { ref TilemapEntry tile = ref this[x, y]; if (format == TilemapFormat.Text4) { writer.Write((ushort)( (tile.Index & 0x3FF) | (tile.FlipX ? 0x400 : 0) | (tile.FlipY ? 0x800 : 0) | (tile.Palette << 12) )); } else if (format == TilemapFormat.Text8) { writer.Write((ushort)( (tile.Index & 0x3FF) | (tile.FlipX ? 0x400 : 0) | (tile.FlipY ? 0x800 : 0) )); } else // TilemapFormat.RotationScaling { writer.Write((byte)tile.Index); } } } for (int i = 0; i < padding; i++) { writer.Write(byte.MinValue); } }
public TilemapRun(IDataModel model, int start, TilemapFormat format, SortedSpan <int> sources = null) : base(start, sources) { Model = model; Format = format; string hint = null; var address = Model.GetAddressFromAnchor(new NoDataChangeDeltaModel(), -1, Format.MatchingTileset); if (address >= 0 && address < Model.Count) { var tileset = Model.GetNextRun(address) as ISpriteRun; if (tileset == null) { tileset = Model.GetNextRun(arrayTilesetAddress) as ISpriteRun; } if (tileset != null && !(tileset is LzTilemapRun)) { hint = tileset.SpriteFormat.PaletteHint; } } SpriteFormat = new SpriteFormat(format.BitsPerPixel, format.TileWidth, format.TileHeight, hint); }
public TilemapRun Duplicate(TilemapFormat format) => new TilemapRun(Model, Start, format, PointerSources);
ITilemapRun ITilemapRun.Duplicate(TilemapFormat format) => Duplicate(format);
public TilemapRunContentStrategy(TilemapFormat format) { this.format = format; }
public LzTilemapRun(TilemapFormat format, IDataModel data, int start, SortedSpan <int> sources = null) : base(data, start, sources) { Format = format; }
public static byte[] GetData(byte[] mapData, byte[] tiles, TilemapFormat format, int bytesPerTile) { throw new NotImplementedException(); }
public LzTilemapRunContentStrategy(TilemapFormat format) => TilemapFormat = format;